docs/how-to-use-flow-to-store-and-work-with-env.md
This is the context-optimized workflow for current Flow behavior.
f env set KEY=VALUE writes to personal env scope.f env project set KEY=VALUE writes to project env scope.If you need deploy/runtime envs for a project, use f env project ....
Flow supports:
cloud (myflow.sh): shared/team-friendly.local (~/.config/flow/env-local/): offline/no-account.Cloud behavior:
env_source = "cloud" plus a service token,
Flow keeps a compatibility plaintext mirror for those project keys until the
host fetch path is upgraded.Set backend in ~/.config/flow/config.ts:
export default {
flow: { env: { backend: "cloud" } } // or "local"
}
Or per shell:
export FLOW_ENV_BACKEND=local
# 1) Login once if using cloud
f env login
# 2) Set project env vars (not personal)
f env project set DATABASE_URL=postgres://... -e production
f env project set RESEND_API_KEY=re_... -e production
# 3) Verify (masked)
f env project list -e production
# 4) Run app with injected project envs
f env run -e production -- pnpm start
# 5) Optional: write current project envs to local .env
f env pull -e production
Use for developer-specific tokens (GitHub, CLI auth, etc.):
f env set GITHUB_TOKEN=ghp_...
f env get --personal GITHUB_TOKEN -f value
f env run --personal -k GITHUB_TOKEN -- gh auth status
Deepgram example (keep value in Flow store, never in docs):
# Set once (personal scope)
f env set --personal DEEPGRAM_API_KEY=<redacted>
# Read when needed
f env get --personal DEEPGRAM_API_KEY -f value
On macOS with the local backend, personal env values are stored in Keychain by
default and Flow keeps only references under ~/.config/flow/env-local/personal/.
Use FLOW_ENV_LOCAL_PLAINTEXT=1 only as a compatibility escape hatch.
Supported environments:
production (default)stagingdevExample:
f env project set API_URL=https://staging.example.com -e staging
f env run -e staging -- pnpm dev
Use these when flow.toml already declares required keys:
f env keys
f env guide -e production
f env setup
In flow.toml:
[cloudflare]
env_source = "cloud" # or "local" for local backend reads
env_keys = ["DATABASE_URL", "BETTER_AUTH_SECRET", "APP_BASE_URL"]
env_vars = ["APP_BASE_URL"] # non-secret vars
environment = "production"
Apply:
f env apply
In flow.toml:
[host]
env_source = "flow" # or "local"
env_keys = ["DATABASE_URL", "RESEND_API_KEY"]
environment = "production"
Then:
f deploy
When backend is local, Flow uses this layout:
~/.config/flow/env-local/
├── <project-or-space>/
│ ├── production.env
│ ├── staging.env
│ └── dev.env
└── personal/
└── production.env
Behavior:
.env files on disk.f env login (or force local backend).-e staging vs production).-- before command.
f env run -k API_KEY -- node app.jsf env run -k API_KEY node app.js