An intuitive, strongly typed, and scalable way to retrieve environment variables.
# Via npm
npm install @americanairlines/simple-env
# Via Yarn
yarn add @americanairlines/simple-env
Create a file to manage your environment variables (either added via arguments or a .env
file loaded with dotenv
):
// src/env.ts
import setEnv from '@americanairlines/simple-env';
export const env = setEnv({
required: {
nodeEnv: 'NODE_ENV',
someRequiredSecret: 'SOME_REQUIRED_SECRET',
},
optional: {
anOptionalSecret: 'AN_OPTIONAL_SECRET',
},
});
Import env
(or whatever you named your export) from your configuration file:
// src/index.ts
import env from './env';
const someRequiredSecret = env.someRequiredSecret;
Env Var Type | State of Variable | Return Value/Behavior |
---|---|---|
optional | set | β Associated value returned as string |
optional | unset | β
undefined returned |
required | set | β Associated value returned as string |
required | unset | π₯ Runtime error |
N/A - Unknown | ??? | π₯ Compilation error |
β οΈ Retrieving an unset andrequired
env variable at the root of a file will throw an error and the app will fail to start.
Autocomplete and Strongly Typed Keys are your new best friend! Using simple-env
makes it easier for devs to utilize environment variables via autocomplete and requiring defined keys prevents typos and makes refactoring incredibly simple.
Feature | simple-env |
dotenv |
env-var |
---|---|---|---|
Zero Dependencies | β | β | β |
JS/TS Support | β | β | β |
Required vs Optional Specification | β | β | β |
Autocomplete | β | β | β |
Strongly Typed Keys | β | β | β |
Single Location Refactor | β | β | β |
Return Type Helpers | π | β | β |
Loads .env | π | β | β |
Let's see how some of the features above look in code:
// fileA.ts
const secret = process.env.SECRET;
// fileB.ts
const secret = process.env.SECRE;
// π Brittle, susceptible to typos, weak types, and painful to refactor π
const env = setEnv({
required: { secret: 'SOMETHING_SECRET' },
});
const secret = env.secret;
const secret = env.secre; // Property 'secre' does not exist on type '{ readonly secret: string; }'. Did you mean 'secret'? ts(2551)
// π Compilation errors on typos, autocompletes as you type, and env var key can be modified without needing to refactor everywhere π
const env = setEnv({
required: { requiredSecret: 'SOME_REQUIRED_SECRET' },
optional: { optionalSecret: 'SOME_OPTIONAL_SECRET' },
});
env.requiredSecret.valueOf(); // No error
env.optionalSecret.valueOf(); // Object is possibly 'undefined'. ts(2532)
// π Extremely strong typing - it knows what's required vs optional, which helps you catch bugs faster π
setEnv
accepts multiple optional arguments:
// src/env.ts
import setEnv from '@americanairlines/simple-env';
export const env = setEnv({
required: {
nodeEnv: 'NODE_ENV',
someRequiredSecret: 'SOME_REQUIRED_SECRET',
},
});
You can choose to only include optional
env vars by passing in a single object:
// src/env.ts
import setEnv from '@americanairlines/simple-env';
export const env = setEnv({
optional: {
anOptionalSecret: 'AN_OPTIONAL_SECRET',
},
});
If you want to set your env vars in multiple groups, make sure to destructure the optional env vars properly.
// src/env.ts
import setEnv from '@americanairlines/simple-env';
setEnv({
required: {
nodeEnv: 'NODE_ENV',
someRequiredSecret: 'SOME_REQUIRED_SECRET',
},
});
export const env = setEnv({
optional: {
anOptionalSecret: 'AN_OPTIONAL_SECRET',
},
});
NOTE: if you choose to assign
optional
andrequired
env vars individually,setEnv
should only be done once for each or you will overwrite your previously defined values.
Providing mocked environment variables during testing is very straightforward. Perform the following steps to mock your environment in Jest:
- Under your
src
folder, create a new folder called__mocks__
. This is a special folder used by Jest to manually mock modules for testing. (Documentation) - Create a file with an identical name and path to the real module. For example, if your module is at
src/env.ts
, your mocked module would live atsrc/__mocks__/env.ts
. - Define your mock environment in the file:
export const env = {
nodeEnv: 'development',
requiredSecret: 'required123',
optionalSecret: 'optionalABC',
};
Now that we have a mock environment, all that's left is to instruct Jest to mock our env module:
- Create a file in your tests folder called
setupTests.ts
and add the following line:
jest.mock('../src/env'); // Modify path to match your project structure
- Add the following options to your Jest config (
jest.config.js
) file:
// ...
setupFilesAfterEnv: ['./tests/setupTests.ts'], // Modify path to match your project structure
clearMocks: true,
// ...
Now you can proceed with writing tests as normal using the new mocked environment.
Interested in contributing to the project? Check out our Contributing Guidelines.
- Install dependencies with
npm i
- Run
npm run dev
to compile and re-compile on change - Run
npm link
- Navigate to another Node.js project and run
npm link @americanairlines/simple-env
You can now use simple-env
functionality within your project. On changing/adding functionality, the @americanairlines/simple-env
package will update within your other project so you can test changes immediately.