Skip to main content

Overview

chat.config.ts is the central configuration for ChatJS. It’s auto-generated from lib/config-schema.ts with sensible defaults and inline comments.
# Regenerate chat.config.ts from schema (resets to defaults)
bun chatjs:init

Access patterns

To access the config, import it from @/lib/config:
import { config } from "@/lib/config";

const { appName } = config;

Configuration Shape

The schema is defined in lib/config-schema.ts. Each field’s .describe() comment appears as an inline comment in the generated config.
export type PricingConfig = {
  currency?: string;
  free?: {
    name: string;
    summary: string;
  };
  pro?: {
    name: string;
    monthlyPrice: number;
    summary: string;
  };
};

export type ModelsConfig = {
  /** Provider sort order in model selector */
  providerOrder: string[];
  /** Models to hide from all users */
  disabledModels: AppModelId[];
  /** Default models enabled for new users */
  curatedDefaults: AppModelId[];
  /** Models available to anonymous users */
  anonymousModels: AppModelId[];
  /** Default model for each task type */
  defaults: {
    chat: AppModelId;
    title: AppModelId;
    pdf: AppModelId;
    artifact: AppModelId;
    artifactSuggestion: AppModelId;
    followupSuggestions: AppModelId;
    suggestions: AppModelId;
    polishText: AppModelId;
    formatSheet: AppModelId;
    analyzeSheet: AppModelId;
    codeEdits: AppModelId;
    chatImageCompatible: AppModelId;
    image: AnyImageModelId;
  };
};

export type AnonymousConfig = {
  /** Message credits for anonymous users */
  credits: number;
  /** Tools available to anonymous users */
  availableTools: string[];
  /** Rate limits */
  rateLimit: {
    requestsPerMinute: number;
    requestsPerMonth: number;
  };
};

export type AttachmentsConfig = {
  /** Max file size in bytes after compression */
  maxBytes: number;
  /** Max image dimension (width/height) */
  maxDimension: number;
  /** Accepted MIME types with their file extensions */
  acceptedTypes: {
    "image/png": string[];
    "image/jpeg": string[];
    "application/pdf": string[];
  };
};

export type Config = {
  githubUrl: string;
  appPrefix: string;
  appName: string;
  appDescription: string;
  appUrl: string;

  organization: {
    name: string;
    contact: {
      privacyEmail: string;
      legalEmail: string;
    };
  };

  services: {
    hosting: string;
    aiProviders: string[];
    paymentProcessors: string[];
  };

  /**
   * Feature flags for optional integrations.
   * Set to true to enable - requires corresponding env vars.
   * Validated at build time via scripts/check-env.ts.
   */
  integrations: {
    /** Code sandbox execution (Vercel-native) */
    sandbox: boolean;
    /** Web search */
    webSearch: boolean;
    /** URL content retrieval */
    urlRetrieval: boolean;
    /** MCP tool servers */
    mcp: boolean;
    /** AI image generation (requires BLOB_READ_WRITE_TOKEN) */
    imageGeneration: boolean;
    /** File attachments - images and PDFs (requires BLOB_READ_WRITE_TOKEN) */
    attachments: boolean;
  };

  pricing?: PricingConfig;

  legal: {
    minimumAge: number;
    governingLaw: string;
    refundPolicy: string;
  };

  policies: {
    privacy: {
      title: string;
      lastUpdated?: string;
    };
    terms: {
      title: string;
      lastUpdated?: string;
    };
  };

  /**
   * Auth provider toggles.
   * Set to true to enable - requires corresponding env vars.
   * Validated at build time via scripts/check-env.ts.
   */
  authentication: {
    /** Google OAuth (requires AUTH_GOOGLE_ID + AUTH_GOOGLE_SECRET) */
    google: boolean;
    /** GitHub OAuth (requires AUTH_GITHUB_ID + AUTH_GITHUB_SECRET) */
    github: boolean;
    /** Vercel OAuth (requires VERCEL_APP_CLIENT_ID + VERCEL_APP_CLIENT_SECRET) */
    vercel: boolean;
  };

  /** Model configuration */
  models: ModelsConfig;
  /** Anonymous user configuration */
  anonymous: AnonymousConfig;
  /** File attachment configuration */
  attachments: AttachmentsConfig;
};

Feature flags + env validation

Feature flags live under integrations and authentication. They’re validated at build time by scripts/check-env.ts:
  • Runs as prebuild step before next build
  • Missing env vars will fail the build immediately

Integrations

  • integrations.sandbox: requires VERCEL_OIDC_TOKEN (on Vercel) or VERCEL_TEAM_ID + VERCEL_PROJECT_ID + VERCEL_TOKEN (self-hosted)
  • integrations.webSearch: requires TAVILY_API_KEY or FIRECRAWL_API_KEY
  • integrations.urlRetrieval: requires FIRECRAWL_API_KEY - fetch structured content from URLs
  • integrations.mcp: requires MCP_ENCRYPTION_KEY
  • integrations.imageGeneration: requires BLOB_READ_WRITE_TOKEN - AI-powered image generation tool
  • integrations.attachments: requires BLOB_READ_WRITE_TOKEN - file uploads (images and PDFs)

Authentication

  • authentication.google: requires AUTH_GOOGLE_ID + AUTH_GOOGLE_SECRET
  • authentication.github: requires AUTH_GITHUB_ID + AUTH_GITHUB_SECRET
  • authentication.vercel: requires VERCEL_APP_CLIENT_ID + VERCEL_APP_CLIENT_SECRET

Notes on behavior

  • Anonymous limits: anonymous.credits and rate limits are typically higher in dev and lower in prod (see config.anonymous implementation).
  • Models: models.defaults drives which model is used per task; models.disabledModels hard-hides models globally; models.anonymousModels constrains what anonymous users can pick.