Skip to main content


The Deno Standard Library
function load
import { load } from "";

Load environment variables from a .env file. Loaded variables are accessible in a configuration object returned by the load() function, as well as optionally exporting them to the process environment using the export option.

Inspired by the node modules dotenv and dotenv-expand.

Basic usage

# .env
GREETING=hello world

Then import the environment variables using the load function.

// app.ts
import { load } from "";

console.log(await load({export: true})); // { GREETING: "hello world" }
console.log(Deno.env.get("GREETING")); // hello world

Run this with deno run --allow-read --allow-env app.ts.

.env files support blank lines, comments, multi-line values and more. See Parsing Rules below for more detail.

Auto loading

Import the load.ts module to auto-import from the .env file and into the process environment.

// app.ts
import "";

console.log(Deno.env.get("GREETING")); // hello world

Run this with deno run --allow-read --allow-env app.ts.


Dotenv supports a number of different files, all of which are optional. File names and paths are configurable.

File Purpose
.env primary file for storing key-value environment entries
.env.example this file does not set any values, but specifies env variables which must be present in the configuration object or process environment after loading dotenv
.env.defaults specify default values for env variables to be used when there is no entry in the .env file

Example file

The purpose of the example file is to provide a list of environment variables which must be set or already present in the process environment or an exception will be thrown. These variables may be set externally or loaded via the .env or .env.defaults files. A description may also be provided to help understand the purpose of the env variable. The values in this file are for documentation only and are not set in the environment. Example:

# .env.example

# With optional description (this is not set in the environment)
DATA_KEY=API key for the service.

# Without description

When the above file is present, after dotenv is loaded, if either DATA_KEY or DATA_URL is not present in the environment an exception is thrown.


This file is used to provide a list of default environment variables which will be used if there is no overriding variable in the .env file.

# .env.defaults
# .env

The environment variables set after dotenv loads are:



Loading environment files comes with a number of options passed into the load() function, all of which are optional.

Option Default Description
envPath ./.env Path and filename of the .env file. Use null to prevent the .env file from being loaded.
defaultsPath ./.env.defaults Path and filename of the .env.defaults file. Use null to prevent the .env.defaults file from being loaded.
examplePath ./.env.example Path and filename of the .env.example file. Use null to prevent the .env.example file from being loaded.
export false When true, this will export all environment variables in the .env and .env.default files to the process environment (e.g. for use by Deno.env.get()) but only if they are not already set. If a variable is already in the process, the .env value is ignored.
allowEmptyValues false Allows empty values for specified env variables (throws otherwise)

Example configuration

import { load } from "";

const conf = await load({
    envPath: "./.env_prod",
    examplePath: "./.env_required",
    export: true,
    allowEmptyValues: true,


At a minimum, loading the .env related files requires the --allow-read permission. Additionally, if you access the process environment, either through exporting your configuration or expanding variables in your .env file, you will need the --allow-env permission. E.g.

deno run --allow-read=.env,.env.defaults,.env.example --allow-env=ENV1,ENV2 app.ts

Parsing Rules

The parsing engine currently supports the following rules:

  • Variables that already exist in the environment are not overridden with export: true
  • BASIC=basic becomes { BASIC: "basic" }
  • empty lines are skipped
  • lines beginning with # are treated as comments
  • empty values become empty strings (EMPTY= becomes { EMPTY: "" })
  • single and double quoted values are escaped (SINGLE_QUOTE='quoted' becomes { SINGLE_QUOTE: "quoted" })
  • new lines are expanded in double quoted values (MULTILINE="new\nline" becomes
{ MULTILINE: "new\nline" }
  • inner quotes are maintained (think JSON) (JSON={"foo": "bar"} becomes { JSON: "{\"foo\": \"bar\"}" })
  • whitespace is removed from both ends of unquoted values (see more on trim) (FOO= some value becomes { FOO: "some value" })
  • whitespace is preserved on both ends of quoted values (FOO=" some value " becomes { FOO: " some value " })
  • dollar sign with an environment key in or without curly braces in unquoted values will expand the environment key (KEY=$KEY or KEY=${KEY} becomes { KEY: "<KEY_VALUE_FROM_ENV>" })
  • escaped dollar sign with an environment key in unquoted values will escape the environment key rather than expand (KEY=\$KEY becomes { KEY: "\\$KEY" })
  • colon and a minus sign with a default value(which can also be another expand value) in expanding construction in unquoted values will first attempt to expand the environment key. If it’s not found, then it will return the default value (KEY=${KEY:-default} If KEY exists it becomes { KEY: "<KEY_VALUE_FROM_ENV>" } If not, then it becomes { KEY: "default" }. Also there is possible to do this case KEY=${NO_SUCH_KEY:-${EXISTING_KEY:-default}} which becomes { KEY: "<EXISTING_KEY_VALUE_FROM_ENV>" })


unnamed 0: LoadOptions = [UNSUPPORTED]


Promise<Record<string, string>>