Skip to content

@json-express/config ​

Advanced file-based configuration provider for JSONExpress.

The @json-express/config package implements IConfigProvider and provides a powerful, multi-format configuration engine. It supports JSON, YAML, JavaScript, and TypeScript configuration files with environment-specific overrides.

If you need more flexibility than simple .env variables, this is the configuration engine you want.

Installation ​

bash
npm install @json-express/config

Configuration File Discovery ​

The provider searches your project root for configuration files in the following formats (in order of priority):

jex.config.json
jex.config.yml / jex.config.yaml
jex.config.js / jex.config.cjs / jex.config.mjs
jex.config.ts

Environment-Specific Overrides ​

You can create environment-specific configuration files that are deeply merged on top of your base configuration:

jex.config.ts          ← Base (always loaded)
jex.config.production.ts  ← Merged on top when NODE_ENV=production
jex.config.staging.ts     ← Merged on top when NODE_ENV=staging

This follows the exact same cascading pattern used by frameworks like Vite and Next.js.

Usage ​

typescript
// jex.config.ts
export default ({ env }: { env: string }) => ({
    port: env === 'production' ? 8080 : 3000,
    auth: {
        secret: process.env.JWT_SECRET,
        exclude: ['/auth/login', '/health']
    },
    swagger: {
        title: 'My Enterprise API',
        version: '2.0.0'
    }
});

YAML Configuration ​

yaml
# jex.config.yml
port: 3000
auth:
  secret: ${JWT_SECRET}
  exclude:
    - /auth/login
    - /health

Core Features ​

1. Deep Merge Strategy ​

If you have a base jex.config.ts and a jex.config.production.ts, the provider performs a recursive deep merge. Nested objects are merged key-by-key, and arrays are replaced (not concatenated). This ensures production overrides are precise and predictable.

2. Runtime TypeScript Transpilation ​

The provider uses Jiti to natively import .ts configuration files at runtime without requiring a separate build step. This means you get full TypeScript autocompletion and type safety in your configuration files.

3. Async Factory Pattern ​

Because loading configuration files may involve asynchronous operations, the provider uses a static init() factory method instead of a constructor:

typescript
const config = await AdvancedConfigProvider.init(process.cwd(), 'production');
const port = config.get<number>('port', 3000);
  • @json-express/config-env: The simpler, .env-only alternative. Use this if you don't need file-based configuration.
  • @json-express/core: The runtime that resolves the active config provider and hands it to every plugin during boot.