Skip to content
DMNO
🚧 DMNO is still in beta! Use with caution!
✨ If you've tried DMNO or looked through the docs, let us know what you think!

Node.js (Express, Koa, etc)

While Node.js recently added native support for loading dotenv files, you’re often still left hacking things together to get a config system that works for your needs. DMNO supports Node out-of-the-box, with no additional plugins to install.

Setup

To get started, install dmno and then set up your config schema according to the schema guide.

Terminal window
npm add dmno

Loading your config

You must trigger the loading of the DMNO_CONFIG global, ideally as the first thing you do in your application code. To do this, simply import 'dmno/load' at the top of any entrypoint into your code, typically something like app.ts/main.ts. Do the same in any other script files you may need to run.

main.ts
import 'dmno/load'; // should be imported first!
// rest of your imports and code...

Booting your app

We recommend you adjust the command(s) you use to run your code by using dmno run.

While the dmno/load import will internally call the dmno cli and load config if necessary, by calling your code via dmno run you’ll get the best experience on the command line.

package.json
{
// ...
"scripts": {
"start": "dmno run -- node dist/main.js",
},

Accessing config values

Use DMNO_CONFIG.SOME_ITEM within your code and you are good to go!

const someApiClient = new SomeApiClient(process.env.SOME_API_SECRET);
const someApiClient = new SomeApiClient(DMNO_CONFIG.SOME_API_SECRET);

External tools

Other tools likely need access to some of your config as well - for example a database migration tool might need the full connection string/url for your database.

In some cases you may have a custom wrapper script, in which case, import 'dmno/load' will do the trick. In other cases, you may want to call those tools directly via their executables - whether directly on the command line or via package.json scripts.

In this case, run the command via dmno run and your config will be loaded and passed back into process.env which is usually where those external tools will be looking. It’s important to note that when we pass the config back into process.env, we convert everything back into strings, because this matches how normal env vars passed into process.env work. This should not be a problem since those tools were likely expecting regular environment variables (i.e., strings) in the first place, but it is important to remember.

package.json
{
// ...
"scripts": {
"migrate": "prisma migrate dev",
"migrate": "dmno run -- prisma migrate dev",
},

Recipes

Watch mode and dev commands

You likely have a pnpm dev, or yarn/npm/etc, command - which you rely on for automatically reloading as you make changes to your application code. It might use nodemon, Node.js’ native --watch option, or something else. Similarly, dmno run has a “watch mode” (-w) which watches your config and reloads when any changes are detected.

By running your watch/dev tool via dmno run, you’ll get your app automatically reloading whenever you make changes to your config or application code - all while validating your config, regenerating types, etc.

Prefix your existing dev command with dmno run -w -- and you’re good to go.

package.json
{
// ...
"scripts": {
"dev:nodemon": "dmno run -w -- nodemon dist/main.js",
"dev:native": "dmno run -w -- node --watch --no-warnings --experimental-specifier-resolution=node --loader ts-node/esm ./src/main.ts",
},

Scanning for leaked secrets

If you are building a Node.js API, you may want to scan for leaked secrets.

We will be releasing middlewares for popular frameworks (e.g., express, koa, fastify) very soon!