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 | ✅ | ❌ | ❌ |
Loads .env | ✅ | ✅ | ❌ |
Return Type Helpers | 🔜 | ❌ | ✅ |
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.
If you set a path to an .env
file, simple-env
will parse the file and import the contents into the environment automatically. These will be available in the process.env
object.
If you don't specify a path,
simple-env
will not automatically load any.env
files. This is to avoid a breaking change.
// src/env.ts
import setEnv from '@americanairlines/simple-env';
export const env = setEnv({
required: {
nodeEnv: 'NODE_ENV',
someRequiredSecret: 'SOME_REQUIRED_SECRET',
},
options: {
envPath: "./.env"
}
});
Each variable needs to be declared on a separate line.
Comments must be on their own line, inline comments will be read in as part of the value to the variable!
If simple-env
finds something that it doesn't know how to parse, it just skips it and moves on to the next thing!
Here's a sample .env
file that will make us all happy :^)
# Comments like this will be ignored
// These will be ignored too :^)
# All of these vars are gonna work just fine!
NODE_ENV=development
SOME_REQUIRED_SECRET='Single quotes are fine!'
ANOTHER_SECRET="Double quotes are fine too, we don't discriminate :^)"
lowercase=no problem
SECRET_2_ELECTRIC_BOOGALOO = "We don't mind whitespace between the equal signs, or before the var definition"
Here's a sample .env
file that will make us all sad :^(
# Uh-oh, these ones are invalid, so we'll have to skip them
1BAD_VAR="Variables can't begin with numbers"
ANOTHER BAD VAR="no whitespace allowed in var names"
KEBAB-CASE="can't do it"
VAR_WITHOUT_EQUAL_IS_SKIPPED
loose text like this will also get skipped
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.