Environment variables and .env
Manage configuration and secrets with --env-file, Deno.env, and precise --allow-env grants
Deno does not load .env files by default; you opt in explicitly. Reading environment variables is also gated by the --allow-env permission.
Loading .env files
deno run --env-file main.ts # discover the first .env from cwd upward
deno run --env-file=.env.local main.ts # explicit file
--env-filecan be passed multiple times. Within one file the first occurrence of a duplicate wins; across files, the last file specified takes precedence.- Do not rely on automatic loading: CI and production should consume real environment variables injected by the platform, not files from the repository.
- To load files in code, the standard library
@std/dotenvworks, but it still needs--allow-readand--allow-env.
Precise grants
deno run --allow-env=PORT,API_KEY main.ts
const port = Number(Deno.env.get("PORT") ?? "8000");
if (!Number.isInteger(port)) throw new Error("PORT must be an integer");
const apiKey = Deno.env.get("API_KEY");
if (!apiKey) throw new Error("API_KEY is required");
Validate variables at startup and fail fast; it is far easier to diagnose than an undefined surfacing mid-request. List only the variables the program actually reads in --allow-env, so third-party dependencies cannot peek at the rest of the environment.
Common DENO_* runtime variables
| Variable | Purpose |
|---|---|
DENO_DIR | Dependency and compile cache directory |
DENO_NO_PACKAGE_JSON | Disable automatic package.json resolution |
DENO_NO_PROMPT | Disable permission prompts, equivalent to --no-prompt |
DENO_NO_UPDATE_CHECK | Disable new-version checks |
DENO_TLS_CA_STORE | Certificate source, system / mozilla, defaults to mozilla |
DENO_CERT | Load extra CAs from a PEM file, equivalent to --cert |
DENO_AUTH_TOKENS | Bearer tokens for private module sources |
HTTP_PROXY / HTTPS_PROXY / NO_PROXY | Proxy settings for module downloads and fetch |
NO_COLOR | Disable colored output |
The official documentation is the authoritative full list; do not assume a variable exists from memory in scripts.
Configuration layering
Following twelve-factor principles, keep every environment-specific value in environment variables:
- Code may carry only non-sensitive defaults (such as port 8000).
- Local development uses
.env, added to.gitignore. - The repository commits
.env.examplewith key names and format notes, never real values. - CI and production receive variables injected by the platform and do not read a
.envfrom the repo.
Connecting to Deno Deploy
On Deno Deploy, environment variables are maintained in the console app's Environment Variables section, or managed with the deno deploy env subcommands (Classic's deployctl was retired with the platform — do not use it anymore):
deno deploy env add API_KEY "sk-..." --secret --org <org> --app <app>
deno deploy env load .env.production --org <org> --app <app>
env add --secret keeps the value hidden in the dashboard and in list output; env load bulk-imports a .env file. Code still only calls Deno.env.get(). When the local .env and the platform use the same key names, the code stays unaware of the deployment shape. See Deno Deploy.
Official reference: Environment variables.