Lithia

Configuration

Configure your Lithia application with lithia.config.ts

Introduction

Lithia uses a configuration file (lithia.config.ts) to customize server behavior, CORS settings, and other framework options. Unlike traditional frameworks that require entry point files, Lithia handles server initialization automatically - you just configure how it should run.

The configuration file is optional. If you don't provide one, Lithia uses sensible defaults.

Basic Configuration

Create lithia.config.ts in your project root:

lithia.config.ts
import { defineLithiaConfig } from 'lithia';

export default defineLithiaConfig({
  server: {
    port: 3000,
    host: 'localhost'
  }
});

The defineLithiaConfig helper provides TypeScript autocomplete and validation.

Configuration Options

Server Configuration

Control how your server runs:

lithia.config.ts
export default defineLithiaConfig({
  server: {
    port: 3000,                  // Port to listen on (default: 3000)
    host: 'localhost',           // Host to bind to (default: 'localhost')
      
    request: {
      maxBodySize: 1024 * 1024,  // Max request body size in bytes (default: 1MB)
    
      queryParser: {
        array: {
          enabled: true,         // Parse array query params (default: true)
          delimiter: ','         // Array delimiter (default: ',')
        },
        number: {
          enabled: true          // Parse numbers automatically (default: true)
        },
        boolean: {
          enabled: true          // Parse booleans automatically (default: true)
        }
      }
    }
  }
});

Query parser examples:

With default configuration, Lithia automatically parses query parameters:

URLParsed as
?page=1{ page: 1 } (number)
?active=true{ active: true } (boolean)
?tags=red,blue,green{ tags: ['red', 'blue', 'green'] } (array)
?name=John{ name: 'John' } (string)

To disable automatic parsing:

lithia.config.ts
export default defineLithiaConfig({
  server: {
    request: {
      queryParser: {
        array: { enabled: false },
        number: { enabled: false },
        boolean: { enabled: false }
      }
    }
  }
});

Now everything is parsed as strings: ?page=1{ page: "1" }

CORS Configuration

Configure Cross-Origin Resource Sharing for your API:

lithia.config.ts
export default defineLithiaConfig({
  cors: {
    origin: ['https://myapp.com', 'https://admin.myapp.com'],
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
    allowedHeaders: ['Content-Type', 'Authorization', 'X-Custom-Header'],
    exposedHeaders: ['X-Total-Count', "X-Powered-By"],
    credentials: true,
    maxAge: 86400,                  // 24 hours in seconds
    optionsSuccessStatus: 204
  }
});

Default CORS values:

defaults
{
  origin: ['*'], // Allow all origins
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  exposedHeaders: [],
  credentials: false,
  maxAge: 86400,
  optionsSuccessStatus: 204
}

Common CORS configurations:

Development - Allow all origins
export default defineLithiaConfig({
  cors: {
    origin: ['*'],
    credentials: false
  }
});
Production - Specific domains
export default defineLithiaConfig({
  cors: {
    origin: [
      'https://myapp.com',
      'https://www.myapp.com'
    ],
    credentials: true
  }
});

Debug Mode

Enable debug logging for development:

lithia.config.ts
export default defineLithiaConfig({
  debug: true  // Enable detailed logging (default: false)
});

By default, debug mode is automatically enabled when DEBUG environment variable is set to true, but it'll be overrided by the debug option.

Build Configuration

Configure the build process:

lithia.config.ts
export default defineLithiaConfig({
  build: {
    builder: 'swc'  // Currently only 'swc' is supported
  }
});

Studio Configuration

Enable or disable the Lithia Studio development UI:

lithia.config.ts
export default defineLithiaConfig({
  studio: {
    enabled: true  // Enable Studio on port 8473 (default: false)
  }
});

When enabled, access the Studio at http://localhost:8473.

Note: Studio always runs on port 8473 and cannot be changed.

Hooks Configuration

Configure lifecycle hooks for your application. Hooks allow you to run custom code at specific points in the request and middleware lifecycle.

Request Lifecycle Hooks

