Skip to content

Configuration

You configure the framework by passing a plain object into the Application constructor. Each top-level key enables & configures a module. Omit a section to skip initialization.

High-Level Structure

ts
interface AppConfig {
  webserver?: { port?: number; routesDirectory?: string; controllersDirectory?: string; host?: string };
  websocket?: { enabled?: boolean; path?: string; maxPayload?: number };
  queue?: { enabled?: boolean; prefix?: string };
  redis?: { host: string; port?: number; password?: string; db?: number };
  cache?: { enabled?: boolean; defaultTtlMs?: number };
  database?: {
    /* MikroORM options: entities, migrations, etc. */
  };
  logger?: { level?: string; json?: boolean; redact?: string[] };
  lifecycle?: { gracefulShutdown?: { timeoutMs?: number } };
  performance?: { enabled?: boolean; thresholds?: Partial<Record<string, number>> };
  auth?: { jwt?: { issuer?: string; audience?: string; publicKey?: string; privateKey?: string } };
  command?: {
    /* CLI specific configuration */
  };
  // ... future extensions
}

Note: The exact TypeScript interface may differ; inspect exported types in @scpxl/nodejs-framework for authoritative definitions.

Minimal Example

ts
new Application({
  webserver: { port: 3000 },
  logger: { level: 'info' },
});

Full(er) Example

ts
new Application({
  webserver: { port: Number(process.env.PORT) || 3000, routesDirectory: 'src/routes' },
  websocket: { enabled: true, path: '/ws' },
  queue: { enabled: true, prefix: 'app' },
  redis: { host: process.env.REDIS_HOST || '127.0.0.1', port: 6379 },
  cache: { enabled: true, defaultTtlMs: 60_000 },
  database: {
    /* MikroORM config (entities, migrations, driver) */
  },
  logger: { level: process.env.LOG_LEVEL || 'info', json: process.env.NODE_ENV === 'production' },
  lifecycle: { gracefulShutdown: { timeoutMs: 15000 } },
  performance: { enabled: true, thresholds: { http: 800, database: 400 } },
  auth: { jwt: { issuer: 'my-service', audience: 'api-clients' } },
});

Merging & Defaults

  • Framework merges your object with internal defaults per module.
  • Unknown keys are ignored (future proofing).
  • Provide only overrides; stick with defaults where possible.

Module Reference

Web Server (webserver)

KeyTypeDefaultDescription
portnumber3000Listen port
hoststring0.0.0.0Bind interface
routesDirectorystringundefinedAuto-load route definitions (files exporting route objects)
controllersDirectorystringundefinedOptional controller class auto-registration

WebSocket (websocket)

KeyTypeDefaultNotes
enabledbooleanfalseMust be true to start WS server
pathstring/wsUpgrade path
maxPayloadnumber1MB (approx)Reject oversized messages

Queue (queue)

KeyTypeDefaultDescription
enabledbooleanfalseEnable BullMQ integration
prefixstringpxlQueue key namespace

Redis (redis)

KeyTypeDefaultDescription
hoststringrequiredRedis host
portnumber6379Port
passwordstringundefinedAuth password
dbnumber0Logical DB index

Cache (cache)

KeyTypeDefaultDescription
enabledbooleantrueToggle cache manager
defaultTtlMsnumber0 (no expiry)Default TTL for set operations

Database (database)

Pass through MikroORM configuration (entities, migrations, seeding). Common keys:

KeyTypeDescription
entitiesany[]Entity classes/paths
migrationsobjectMikroORM migration config
dbNamestringDatabase name (if not using URL)
clientUrlstringConnection string

Logger (logger)

KeyTypeDefaultDescription
levelstringinfoMinimum level (e.g. debug, info, warn, error)
jsonbooleanenv basedStructured JSON output toggle
redactstring[][]Keys to redact from logs

Lifecycle (lifecycle)

KeyTypeDefaultDescription
gracefulShutdown.timeoutMsnumber10000Max total shutdown duration before forcing exit

Performance (performance)

KeyTypeDefaultDescription
enabledbooleantrueMaster toggle
thresholdsobjectModule-specific defaultsOverride per operation type (http, database, cache, queue, websocket, custom)

Auth (auth.jwt)

KeyTypeDescription
issuerstringJWT issuer claim
audiencestringJWT audience claim
publicKeystringVerification key (if asymmetric)
privateKeystringSigning key

Environment Variable Mapping

Create a helper to translate process env into config:

ts
export function buildConfig(): AppConfig {
  return {
    webserver: { port: Number(process.env.PORT) || 3000 },
    logger: { level: process.env.LOG_LEVEL || 'info' },
    redis: process.env.REDIS_HOST
      ? { host: process.env.REDIS_HOST, port: Number(process.env.REDIS_PORT) || 6379 }
      : undefined,
  };
}

Validation

Use a schema library (e.g. zod or joi) to validate env + config early. Example with zod:

ts
import { z } from 'zod';

const EnvSchema = z.object({
  PORT: z.string().optional(),
  REDIS_HOST: z.string().optional(),
});

const env = EnvSchema.parse(process.env);

Fail fast at boot if required configuration is missing.

Progressive Activation

Start with only webserver + logger, then add modules as needs emerge. This keeps initial complexity low and surfaces integration boundaries clearly.

Overriding Defaults at Runtime

You can compose config objects:

ts
const base = buildConfig();
const testOverrides = { logger: { level: 'error' } };
const finalConfig = { ...base, ...testOverrides };

Avoid deep-merging arrays (prefer explicit replacement) to prevent subtle bugs.

Common Pitfalls

IssueCauseMitigation
Redis connect errors spam logsWrong host / networkMake redis optional until stable
Hanging shutdownLong DB query in onShutdownAdd timeout and cancel/abort logic
High p95 latencyThresholds too high to notice earlyLower per-module thresholds incrementally

Next


Planned additions: generated type reference & dynamic schema docs.

Released under the ISC License.