Configuration (exis.config.ts)

ExisJS uses an extremely powerful, fully typed configuration engine that closely resembles Vite or Next.js.

By placing an exis.config.ts file in the root of your project, you gain complete control over the underlying server (Node.js or uWebSockets), middleware (CORS, Helmet, Compression), SSL, and the Plugin ecosystem.


1. Basic Configuration

A basic configuration simply exports the result of defineConfig. This provides flawless TypeScript autocomplete for all available options!

exis.config.ts
import { defineConfig } from 'exisjs/config'
export default defineConfig({  port: 4000,  host: '0.0.0.0',    cors: {    origin: '*',    credentials: true,  },    logger: {    level: 'debug',    pretty: true  }})

2. Dynamic & Phase-Based Config

Often, you'll need different configurations for Development, Production, or Testing (e.g., enabling pretty logging only in development, or changing the Database URL).

ExisJS allows you to export an async function that provides the current phase (Environment).

exis.config.ts
import { defineConfig, PHASE_DEVELOPMENT_SERVER } from 'exisjs/config'
export default async (phase: string, { defaultConfig }: any) => {  const isDev = phase === PHASE_DEVELOPMENT_SERVER
  return defineConfig({    port: Number(process.env.PORT) || 4000,        // Enable pretty logging only in Development    logger: isDev ? { level: 'debug', pretty: true } : false,        // Compress responses in Production    compression: !isDev  })}

The available phases are:

  • PHASE_DEVELOPMENT_SERVER (Triggered via exis dev)
  • PHASE_PRODUCTION_SERVER (Triggered via exis start)
  • PHASE_TEST (Triggered when NODE_ENV=test)

3. Type-Safe Environment Variables

We highly recommend using v.env() from exisjs/validator to strongly type and validate your environment variables before the server starts. You can create an env.ts file and import it directly into your exis.config.ts.

env.ts
import { v } from "exisjs/validator";
export const env = v.env(  v.object({    PORT: v.string().transform(Number).default(4000),    NODE_ENV: v.string().default("development"),    MONGODB_URI: v.string(),  }));
exis.config.ts
import { defineConfig } from 'exisjs/config'import { env } from './env.ts' // Fails fast if variables are missing!
export default defineConfig({  port: env.PORT,  logger: {    pretty: env.NODE_ENV !== "production",  }})

4. Background Jobs & Workers

To enable the background job engine (which powers scheduled Cron jobs and the task queue), you must explicitly configure a queue driver in exis.config.ts.

If this is missing, the job scheduler is completely disabled to save memory.

exis.config.ts
export default defineConfig({  queue: {    driver: 'memory', // Use 'redis' for multi-server production    enableWorkers: true // Set to false to push jobs but not process them  }})

5. The Underlying Server Engine

By default, ExisJS uses the native Node.js HTTP/HTTPS modules. However, you can seamlessly switch the underlying engine to uWebSockets.js (uWS) for significantly higher throughput and performance!

exis.config.ts
export default defineConfig({  // 'auto' will use uWS if installed, otherwise gracefully fallback to Node  server: 'auto', // 'auto' | 'node' | 'uws'})

6. Complete Options Reference

Here is a full breakdown of the configuration schema:

Network & SSL

  • port (number): The port the server will bind to. (Default: 4000)
  • host (string): The host interface to bind to. (Default: '0.0.0.0')
  • ssl (object): Provide { key, cert } strings or Buffers to enable HTTPS natively.
  • http2 (boolean): Enables HTTP/2 support natively. (Defaults to true when SSL is provided).
  • redirectHttp (boolean | number): Automatically intercepts HTTP requests and redirects them to HTTPS.

Global Middleware

  • cors (object | boolean): Global CORS policy configuration (origin, methods, credentials, etc.).
  • helmet (object | boolean): Automatically secures your app with standard HTTP headers. (Enabled by default).
  • compression (object | boolean): Enables Gzip/Brotli compression for all HTTP responses.
  • logger (object | boolean): Configures the internal Pino-based logger (level, pretty).
  • etag (boolean): Automatically generates ETag headers for cache-invalidation.

Performance & Security

  • bodyLimit (number): The maximum allowed size (in bytes) for incoming request bodies. (Default: 1MB)
  • trustProxy (boolean): If true, respects X-Forwarded-For and X-Forwarded-Host headers (essential for apps deployed behind NGINX, Cloudflare, or AWS ELB).
  • keepAlive (object | boolean): Tunes the Keep-Alive timeout and Header timeout limits.

Queues & Plugins

  • queue (object): Configures the Global Job Queue driver (memory or redis) and backpressure settings.
  • plugins (array): Registers framework-level plugins.

7. ExisJS Plugin Ecosystem

The ExisJS configuration file is also where you integrate native plugins and modules.

You can easily build your own plugins using defineModule from exisjs/module. Under the hood, plugins get full access to the app instance to register routes, providers, or lifecycle hooks!

exis.config.ts
import { defineConfig } from 'exisjs/config'import { defineModule } from 'exisjs/module'
// 1. Create a custom plugin (e.g., a mock GraphQL endpoint)const graphqlPlugin = (options: { endpoint: string }) => defineModule({  name: 'graphql',  routes: (app) => {    app.post(options.endpoint, (req, res) => res.json({ data: 'GraphQL Response' }))  }})
// 2. Register it in your configexport default defineConfig({  plugins: [    graphqlPlugin({ endpoint: '/graphql' })  ]})