Deno - Using Deno.env and Read Environment Variables Files

This tutorial is about how to work with environment variables in Deno, including how to read .env files.

It's very common for an application to make use of environment variables. Deno already has support for managing the values of environment variables. You can use the functions of Deno.env in order to set, delete, and get the values which will be exemplified later in this tutorial. In addition, It's quite common to store the values in files. If you use Deno, there is a module that makes it easier to read data from .env files. The module is dotenv. In this tutorial, I'm going to show you how to use Deno.env and how to read environment variables from files using dotenv.

Using Deno.env

You can set the value for an environment variable using set function. If the environment variable already exists, the value will be replaced.

  Deno.env.set('APPLICATION_NAME', 'woolha');

To get the value of an environment variable, use get function and pass the variable name as the argument.

  console.log(Deno.env.get("APPLICATION_NAME"));

To get the list of all environment variables, use toObject function.

  console.log(Deno.env.toObject());

In case you want to delete an environment variable, use delete function with the variable name as the argument.

  Deno.env.delete("APPLICATION_NAME");

Using dotenv Module

dotenv is a module that makes it easier for us to read .env files. Before using the module, it's better to understand how it works. The module can read three files containing the environment variables: .env, .env.defaults and .env.example.

By default, it looks for a .env file in the root of the project to get the list of environment variables. It only takes values from.env.defaults that are not present in .env file. If an environment variable is present in both .env and .env.defaults files, the one in .env will be used. It doesn't use any value from .env.example. The .env.example file is usually used for example only, but it can also be used to validate the list of environment variables that should be defined in .env file.

To define an environment variable, the format is {environment variable name}={value}. Each variable needs to be separated with a new line.

  ENVIRONMENT=development
  APPLICATION_NAME=woolha

Each value is parsed as a string, even if it contains number only or boolean. If the value is empty, it will be parsed as an empty string. It skips empty lines, while lines beginning with # are treated as comments.

You can also wrap a value inside single quotes or double quotes. If the value needs to contain a new line, it has to be wrapped inside double quotes.

  ENVIRONMENT='development'
  VALUES="first\nsecond"

The function of dotenv module we are going to use is config. It has a parameter options which is an object with the following fields.

  • string path: Path to .env file. Defaults to ./.env.
  • boolean export: Whether to export all variables to the process environment.
  • boolean safe: Whether to make sure that all variables defined in .env.example are defined in either .env or .env.defaults.
  • string example: Path to .env.example file. Defaults to ./.env.example.
  • boolean allowEmptyValues: Whether to allow empty value. If set to false (the default value), it will throw an error if any variable has empty value..
  • string defaults: Path to .env.defaults file. Defaults to ./.env.defaults.

For this tutorial, let's assume we have the following files at the root of the project.

.env

  ENVIRONMENT=development
  APPLICATION_NAME=woolha
  X=1

.env.defaults

  Y=2

.env.example

  X=0
  Y=0
  Z=0

To use the module it's better to import and re-export it on deps.ts file first.

  import { config as dotEnvConfig } from 'https://deno.land/x/dotenv@v1.0.1/mod.ts';

  export { dotEnvConfig };

For the basic usage, we don't need to pass any option

  import { dotEnvConfig } from './deps.ts';

  console.log(config({}));

To run the app, you need to add --allow-read and --allow-env flags.

  deno run --allow-read --allow-env examples/app.ts

Output:

  { ENVIRONMENT: "development", APPLICATION_NAME: "woolha", X: "1", Y: "2" }

In Deno, we can get a value of an environment variable using Deno.env.get function. The code above doesn't export the values to Deno.env. To export all values to the Deno.env, you need to set export option to true.

  import { dotEnvConfig } from './deps.ts';

  config({ export: true });

  console.log(Deno.env.get('ENVIRONMENT')); 

Output:

  development

You can also validate that all variables defined in .env.example file are also defined in .env file.

  import { dotEnvConfig } from './deps.ts';

  config({ safe: true });

Output:

  error: Uncaught MissingEnvVarsError: The following variables were defined in the example file but are not present in the environment:
  Y, Z

  Make sure to add them to your env file.

  If you expect any of these variables to be empty, you can set the allowEmptyValues option to true.
    throw new MissingEnvVarsError(errorMessages.filter(Boolean).join("\n\n"));
          ^
    at assertSafe (mod.ts:117:11)
    at config (mod.ts:46:5)
    at app.ts:4:1

As you can see from the above output, it will throw MissingEnvVarsError because Y and Z are not defined in .env file.

That's how to work with environment variables in Deno. Deno.env provides the functionalities to manage the environment variable values. For reading the values from .env files, you can use a third party module such as dotenv.