Published
- 2 min read
Better Environment Variables

Better Env Vars for Great Good!
Environment variables that you can easily error check, throw transpilation errors, and can be imported by name!
The Problem
You need environment variables, but you don’t know how to properly behave when required vars are missing, don’t want to bloat your project with packages like dotenv
, and want intellisense support for them!
The Solution
The solution is to add environment variable declarations to process.env
in the global namespace.
// in environment.d.ts at project root
declare global {
namespace NodeJS {
interface ProcessEnv {
LOGIN_TABLE: string
NEO4J_CONNECTION_MAX_RETRIES?: string
NEO4J_PW: string
NEO4J_UNAME: string
NEO4J_URI: string
ORIGIN: string
PINO_LOG_HTTP?: string
PINO_LOG_LEVEL?: string
PORT?: string
}
}
}
Time to use them!
// <root>/index.ts
const {
NEO4J_PW,
NEO4J_URI,
NEO4J_UNAME,
NEO4J_CONNECTION_MAX_RETRIES,
PORT,
ORIGIN,
PINO_LOG_HTTP
} = process.env
// Initialize Neo4J connection
if (!NEO4J_URI || !NEO4J_UNAME || !NEO4J_PW) {
log.error(
`Missing Neo4J parameters: ${JSON.stringify({
uri: NEO4J_URI,
uname: NEO4J_UNAME,
pw: !!NEO4J_PW
})}`
)
throw new Error('Missing Neo4J parameter')
}
const localNeo4JDriver: Neo4JDriver = new Neo4JDriver(NEO4J_URI, NEO4J_UNAME, NEO4J_PW)
I just love that you get a nice little import wherever you need to use your env vars. They’re declared up front, not duplicated, and are picked up by intellisense! My only frustration is that they can only be strings, but that’s the case with packages like dotenv
as well afaik.
Happy coding!