Layered configuration in KrakenJS: base files plus NODE_ENV overlays
KrakenJS merges a base config file with environment-specific overlays selected by NODE_ENV. Learn the layout, a worked example, and where JSON configuration reaches its limits.
19 Nov 2025, 23:58 UTC

One config file per environment, not one process.env per controller
You add a staging environment to a Node service and discover database URLs, port numbers, and feature flags hidden behind process.env calls in half a dozen controllers. A typo in one file points staging at the production database. KrakenJS, an Express-based Node framework, centralizes these values in a config/ directory instead.
This post explains how KrakenJS loads a base configuration file, merges an environment-specific overlay selected by NODE_ENV, and makes the result available to route handlers and middleware. It also covers where the approach breaks down and how to verify the behavior in your installed release.
Config files and environment overlays
KrakenJS expects a config/ directory next to your application entry point. The convention is:
- config/config.json — shared defaults used by every environment
- config/development.json — values that override the base for local development
- config/production.json — values that override the base for production
When the application starts, KrakenJS reads the base file, then reads the file matching NODE_ENV and merges it on top. If NODE_ENV is unset, many releases fall back to the base file only, though you should confirm the fallback for your version. The merged object is attached to the Express application instance so controllers and middleware can read it without calling process.env directly.
What NODE_ENV controls at startup
NODE_ENV is not just a label for logging. In KrakenJS it selects the overlay file. A value of development loads config/development.json; production loads config/production.json. The merge behavior for nested keys can differ between releases, so check your installed kraken-js loader if you need exact semantics.
Worked example: base, development, and production overlays
Create the directory and files:
config/config.json:
{
"http": { "port": 3000, "host": "localhost" },
"database": { "url": "mongodb://localhost:27017/dev" },
"features": { "newDashboard": false }
}
config/development.json:
{
"http": { "port": 3000 },
"features": { "newDashboard": true }
}
config/production.json:
{
"http": { "port": 8080 },
"database": { "url": "mongodb://prod-db:27017/app" }
}
With NODE_ENV=development, the running process should use port 3000, localhost, the development database URL, and newDashboard enabled. With NODE_ENV=production, it should use port 8080 and the production database URL.
Run these commands in your project directory; no root permissions are required:
mkdir -p config
npm init -y
npm install kraken-js
Then boot the app:
NODE_ENV=development node index.js
Expected check: the server starts and binds to the port from the merged config. If you add a startup log of the resolved configuration, confirm that development values overrode base values but did not wipe out keys absent from the overlay. Repeat with NODE_ENV=production and confirm the production overlay applied instead.
Risk: changing any JSON file requires a restart. KrakenJS resolves configuration during initialization, so the values are fixed for the lifetime of the process.
Trade-offs and verification
JSON files cannot contain comments or compute values dynamically. If you need a connection string assembled from several parts, or a value that changes without redeploying, file-based config is the wrong place. Committing config/production.json with real credentials also risks accidental exposure; keep secrets out of source control and inject them through environment variables or a secrets manager.
Some KrakenJS releases allow environment variables or command-line arguments to outrank file values, but the exact precedence order varies by version. Do not assume a precedence rule; inspect your installed kraken-js release or test it in a throwaway app before relying on it for deployment-specific settings.
Practical verification:
- Start the app with NODE_ENV=development and log the resolved config.
- Restart with NODE_ENV=production and confirm the port and database URL changed as expected.
- Confirm that a missing required value fails fast rather than silently falling back to an unsafe default.
Closing
Treat config/ as the single source for non-secret settings, add overlays only for environments you actually deploy, and pin your kraken-js version because loader behavior can change between releases. If your team needs comments, dynamic values, or hot reloading without restarts, a JavaScript config module or external config service may fit better—but for static, environment-specific defaults, KrakenJS layering removes the scattered process.env calls that make multi-environment Node apps hard to audit.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.