const { z } = require('zod');
const ConfigSchema = z.object({
env: z.enum(['development', 'test', 'production']).default('development'),
port: z.coerce.number().int().positive().default(3000),
database: z.object({
url: z.string().url(),
poolSize: z.coerce.number().int().min(1).max(50).default(10),
ssl: z.coerce.boolean().default(false),
}),
features: z.object({
signups: z.coerce.boolean().default(true),
}).default({}),
});
module.exports = { ConfigSchema };
const fs = require('fs');
const path = require('path');
const { ConfigSchema } = require('./schema');
function envOverrides() {
const out = { database: {}, features: {} };
if (process.env.NODE_ENV) out.env = process.env.NODE_ENV;
if (process.env.PORT) out.port = process.env.PORT;
if (process.env.DATABASE_URL) out.database.url = process.env.DATABASE_URL;
if (process.env.DB_POOL_SIZE) out.database.poolSize = process.env.DB_POOL_SIZE;
if (process.env.FEATURE_SIGNUPS) out.features.signups = process.env.FEATURE_SIGNUPS;
return out;
}
function deepMerge(base, extra) {
const result = Array.isArray(base) ? [...base] : { ...base };
for (const key of Object.keys(extra)) {
const value = extra[key];
if (value && typeof value === 'object' && !Array.isArray(value)) {
result[key] = deepMerge(result[key] || {}, value);
} else if (value !== undefined) {
result[key] = value;
}
}
return result;
}
function deepFreeze(obj) {
for (const key of Object.keys(obj)) {
const value = obj[key];
if (value && typeof value === 'object') deepFreeze(value);
}
return Object.freeze(obj);
}
function load(filePath) {
const target = filePath || path.join(process.cwd(), 'config.json');
let fileConfig = {};
if (fs.existsSync(target)) {
fileConfig = JSON.parse(fs.readFileSync(target, 'utf8'));
}
const merged = deepMerge(fileConfig, envOverrides());
return ConfigSchema.parse(merged);
}
const config = deepFreeze(load());
module.exports = config;
module.exports.load = load;
const { Pool } = require('pg');
const config = require('./config');
let pool;
function getPool() {
if (!pool) {
pool = new Pool({
connectionString: config.database.url,
max: config.database.poolSize,
ssl: config.database.ssl ? { rejectUnauthorized: false } : false,
});
}
return pool;
}
async function query(text, params) {
const client = await getPool().connect();
try {
return await client.query(text, params);
} finally {
client.release();
}
}
module.exports = { getPool, query };
A common need in a Node.js service is to read configuration from disk and the environment exactly once at startup, validate it, and then hand the same frozen object to every module that asks for it. This snippet implements that with the module cache: because Node caches the result of require/import per resolved path, a module that computes its config on first load and exports the result naturally becomes a process-wide singleton.
In config.js, the loader merges three layers in precedence order — a JSON file, environment variables, and hard defaults — then runs the merged shape through a schema. The load() function reads the file with readFileSync (synchronous is fine here because it happens once, during boot, before the server accepts traffic), parses it, and overlays envOverrides() so that a PORT or DATABASE_URL in the environment always wins. The parsed config is validated by ConfigSchema from schema.js; schema.parse throws on the first bad field, so a misconfigured deploy fails fast and loudly instead of surfacing an undefined deep inside request handling.
The crucial line is module.exports = deepFreeze(load()). It runs load() a single time at module-evaluation and freezes the object recursively, so consumers cannot accidentally mutate shared state and create spooky action at a distance between modules. Every later require('./config') returns the cached, frozen instance rather than re-reading the file.
schema.js uses zod to describe the expected shape: coercions turn string env vars into numbers, .default() supplies fallbacks, and .url() enforces format. Keeping validation in its own module keeps the loader focused on I/O and merging.
db.js shows a typical consumer. It simply imports config and reads config.database; it never touches process.env or the file itself, which keeps the config surface centralized and testable. The trade-off of the module-cache singleton is that it hides a global and complicates unit testing — swapping config requires jest.resetModules or dependency injection. For that reason the loader is exported as load too, so tests can construct fresh instances with an explicit path. This pattern fits the twelve-factor idea of config living in the environment while giving the rest of the codebase one clean, immutable object to depend on.
Related snips
module Api
module V1
class UsersController < BaseController
def show
user = User.includes(:profile).find(params[:id])
ETags for conditional requests and caching
class SignupForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :account_name, :string
attribute :email, :string
Shallow Controller, Deep Params: Form Object Pattern
package com.example.myapp
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
Dependency injection with Hilt
json.array! @posts do |post|
json.cache! ['v1', post], expires_in: 1.hour do
json.id post.id
json.title post.title
json.excerpt post.excerpt
json.published_at post.published_at
Fragment caching for expensive JSON serialization
#!/usr/bin/env bash
set -euo pipefail
export VAULT_ADDR="https://vault.internal:8200"
export VAULT_TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}"
Secrets management with environment isolation and Vault
<?php
namespace App\Providers;
use App\Contracts\PaymentGateway;
use App\Services\StripePaymentGateway;
Laravel service container and dependency injection
Share this code
Here's the card — post it anywhere.