lithia.config.ts
export default defineLithiaConfig({
  hooks: {
    // Called before request processing
    'request:before': async (req, res) => {
      console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
      
      // Add custom request context
      req.set('requestId', crypto.randomUUID());
      req.set('startTime', Date.now());
    },
    
    // Called after request processing
    'request:after': async (req, res) => {
      // Get custom request context
      const duration = Date.now() - req.get<number>('startTime');
      const requestId = req.get<string>('requestId');
      
      console.log(`Request ${requestId} completed with status ${res.statusCode} in ${duration}ms`);
    },
    
    // Called when request processing throws an error
    'request:error': async (req, res, error) => {
      const requestId = req.get<string>('requestId');
      
      console.error(`Request ${requestId} failed:`, error);
      
      // Send error to monitoring service
      await errorTracking.captureException(error, {
        request: {
          method: req.method,
          url: req.url,
          headers: req.headers
        }
      });
    }
  }
});

The request context set in the hooks system is available to all middleware and route handlers.

See more about the request context in Request.

Middleware Lifecycle Hooks

lithia.config.ts
export default defineLithiaConfig({
  hooks: {
    // Called before each middleware execution
    'middleware:beforeExecute': async (middleware, req, res) => {
      console.log(`Executing middleware: ${middleware.name}`);
    
      // Track middleware execution time
      const middlewareTimings = req.get<Record<string, number>>('middlewareTimings') || {};
      middlewareTimings[middleware.name] = Date.now();
      
      req.set('middlewareTimings', middlewareTimings);
    },
    
    // Called after each middleware execution
    'middleware:afterExecute': async (middleware, req, res) => {
      const middlewareTimings = req.get<Record<string, number>>('middlewareTimings') || {};
      const duration = Date.now() - middlewareTimings[middleware.name];
      
      console.log(`Middleware ${middleware.name} completed in ${duration}ms`);
    },
    
    // Called when middleware throws an error
    'middleware:error': async (middleware, req, res, error) => {
      console.error(`Middleware ${middleware.name} failed:`, error);
    }
  }
});

Available Hook Types

HookParametersDescription
request:beforereq, resCalled before request processing starts
request:afterreq, resCalled after request processing completes
request:errorreq, res, errorCalled when request processing fails
middleware:beforeExecutemiddleware, req, resCalled before each middleware executes. middleware contains info about the middleware (name, position, route)
middleware:afterExecutemiddleware, req, resCalled after each middleware completes
middleware:errormiddleware, req, res, errorCalled when middleware throws an error

See more about the hook types in API Reference.

See Hooks for more advanced hook patterns and best practices.

Environment-Based Configuration

Use environment variables to customize configuration per environment:

lithia.config.ts
import { defineLithiaConfig } from 'lithia';

const isDev = process.env.NODE_ENV !== 'production';

export default defineLithiaConfig({
  debug: isDev,
  server: {
    port: parseInt(process.env.PORT || '3000'),
    host: process.env.HOST || 'localhost'
  },
  cors: {
    origin: isDev 
      ? ['*'] 
      : process.env.ALLOWED_ORIGINS?.split(',') || [],
    credentials: !isDev
  },
});

For security reasons, studio only runs with Lithia.js development server.

Troubleshooting

Configuration not loading

Make sure your file is named exactly lithia.config.ts and is in the project root:

project structure
my-app/
├── src/
├── lithia.config.ts  ← Must be here
├── package.json
└── tsconfig.json

TypeScript errors

If you get TypeScript errors, ensure you have the correct imports:

lithia.config.ts
import { defineLithiaConfig } from 'lithia';

export default defineLithiaConfig({
// Configuration here
});

CORS issues

If you're getting CORS errors:

  1. Check your origin configuration matches your frontend URL exactly
  2. Enable credentials: true if using cookies/auth
  3. Add required headers to allowedHeaders
lithia.config.ts
export default defineLithiaConfig({
  cors: {
    origin: ['http://localhost:5173'],  // Exact match required
    credentials: true,
    allowedHeaders: ['Content-Type', 'Authorization']
  }
});