Configuration Directory in usekaneo/kaneo: How Environment Configuration Works

No, usekaneo/kaneo does not have a top-level configuration directory. Instead, the project uses a decentralized environment-based approach where configuration is split between a central .env.sample file and feature-specific config.ts modules throughout the codebase.

This approach keeps configuration scoped to the services and plugins that actually need it, rather than centralizing everything in a single folder. The Kaneo project is a TypeScript-based monorepo, and its configuration pattern reflects modern Node.js best practices for environment-driven applications.


How Kaneo Handles Configuration Without a Config Directory

The Central Environment File

All runtime configuration starts with .env.sample at the repository root. This file serves as the single source of truth for required environment variables:

  1. KANEO_CLIENT_URL – URL for the frontend client
  2. KANEO_API_URL – URL for the API server
  3. AUTH_SECRET – Secret key for authentication
  4. DATABASE_URL – PostgreSQL connection string
  5. POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD – Database credentials
  6. CORS_ORIGINS – Allowed CORS origins
  7. VITE_API_URL – API URL for Vite build process
  8. REDIS_URL – Redis connection string

Developers copy this to .env and fill in actual values. The project loads these via dotenv/config at runtime.


Feature-Specific Configuration Files

Billing Configuration

In apps/api/src/billing/config.ts, the billing system reads its settings directly from process.env:

import { env } from "process";

export const BILLING_ENABLED = env.BILLING_ENABLED === "true";
export const STRIPE_SECRET_KEY = env.STRIPE_SECRET_KEY ?? "";
export const STRIPE_WEBHOOK_SECRET = env.STRIPE_WEBHOOK_SECRET ?? "";
export const STRIPE_PUBLIC_KEY = env.STRIPE_PUBLIC_KEY ?? "";

This pattern validates and transforms environment variables at the module boundary, converting BILLING_ENABLED from string to boolean and providing defaults with nullish coalescing.

Plugin Configuration Modules

Each integration plugin follows the same decentralized pattern. In apps/api/src/plugins/slack/config.ts:

export const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN ?? "";
export const SLACK_APP_ID = process.env.SLACK_APP_ID ?? "";
export const SLACK_SIGNING_SECRET = process.env.SLACK_SIGNING_SECRET ?? "";

The GitHub, Discord, and other plugins implement identical config.ts files in their respective directories.


Practical Configuration Examples

Loading Environment Variables

// apps/api/src/index.ts or entry point
import "dotenv/config"; // Loads .env into process.env automatically

// Access variables anywhere in the application
const apiUrl = process.env.KANEO_API_URL;

Using Billing Configuration

// In a billing controller or service
import { BILLING_ENABLED, STRIPE_SECRET_KEY } from "./config";

if (!BILLING_ENABLED) {
  throw new HTTPException(403, "Billing is disabled");
}

// Initialize Stripe only when billing is enabled
import Stripe from "stripe";
const stripe = new Stripe(STRIPE_SECRET_KEY, { apiVersion: "2023-10-16" });

Using Slack Plugin Configuration

// apps/api/src/plugins/slack/client.ts
import { WebClient } from "@slack/web-api";
import { SLACK_BOT_TOKEN } from "./config";

// Fail fast if not configured
if (!SLACK_BOT_TOKEN) {
  console.warn("Slack integration disabled: SLACK_BOT_TOKEN not set");
}

export const slackClient = SLACK_BOT_TOKEN 
  ? new WebClient(SLACK_BOT_TOKEN) 
  : null;

Configuration File Locations

File Path Purpose
.env.sample Template for all required environment variables
apps/api/src/billing/config.ts Billing feature configuration wrapper
apps/api/src/plugins/slack/config.ts Slack integration settings
apps/api/src/plugins/github/config.ts GitHub integration settings
apps/api/src/plugins/discord/config.ts Discord integration settings

Why Kaneo Avoids a Central Config Directory

This decentralized approach provides three advantages:

  • Scoped configuration – Each module owns its settings, reducing merge conflicts
  • Lazy loading – Configuration modules are only imported when features are used
  • Type safety – TypeScript can enforce config shapes per feature without a global type definition

The pattern aligns with the conventional configuration approach used in modern JavaScript frameworks, where environment variables replace static config files.


Summary

  • usekaneo/kaneo has no config/ directory – configuration is environment-driven
  • .env.sample at root defines all required variables for the entire application
  • Feature-specific config.ts files in apps/api/src/** transform and export relevant process.env values
  • Billing, Slack, GitHub, Discord, and other plugins each maintain their own configuration module
  • The pattern enables optional features to disable gracefully when environment variables are absent

Frequently Asked Questions

Where do I set database credentials in Kaneo?

Database credentials go in the .env file, copied from .env.sample. Set DATABASE_URL with the full PostgreSQL connection string, or use the split POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD variables for Docker Compose setups.

How do I enable billing in Kaneo?

Set BILLING_ENABLED=true in your .env file and provide the three Stripe-related variables: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, and STRIPE_PUBLIC_KEY. The billing module in apps/api/src/billing/config.ts automatically picks these up.

Can I add a custom config directory to Kaneo?

While possible, it would break the established pattern. If you need additional configuration, create a new config.ts file in the relevant feature directory following the existing pattern of reading from process.env with nullish coalescing for defaults.

How does Kaneo handle missing environment variables?

Each config.ts module handles missing variables independently. Most use the ?? "" pattern to provide empty string defaults, while critical variables like DATABASE_URL typically cause startup failures if absent. Check ENVIRONMENT_SETUP.md in the repository for required vs. optional variables.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →