@noshot/env
    TypeScript icon, indicating that this package has built-in type declarations

    2.1.1 • Public • Published

    Heavily inspired by dotenv and dotenv-expand, @noshot/env is a simple to use zero-dependency package module that automatically loads environment variables from a predefined Env variable. When it comes to .env.* file naming, @noshot/env is unopinionated, so you can name them anything you'd like or you can follow the The Twelve-Factor App methodology.

    Why @noshot/env?

    ✔️ Loads .env.* files between 40%-70% faster than dotenv and dotenv-expand: demo, metrics

    ✔️ Typescript source with included type declarations

    ✔️ Zero dependencies

    ✔️ Compiled and minified ES5 CommonJS

    ✔️ Experimental ESM support (beta)

    ✔️ Unopinionated about .env.* naming

    ✔️ Supports loading multiple .env.* files at once

    ✔️ Supports manually importing or parsing .env.* files

    ✔️ Supports overriding Envs in process.env

    ✔️ Supports extending local .env files

    ✔️ Supports fetching remote .env files (beta)

    ✔️ Supports Env encryption and decryption

    ✔️ Supports Env interpolation

    ✔️ Supports Env preloading

    ✔️ Supports loading Envs via an Env Configuration File

    Quick Links

    Installation

    Usage

    Env Configuration File

    CLI Options

    Preload

    Config Method

    Parse Method

    Load Method

    Decrypt Method

    Encrypt Method

    Encryption and Decryption Arguments

    Encryption and Decryption Limitations

    Extending Local .env Files

    Fetching Remote .env Files

    Interpolation

    FAQ

    Contributing Guide

    Installation

    # with npm
    npm install @noshot/env
    
    # or with yarn
    yarn add @noshot/env

    Usage

    In a CLI or within your package.json, under the scripts property, define CLI Options before running a process. Then @noshot/env will load the .env.* files according to their defined paths order (left to right), where the last imported file will take precedence over any previously imported files.

    For example, .env.* files can loaded by an Env Configuration File file via LOAD_CONFIG:

    {
      "scripts": {
        "dev": "LOAD_CONFIG=development node test.js",
        "staging": "LOAD_CONFIG=staging node app.js"
      },
      "dependencies": {
        "@noshot/env": "^x.x.x"
      }
    }

    All you need to do now is require/import the @noshot/env base package as early as possible:

    require("@noshot/env");
    // import '@noshot/env';

    Optionally, you can preload your .env.* files instead!

    Env Configuration File

    The easiest and cleanest way to load .env.* files is to create an env.config.json configuration file located at the project's root directory. The configuration file will be a JSON object that follows the config argument options pattern. The environment configuration naming is unopinionated -- they can be named anything you'd like (for example: dev, staging, prepublish, testing, and so on):

    env.config.json

    {
      "development": {
        "debug": true,
        "paths": [".env.base", ".env.dev"],
        "override": true
      },
      "production": {
        "paths": ".env.prod",
      },
      "test": {
        "dir": "custom/path/to/directory",
        "paths": [".env.base", ".env.dev"],
      }
    }

    Then in your package.json, add a LOAD_CONFIG variable to load one of the configurations by an environment name (the environment name must match one of environments specified in the configuration file above):

    {
      "scripts": {
        "dev": "LOAD_CONFIG=development node app.js"
      },
      "dependencies": {
        "@noshot/env": "^x.x.x"
      }
    }

    Then, either preload or import the @noshot/env package as early as possible to load the development Envs.

    {
     "development": {
        "debug": true,
        "paths": [".env.base", ".env.dev"],
        "override": true
      }
    }

    CLI Options

    LOAD_CONFIG

    By defining a LOAD_CONFIG variable, this will let @noshot/env know you'd like to load an env.config.json configuration file according to a specific environment name. The environment naming is unopinionated -- they can be named anything you'd like (for example: dev, staging, prepublish, testing and so on); however, the environment name must match one of environments specified in the configuration file.

    {
      "scripts": {
        "dev": "LOAD_CONFIG=development node app.js"
      },
      "dependencies": {
        "@noshot/env": "^x.x.x"
      }
    }

    env.config.json

    {
      "development": {
        "debug": true,
        "paths": [".env.base", ".env.dev"],
        "override": true
      },
      "production": {
        "paths": ".env.prod",
      },
      "test": {
        "dir": "custom/path/to/directory",
        "paths": [".env.base", ".env.dev"],
      }
    }

    Note: Defining any of the options within the configuration file WILL NOT change the default behavior of config, load or parse methods.

    Preload

    You can use the --require (-r) command line option with @noshot/env to preload your .env.* files! By doing so, you do not need to require/import the @noshot/env package within your project.

    CLI:

    $ LOAD_CONFIG=dev node -r @noshot/env app.js

    Package.json:

    {
      "scripts": {
        "dev": "LOAD_CONFIG=dev node -r @noshot/env app.js"
      },
      "dependencies": {
        "@noshot/env": "^x.x.x"
      }
    }

    Config Method

    If you wish to manaully import .env.* files, then the config method will read your .env.* files, parse the contents, assign them to process.env, and return an Object with parsed and extracted Envs:

    const env = require("@noshot/env");
    // import env from "@noshot/env";
    
    const result = env.config();
    
    console.log("parsed", result.parsed); // process.env with loaded Envs
    console.log("extracted", result.extracted); // extracted Envs within a { KEY: VALUE } object

    Additionally, you can pass argument options to config.

    Config Argument Options

    The config method accepts a single Object argument with the following properties:

    { 
      dir?: string, 
      paths?: string | string[], 
      encoding?: BufferEncoding,
      override?: boolean | string,
      debug?: boolean | string
    }

    Config dir

    Default: process.cwd() (project root directory)

    You may specify a single directory path if your files are located elsewhere.

    A single directory path as a string:

    require("@noshot/env").config({ dir: "custom/path/to/directory" });
    
    // import { config } from "@noshot/env";
    // config({ dir: "custom/path/to/directory" });

    Config paths

    Default: [".env"]

    You may specify custom paths if your files are located elsewhere (recommended to use absolute path(s) from your root directory).

    A single file path as a string:

    require("@noshot/env").config({ paths: "custom/path/to/.env" });
    
    // import { config } from "@noshot/env";
    // config({ paths: "custom/path/to/.env" });

    Multiple file paths as a single string separated by commas:

    require("@noshot/env").config({
      paths: "custom/path/to/.env,custom/path/to/.env.base"
    });
    
    // import { config } from "@noshot/env";
    // config({ paths: "custom/path/to/.env,custom/path/to/.env.base" });

    Or multiple file paths as an Array of strings:

    require("@noshot/env").config({
      paths: ["custom/path/to/.env", "custom/path/to/.env.base"]
    });
    
    // import { config } from "@noshot/env";
    // config({ paths: ["custom/path/to/.env", "custom/path/to/.env.base"] });

    It's highly recommended that you utilize dir if you're loading from a single custom directory:

    require("@noshot/env").config({ dir: "custom/path/to/directory", paths: [".env", ".env.base"] });
    
    // import { config } from "@noshot/env";
    // config({ dir: "custom/path/to/directory", paths: [".env", ".env.base"] });

    Config encoding

    Default: utf8

    You may specify the character encoding type of your file containing environment variables.

    require("@noshot/env").config({ encoding: "latin1" });
    
    // import { config } from "@noshot/env";
    // config({ encoding: "latin1" });

    Config override

    Default: false

    You may specify whether or not to override Envs in process.env.

    require("@noshot/env").config({ override: true });
    
    // import { config } from "@noshot/env";
    // config({ override: true });

    Config debug

    Default: undefined

    You may turn on logging to help debug file loading.

    require("@noshot/env").config({ debug: true });
    
    // import { config } from "@noshot/env";
    // config({ debug: true });

    Parse Method

    If you wish to manually parse Envs, then you can utilize parse to read a string or Buffer and parse their contents.

    Parse Argument Options

    The parse method accepts two arguments in the following order:

    src: string | Buffer, 
    override: boolean | string | undefined
    

    Parse src

    For some use cases, you may want to pass parse a string or Buffer which returns parsed extracted keys/values as a single Object. These will NOT be assigned to process.env. Why not?

    const { readFileSync } = require("fs");
    const { parse } = require("@noshot/env");
    // import { readFileSync } from "fs";
    // import { parse } from "@noshot/env";
    
    const config = parse(Buffer.from("BASIC=basic")); // will return an object
    console.log(typeof config, config); // object - { BASIC : 'basic' }
    
    const results = parse(readFileSync("path/to/.env.file", { encoding: "utf8" })); // will return an object
    console.log(typeof results, results); // object - { KEY : 'value' }

    Note: If you're attempting to parse Envs that have already been defined within process.env, then you must pass parse an override argument.

    Parse override

    If you wish to extract and potentially override Envs in process.env, then you can pass a boolean or string (passing "false" will still be truthy) as a second argument to parse. These will NOT be assigned to process.env. Why not?

    const { readFileSync } = require("fs");
    const { parse } = require("@noshot/env");
    // import { readFileSync } from "fs";
    // import { parse } from "@noshot/env";
    
    const config = parse(Buffer.from("BASIC=basic"), true); // will return an object
    console.log(typeof config, config); // object - { BASIC : 'basic' }
    
    const result = parse(readFileSync("path/to/.env.file", { encoding: "utf8" }), true); // will return an object
    console.log(typeof result, result); // object - { OVERRIDEKEY : 'value' }

    Parse Rules

    The parsing method currently supports the following rules:

    • BASIC=basic becomes {BASIC: 'basic'}
    • empty lines are skipped
    • lines beginning with # are treated as comments
    • empty values become empty strings (EMPTY= becomes {EMPTY: ''})
    • inner quotes are maintained (think JSON) (JSON={"foo": "bar"} becomes {JSON:"{\"foo\": \"bar\"}")
    • single and double quoted values are escaped (SINGLE_QUOTE='quoted' becomes {SINGLE_QUOTE: "quoted"})
    • single and double quoted values maintain whitespace from both ends (FOO=" some value " becomes {FOO: ' some value '})
    • double quoted values expand new lines MULTILINE="new\nline" becomes
    {MULTILINE: 'new
    line'}
    

    Load Method

    If you wish to manually load the env.config.json configuration file, then you can utilize the load method. Please note that this synchronously retrieves the environment configuration from the env.config.json configuration file, but will not automatically assign any Envs; instead, you'll have to manually pass its returned environment configuration to the config method.

    Load Argument Options

    The load method accepts two arguments in the following order:

    env: string, 
    dir: string | undefined
    

    Load env

    For some use cases, you may want to manually load the env.config.json configuration file and pass its returned environment configuration to the config method. To do so, pass load an environment name as the first argument:

    const { config, load } = require("@noshot/env");
    // import { config, load } from "@noshot/env";
    
    const configArgs = load("development"); // will return an object of config arguments
    console.log(typeof configArgs, configArgs) // object - { paths: ".env.dev", debug: true }
    config(configArgs) // parses .env.dev and assigns it to process.env

    Load dir

    For some use cases, you may want to manually load an env.config.json configuration file that is not located at the project's root directory and pass its returned environment configuration to the config method. To do so, pass load an environment name as the first argument and an absolute directory path as a second argument:

    const { config, load } = require("@noshot/env");
    // import { config, load } from "@noshot/env";
    
    const configArgs = load("development", "path/to/custom/directory"); // will return an object of config arguments
    console.log(typeof configArgs, configArgs) // object - { paths: ".env.dev", debug: true }
    config(configArgs) // parses .env.dev and assigns it to process.env

    Decrypt Method

    If you wish to manaully decrypt an encrypted string, then the decrypt method will parse the encrypted string and return an Object with decryptedEnvs as a single string of KEY=value pairs and a decryptedResult as either decrypted parsed JSON or a decrypted Buffer.

    The decrypt method accepts a single Object argument with the following required properties (see Encryption and Decryption Arguments for more details):

    { 
      algorithm: string, 
      envs: string (encrypted), 
      encoding: BufferEncoding,
      input: Encoding,
      iv: string,
      secret: CipherKey
    }

    Example:

    const env = require("@noshot/env");
    // import env from "@noshot/env";
    
    const result = env.decrypt({ 
      algorithm: "aes-256-cbc", 
      envs: "b8cb1867e4a8248c839db9cb0f1e1d", 
      encoding: "utf8", 
      input: "hex", 
      iv: "05c6f2c47de0ecfe", 
      secret: "abcdefghijklmnopqrstuv1234567890" 
    });
    
    console.log(typeof decryptedEnvs, result.decryptedEnvs); // string - a single string of "KEY=value" pairs
    console.log(typeof decryptedResult, result.decryptedResult); // object - { "KEY": "VALUE" } as JSON object
    // console.log(typeof decryptedResult, result.decryptedResult); // object - <Buffer xx xx xx ...etc>

    Encrypt Method

    If you wish to manaully encrypt a flat stringified JSON object or a Buffer, then the encrypt method will encrypt the string/Buffer and return an Object with encryptedEvs and an iv.

    The encrypt method accepts a single Object argument with the following required properties (see Encryption and Decryption Arguments for more details):

    { 
      algorithm: string, 
      envs: string (stringified JSON object) | Buffer, 
      encoding: BufferEncoding,
      input: Encoding,
      secret: CipherKey
    }

    Example:

    const env = require("@noshot/env");
    // import env from "@noshot/env";
    
    const result = env.encrypt({ 
      algorithm: "aes-256-cbc", 
      envs: JSON.stringify({ "KEY": "value" }), 
      encoding: "utf8", 
      input: "hex", 
      secret: "abcdefghijklmnopqrstuv1234567890" 
    });
    
    console.log(typeof encryptedEvs, result.encryptedEvs); // string - a single encrypted string
    console.log(typeof iv, result.iv); // string - a random encryption/decryption string

    Encryption and Decryption Arguments

    Encryption and decryption methods share similar arguments and here's a breakdown of each one:

    Encrypt/Decrypt algorithm

    The algorithm argument is a string that is dependent on OpenSSL. On recent OpenSSL releases, openssl list -cipher-algorithms (openssl list-cipher-algorithms for older versions of OpenSSL) will display the available cipher algorithms for your version.

    Encrypt/Decrypt envs

    The envs argument is, depending on the method, either a stringified JSON object or a Buffer for the encrypt method; or, a single encrypted string of Envs for the decrypt method.

    Encrypt (JSON string):

    const jsonString = JSON.stringify({ "KEY": "value" });

    Encrypt (Buffer):

    const buf = Buffer.from("KEY=value");

    Decrypt (a stringified value derived from the encrypt method):

    b8cb1867e4a8248c839db9cb0f1e1d
    

    Encrypt/Decrypt encoding

    Both methods expect the encoding argument to be a string type of character BufferEncoding.

    Encrypt/Decrypt input

    Both methods expect the input argument to be a string type of either base64 or hex.

    Encrypt/Decrypt iv

    The iv, or Initialization Vector, is a randomly generated string that is used to encrypt or decrypt a single string. Since it's randomly generated and unique to when it was created, ideally, it should be stored on a disk inaccessible to the source machine. Missplacing or forgetting the iv will mean that you have to regenerate a new encrypted string to retrieve a new iv. This iv should never be commited to version control!

    Encrypt/Decrypt secret

    The secret should be a randomly generated CipherKey (see key) that is one byte in length and is used to encrypt or decrypt a single string. This secret should never be commited to version control!

    Encryption and Decryption Limitations

    Due to the decryption method converting stringified JSON Envs to a non-standard format: KEY=value, double/single quotes can NOT be used in values (there's no performant way to only remove surrounding quotes from a "KEY" and a '"value"' without splitting key-value pairs into individual strings, removing the extraneous surrounding quotes, then rechunking them into pairs). Instead, it's recommended that you use a Buffer to retain quotes:

    For example, instead of using JSON:

    {
      "ABC": "123",
      "DEF": '"   567   "'
    }

    Use a Buffer:

    const buf = Buffer.from(`ABC=123\nDEF="  567  "`);

    On thate note, all interpolated values that follow the interpolation rules are supported.

    Extending Local .env Files

    Local .env.* file can be extended by adding # extends: magic comments followed by absolute/path/to/.env. These magic comments can be stacked within a single .env.* file:

    .env.example

    # extends: .env
    # extends: .env.base
    MESSAGE=Hello World

    Output:

    ROOT=true
    BASE=true
    MESSAGE=Hello World

    And/or they can be recursively extended:

    .env.example

    # extends: .env.base
    MESSAGE=Hello World

    .env.base

    # extends: .env
    BASE=true

    .env

    ROOT=true

    Output:

    ROOT=true
    BASE=true
    MESSAGE=Hello World

    ⚠️ Please note that extending .env.* files that don't exist will silently fail.

    Fetching Remote .env Files

    ⚠️ Support for this feature is in beta. It utilizes the curl command within a bash script which requires a Unix based operating system and/or Windows 10 v1803+. For now, this package expects the response body from the remote url to be encrypted plain text.

    Envs can be fetched by adding # uses: magic comments followed by 6 arguments with spaces between them (do NOT use new lines, only spaces, and they must be defined in this order):

    remoteurl: string 
    algorithm: string
    input: Encoding
    encoding: BufferEncoding
    secretkey: string
    iv: string
    

    For example:

    remote url

    https://domain.com/encryptedJSON.txt
    

    algorithm

    aes-256-cbc
    

    input

    hex
    

    encoding

    utf8
    

    secret

    abcdefghijklmnopqrstuv1234567890
    

    iv

    05c6f2c47de0ecfe
    

    JSON Object

    {
      "ABC": "123",
      "DEF": "678",
      "HIJ": "$ABC$DEF"
    }

    encryptedJSON.txt

    2ad5a38779ca444fe63773ed3771b6d9d52ceb7c6672823be594879d5dba50132f13ef647e2a69060e7e5f0f296c6fd3
    

    .env.example

    # uses: https://domain.com/encryptedJSON.txt aes-256-cbc hex utf8 abcdefghijklmnopqrstuv1234567890 05c6f2c47de0ecfe
    REMOTEFILE=true

    Output:

    ABC=123
    DEF=456
    HIJ=123456
    REMOTE_FILE=true

    ⚠️ Please note that fetching .env.* files from an invalid URL will silently fail.

    Interpolation

    Env values can be interpolated based upon a process.env value, a KEY within the .env.* file, a command line substitution and/or a fallback value.

    To interpolate a value from process.env or .env.*, simply define it with either $KEY or within brackets ${KEY}, for example:

    Input:

    MESSAGE=Hello
    INTERP_MESSAGE=$MESSAGE World
    INTERP_MESSAGE_BRACKETS=${MESSAGE} World
    ENVIRONMENT=$NODE_ENV

    Output:

    MESSAGE=Hello
    INTERP_MESSAGE=Hello World
    INTERP_MESSAGE_BRACKETS=Hello World
    ENVIRONMENT=development

    To interpolate a value with a single fallback value use the | symbol beside a $KEY or inside a ${KEY}, for example:

    Input:

    MESSAGE=Hello
    INTERP_MESSAGE=$MESSAGE|Hello World
    INTERP_MESSAGE_BRACKETS=${MESSAGE|Hello} World
    FALLBACK_VALUE=$UNDEFINED_KEY|Hello
    FALLBACK_VALUE_BRAKCETS=${UNDEFINED_KEY|Hello}
    FALLBACK_VALUE_WITH_INTERP=$UNDEFINED_KEY|$MESSAGE

    Output:

    MESSAGE=Hello
    INTERP_MESSAGE=Hello World
    INTERP_MESSAGE_BRACKETS=Hello World
    FALLBACK_VALUE=Hello
    FALLBACK_VALUE_BRAKCETS=Hello
    FALLBACK_VALUE_WITH_INTERP=Hello

    To interpolate a command line substitution, simply define it within parentheses $(KEY) for example:

    Input:

    USER=$(whoami)
    MULTICOMMAND=$(echo 'I Would Have Been Your Daddy' | sed 's/[^A-Z]//g')

    Output:

    USER=Jane
    MULTICOMMAND=IWHBYD

    Interpolation Rules

    • Values can be interpolated based upon a process.env value: BASIC=$NODE_ENV || BASIC=${NODE_ENV}
    • Values in process.env take precedence over interpolated values in .env.* files
    • Interpolated values can't be referenced across multiple .env.*s, instead they must only be referenced within the same file
    • Command line substitutions can NOT contain bash commands that use parentheses: EX=$(info=$(uname -a); echo $info;), instead its recommended to use .sh files instead: EX=$(bash ./path/to/info.sh)
    • Fallback values can NOT be used with command line substitutions
    • The $ character must be escaped when it doesn't refer to another key within the .env.* file: \$1234
    • Do not use escaped \$ within a value when it's key is referenced by another key:

    Input:

    A=\$example
    B=$A

    Output:

    A=$example
    B=

    Fix:

    A=example
    B=\$$A

    Output:

    A=example
    B=$example

    FAQ

    Should I commit my .env.* files?

    No. It's strongly recommended not to commit your .env.* files to version control. They'll include environment-specific values such as database passwords and API keys that should not be public. Commiting the env.config.json file is OK, as it won't/shouldn't contain any secrets.

    On the same note, most CI (continous integration) services like Github Actions and CircleCI offer their own Env configuration options for CI actions, so commiting .env.* files is unnecessary.

    Does this package allow submodule imports?

    Yes! You can import submodules directly by their name:

    // ASSIGN (CJS - named export is different!)
    const { assignEnvs } = require("@noshot/env/assign");
    const assign = require("@noshot/env/assign").default;
    // ASSIGN (ESM)
    import assign from "@noshot/env/assign";
    import assign from "@noshot/env/esm/assign";
    
    // CONFIG (CJS)
    const { config } = require("@noshot/env/config");
    const config = require("@noshot/env/config").default;
    // CONFIG (ESM)
    import config from "@noshot/env/config";
    import config from "@noshot/env/esm/config";
    
    // DECRYPT (CJS)
    const { decrypt } = require("@noshot/env/decrypt");
    const decrypt = require("@noshot/env/decrypt").default;
    // DECRYPT (ESM)
    import decrypt from "@noshot/env/decrypt";
    import decrypt from "@noshot/env/esm/decrypt";
    
    // ENCRYPT (CJS)
    const { encrypt } = require("@noshot/env/encrypt");
    const encrypt = require("@noshot/env/encrypt").default;
    // ENCRYPT (ESM)
    import encrypt from "@noshot/env/encrypt";
    import encrypt from "@noshot/env/esm/encrypt";
    
    // LOAD (CJS)
    const { load } = require("@noshot/env/load");
    const load = require("@noshot/env/load").default;
    // LOAD (ESM)
    import load from "@noshot/env/load";
    import load from "@noshot/env/esm/load";
    
    // PARSE (CJS)
    const { parse } = require("@noshot/env/parse");
    const parse = require("@noshot/env/parse").default;
    // PARSE (ESM)
    import parse from "@noshot/env/parse";
    import parse from "@noshot/env/esm/parse";

    ⚠️ Please note that for CommonJS imports (require) you'll need to import the default property for default exports. Unfortunately, this is a limitation of mixing ESM (which automatically imports default) and CJS imports (which doesn't). Alternatively, you can import (require) the named export instead.

    How does @noshot/env work and will it override already set or predefined variables?

    By default, @noshot/env will look for the .env.* file(s) defined within a LOAD_CONFIG environment variable and append them to process.env.

    For example, LOAD_CONFIG=development loads two files .env.base and .env.dev from env.config.json:

    {
      "scripts": {
        "dev": "LOAD_CONFIG=development node app.js"
      },
      "dependencies": {
        "@noshot/env": "^x.x.x"
      }
    }

    in a local environment, .env.base may have static shared database variables:

    DB_HOST=localhost
    DB_USER=root
    DB_PASS=password

    while .env.dev may have environment specific variables:

    DB_PASS=password123
    HOST=http://localhost
    PORT=3000

    @noshot/env will parse the files and append the Envs in the order of how they were defined in paths. In the example above, the DB_PASS variable within .env.base would be overidden by .env.dev because .env.dev file was imported last and, as a result, its DB_PASS will be assigned to process.env.

    By default, Envs that are pre-set or defined within process.env WILL NOT be overidden. If you wish to override variables in process.env or Config Override or Parse Override.

    Why doesn't the parse method automatically assign Envs?

    In short, parse can not automatically assign Envs as they're extracted.

    Why?

    Under the hood, the config method utilizes the parse method to extract one or multiple .env.* files as it loops over the config paths argument. The config method expects parse to return a single Object of extracted Envs that will be accumulated with other files' extracted Envs. The result of these accumulated Envs is then assigned to process.env once -- this approach has the added benefit of prioritizing Envs without using any additional logic since the last set of extracted Envs automatically override any previous Envs (by leveraging Object.assign). While allowing Envs to be assigned multiple times to process.env doesn't appear to be much different in terms of performance, it unforuntately requires quite a bit more additional overhead logic to determine which .env.* has priority and whether or not to conditionally assign them (including times when you might want to parse Envs, but not neccesarily assign them). A workaround to this limitation is to simply assign them yourself:

    const { assign, parse } = require("@noshot/env");
    // import { assign, parse } from "@noshot/env";
    
    const parsed = parse(Buffer.from("BASIC=basic")); // parse/interpolate Envs not defined in process.env
    // const parsed = parse(Buffer.from("BASIC=basic"), true); // parse/interpolate and override any Envs in process.env
    
    assign(parsed); // assigns parsed Envs to process.env

    Is the Env variable required?

    To be as flexible as possible, the Env variable (LOAD_CONFIG) is not required to set Envs to process.env. However, you will then be required to use this package similarly to how you would use dotenv:

    const { config } = require("@noshot/env");
    // import { config } from "@noshot/env";
    
    config({ ... });

    Check out the Config Method and Config Arguments for more information about manually loading .env.* files.

    How do I use ES modules?

    As of Node v12.17.0+, node removed the experimental flag for ES modules. Unfortunately, most of development world has yet to adopt ESM as the standard. Therefore, until there's more widespread support, this documentation will caution against using ESM and instead opt for CJS. In addition, node doesn't support preloading ESM, since preloading utilizes Node's require function. That said, this package offers experimental support for ESM. You can try it out by importing from the esm directory of the package:

    import env from "@noshot/env/esm";
    // import { assign, config, load, parse } from "@noshot/env/esm";
    // import config from "@noshot/env/esm/config";

    Contributing Guide

    See CONTRIBUTING.md

    Install

    npm i @noshot/env

    DownloadsWeekly Downloads

    88

    Version

    2.1.1

    License

    MIT

    Unpacked Size

    62.9 kB

    Total Files

    43

    Last publish

    Collaborators

    • mattcarlotta