Output Formats
Hush can output secrets in multiple formats to match what each package in your monorepo expects.
Available Formats
| Format | Output File | Use Case |
|---|---|---|
dotenv | .env.development / .env.production | Next.js, Vite, Expo, Remix, Node.js, etc. |
wrangler | .dev.vars | Cloudflare Workers & Pages |
json | .env.development.json | AWS Lambda, serverless, JSON configs |
shell | .env.development.sh | CI/CD pipelines, Docker builds |
yaml | .env.development.yaml | Kubernetes ConfigMaps, Docker Compose |
dotenv
Standard .env file format. The most common choice for Node.js applications.
Configuration
targets: - name: app path: ./packages/app format: dotenvOutput
File: .env.development
DATABASE_URL=postgres://localhost/mydbAPI_KEY=sk_test_xxxDEBUG=trueFile: .env.production
DATABASE_URL=postgres://prod-host/mydbAPI_KEY=sk_live_xxxDEBUG=falseCompatibility
Works with every major framework:
| Framework | Client Prefix |
|---|---|
| Next.js | NEXT_PUBLIC_* |
| Vite | VITE_* |
| Create React App | REACT_APP_* |
| Vue CLI | VUE_APP_* |
| Nuxt | NUXT_PUBLIC_* |
| Astro | PUBLIC_* |
| SvelteKit | PUBLIC_* |
| Expo | EXPO_PUBLIC_* |
| Gatsby | GATSBY_* |
| Remix | (server-only) |
| Node.js | (any) |
wrangler
Cloudflare Wrangler format for Workers development.
Configuration
targets: - name: api path: ./packages/api format: wranglerRecommended: Use hush run (Secrets in Memory)
The best way to use Hush with Wrangler is hush run, which keeps secrets in memory and never writes them to disk:
# Recommended approach - secrets never touch diskhush run -t api -- wrangler devWhen you use hush run with a Wrangler target, Hush automatically:
- Decrypts secrets to memory
- Sets
CLOUDFLARE_INCLUDE_PROCESS_ENV=true(tells Wrangler to read from process.env) - Passes secrets to Wrangler via environment variables
Alternative: hush decrypt (Secrets on Disk)
If you need to write secrets to disk (not recommended), use hush decrypt --force:
Output File: .dev.vars
DATABASE_URL=postgres://localhost/mydbSTRIPE_SECRET_KEY=sk_test_xxxJWT_SECRET=super-secret-keyHow Wrangler Loads Environment Variables
Understanding Wrangler’s loading order helps troubleshoot issues:
| Priority | Source | Behavior |
|---|---|---|
| 1st | .dev.vars file | If exists, blocks all other sources |
| 2nd | .env files | Loads if no .dev.vars; merges with process.env |
| 3rd | process.env | Only if CLOUDFLARE_INCLUDE_PROCESS_ENV=true |
| 4th | wrangler.toml [vars] | Base layer |
Key insight: If a .dev.vars file exists (even if empty!), Wrangler ignores CLOUDFLARE_INCLUDE_PROCESS_ENV entirely.
Troubleshooting
Secrets not appearing in your Worker?
-
Check for
.dev.varsfile:Terminal window ls -la .dev.varsIf it exists, delete it:
Terminal window rm .dev.vars -
Use
hush runinstead ofhush decrypt:Terminal window # Wrong - creates .dev.vars which blocks future hush run usagehush decrypt --force# Right - keeps secrets in memoryhush run -t api -- wrangler dev -
Check your Wrangler version: Older versions of Wrangler may not support
CLOUDFLARE_INCLUDE_PROCESS_ENV. Update to the latest:Terminal window npm update wrangler -
Verify Hush is targeting correctly:
Terminal window hush status
Push to Production
Hush can push secrets to Cloudflare Workers:
# Preview what would be pushedhush push --dry-run
# Push production secretshush push
# Push specific target onlyhush push -t apiThis runs wrangler secret put for each variable.
Cloudflare Pages
For Cloudflare Pages projects, use any format for local development and add a push_to configuration to enable pushing secrets.
Configuration
targets: - name: app path: ./app format: dotenv include: - NEXT_PUBLIC_* push_to: type: cloudflare-pages project: my-pages-project # Your Cloudflare Pages project nameLocal Development
The format: dotenv setting creates .env.development or .env.production files for local development, which frameworks like Next.js, Vite, etc. read automatically.
Push to Production
# Preview what would be pushedhush push -t app --dry-run --verbose
# Push production secrets to Cloudflare Pageshush push -t appThis uses wrangler pages secret bulk to push all secrets at once.
Template Expansion
If your target uses subdirectory templates, expansions are resolved before pushing:
# app/.env (template)NEXT_PUBLIC_API_URL=${API_URL}NEXT_PUBLIC_STRIPE_KEY=${STRIPE_PUBLISHABLE_KEY}When you run hush push -t app, these ${VAR} references are resolved against your root secrets, and the expanded values are pushed to Cloudflare Pages.
json
JSON object format for applications that consume JSON configuration.
Configuration
targets: - name: shared path: ./packages/shared format: jsonOutput
File: .env.development.json
{ "DATABASE_URL": "postgres://localhost/mydb", "API_KEY": "sk_test_xxx", "DEBUG": "true"}File: .env.production.json
{ "DATABASE_URL": "postgres://prod-host/mydb", "API_KEY": "sk_live_xxx", "DEBUG": "false"}Use Cases
- Configuration files that need JSON
- Tools that read JSON config
- API responses or fixtures
- Type-safe config loading
shell
Sourceable shell script with export statements.
Configuration
targets: - name: scripts path: ./scripts format: shellOutput
File: .env.development.sh
#!/bin/shexport DATABASE_URL="postgres://localhost/mydb"export API_KEY="sk_test_xxx"export DEBUG="true"File: .env.production.sh
#!/bin/shexport DATABASE_URL="postgres://prod-host/mydb"export API_KEY="sk_live_xxx"export DEBUG="false"Usage
# Source the file to set environment variablessource .env.development.sh
# Or in a script#!/bin/bashsource ./scripts/.env.production.sh./deploy.shUse Cases
- CI/CD pipelines
- Shell scripts
- Docker build arguments
- Makefile targets
yaml
YAML format for Kubernetes ConfigMaps, Docker Compose, and other YAML-based configuration.
Configuration
targets: - name: k8s path: ./k8s format: yamlOutput
File: .env.development.yaml
DATABASE_URL: "postgres://localhost/mydb"API_KEY: "sk_test_xxx"DEBUG: "true"REDIS_URL: "redis://localhost:6379"File: .env.production.yaml
DATABASE_URL: "postgres://prod-host/mydb"API_KEY: "sk_live_xxx"DEBUG: "false"REDIS_URL: "redis://prod-redis:6379"Use Cases
- Kubernetes ConfigMaps and Secrets
- Docker Compose environment files
- Helm chart values
- Any YAML-based configuration
Creating a Kubernetes ConfigMap
For Kubernetes deployments, use hush run to inject secrets into your kubectl commands:
# Run kubectl with secrets injectedhush run -e production -- kubectl apply -f k8s/
# Or use hush push for Cloudflare Workershush pushFor ConfigMaps, consider using external secrets operators or injecting secrets at runtime rather than writing them to files.
Docker Compose Integration
services: app: env_file: - ./config/.env.development.yamlChoosing a Format
| Your Stack | Recommended Format |
|---|---|
| Next.js, Vite, CRA, Vue, Nuxt | dotenv |
| Astro, SvelteKit, Remix | dotenv |
| Expo / React Native | dotenv |
| Gatsby | dotenv |
| Cloudflare Workers & Pages | wrangler |
| AWS Lambda, serverless | json |
| Kubernetes, Docker Compose | yaml |
| CI/CD pipelines, shell scripts | shell |
| Node.js / general backend | dotenv |
Multiple Formats
You can use different formats for different targets:
targets: # Next.js app uses dotenv - name: web path: ./apps/web format: dotenv include: - NEXT_PUBLIC_*
# Cloudflare Worker uses wrangler - name: api path: ./apps/api format: wrangler exclude: - NEXT_PUBLIC_*
# Lambda functions use JSON - name: lambda path: ./packages/lambda format: json
# Kubernetes uses YAML - name: k8s path: ./k8s format: yaml exclude: - NEXT_PUBLIC_*
# CI scripts use shell - name: ci path: ./scripts format: shell