Krantho is in active development and not yet published to npm. Read what that means today.
esc

Search the documentation and product pages. Type “theme” to switch themes.

Features

Typed configuration

The same code runs on every host; what differs between them is configuration you can read in one place.

Problem

Configuration spread across files, environment variables and code paths is hard to reason about. A typo in a variable name shows up as odd behavior in production. A missing secret is found one error at a time, on each restart.

Approach

@krantho/config resolves one typed tree in one pass at startup: defaults, then krantho.config.ts, then the environment, which wins. The tree covers site identity, persistence, authentication, page caching, media, SEO seeds and the LLM provider.

  • The environment wins. Every leaf can be set from an environment variable, except structured ones such as the SEO types of each collection, which are set in code.
  • Every problem at once. A bad value, a missing required field and a rule spanning two leaves are reported together, each naming its path, and most also the variable that sets it.
  • Secrets stay on the server. A secret leaf also reads from a file named by its _FILE variable, is redacted in any dump of the tree, and never reaches a browser; only the public part of the tree is serialized.
  • Data, not wiring. Configuration holds values. Collections, plugins and hooks are code, passed to the handler.

Proof

A deployment that picks S3 for media but forgets two settings fails at startup with one message:

Startup
Invalid krantho configuration:
  - media.s3.bucket: required when media.provider is "s3" (KRANTHO_MEDIA_S3_BUCKET)
  - media.s3.region: required when media.provider is "s3" (KRANTHO_MEDIA_S3_REGION)

The configuration reference is generated from the same tree by envReference() in @krantho/config, so it lists every variable the code reads.

krantho.config.ts
import { defineKranthoConfig } from '@krantho/config'

// krantho.com's own configuration. Data only, resolved once at startup:
// defaults, then this file, then the environment.
export default defineKranthoConfig({
  site: {
    domain: 'krantho.com',
    name: 'Krantho',
    language: 'en',
    baseUrl: 'https://krantho.com',
  },
  // The site's own Schema.org identity and collection archetypes, seeded into
  // the database on first boot; /admin → SEO edits them from there
  seo: {
    configDir: './krantho.seo',
  },
  // Pages stay cached until a content change invalidates them
  cache: { pages: 'next-isr' },
})

// In production the environment sets the rest, secrets included:
//   KRANTHO_PERSISTENCE_PROVIDER=postgres
//   KRANTHO_PERSISTENCE_POSTGRES_URL=postgres://…
//   KRANTHO_AUTH=oidc

Limits

  • Configuration is resolved once, at startup. Changing a value means a restart.
  • Some settings are stored in the database after first boot and edited in the admin from then on, such as the LLM provider and model used for enrichment.