bext.config.toml

Full reference for all configuration options. See docs/platform/06-config-reference.md in the bext repository for the complete spec.

Sections

Section Description
[server] Listen address, static dir, hybrid mode proxy URL
[cache] ISR cache (max entries, TTL, SWR), tenant cache TTL
[render] Worker count, bundle path, streaming + RSC toggles
[build] Build script, watch dirs, CSS config
[build.css] Extra CSS sources and files for Rust-native Tailwind
[nextjs] On-demand rendering, cache TTL, shell limits
[admin] Admin panel enable, JWT secret, users
[auth] JWT secret, cookie name, localhost bypass
[cors] Allowed origins, max age
[rate_limit] Requests per minute, enable/disable
[i18n] Locales, default locale, prefix strategy
[database] PostgreSQL URL, connection pool
[license] License key for Pro/Enterprise features
[redis] Redis URL for horizontal scaling
[tls] Auto-TLS (ACME), manual certs
[waf] WAF rules, IP filter, geo-blocking
[realtime] SSE/WebSocket hub config
[plugins] Plugin directories, WASM config
[storage] Object storage for backups (local, S3, R2)
[storage.backup] Automatic backup schedule and retention
[endpoints] Endpoint visibility (health, metrics, api, obs, admin)
[telemetry] OpenTelemetry endpoint, sampling

[license]

[license]
# License key for Pro or Enterprise features.
# Can also be set via BEXT_LICENSE_KEY environment variable.
# Omit for Community (free) tier.
key = "BEXT-PRO-eyJ0aWVy..."

See Licensing for tier details and Setup for configuration options.

[storage]

Object storage for backups. Supports local filesystem, AWS S3, and Cloudflare R2.

[storage]
provider = "s3"                          # "local", "s3", or "r2"
bucket = "my-bext-backups"
region = "us-east-1"                     # Ignored for R2
endpoint = ""                            # Required for R2/MinIO
prefix = "bext/prod/"                    # Optional key prefix
access_key_env = "BEXT_STORAGE_ACCESS_KEY"   # Env var name for access key
secret_key_env = "BEXT_STORAGE_SECRET_KEY"   # Env var name for secret key
local_path = ".bext/storage"             # Path for local provider

[storage.backup]
enabled = true                           # Enable automatic scheduled backups
schedule = "0 2 * * *"                   # Cron schedule (default: daily 2am)
retention_days = 30                      # Auto-delete backups older than N days
include_blobs = true                     # Include blob files in backups
include_databases = true                 # Include SQLite databases
include_cache = false                    # Include ISR cache snapshot
max_size_mb = 0                          # Max backup size (0 = unlimited)

CLI usage:

bext-server backup create --provider s3 --bucket my-bext
bext-server backup list
bext-server backup restore backup-20260404-020000

See CLI Reference for all flags.

Quick Example

[server]
listen = "0.0.0.0:3061"
static_dir = "./dist/static"

[license]
key = "BEXT-PRO-eyJ0aWVy..."

[cache.isr]
max_entries = 10_000
default_ttl_ms = 60_000
default_swr_ms = 3_600_000

[render]
bundle_path = "dist/ssr-bundle.js"
workers = 4

[rate_limit]
requests_per_minute = 600
enabled = true

Render Engine

[render]
workers = 4                  # SSR worker thread count (applies to both engines)
bundle_path = "dist/ssr-bundle.js"  # Pre-built SSR bundle path

# Streaming SSR (V8 only) — react-dom/server renderToReadableStream
# driven by bext's custom event-loop driver. Required for async server
# components, , and the use(promise) hook.
streaming = true
streaming_timeout_ms = 5000  # Wall-clock cap per render
streaming_stall_ms   = 250   # Bail out if no new chunk for this long

# React Server Components (V8 only, experimental). When enabled,
# /__bext/rsc/<path> serves the route's Flight payload via
# react-server-dom-parcel. Compiled in a separate bundle with
# --conditions=react-server.
rsc = false

See V8 Render Engine for the full streaming + RSC architecture.

Next.js / PRISM On-Demand

[nextjs]
compat = "full"              # "full" (real layouts) or "prism" (default)
on_demand = true             # Per-route compilation (default: false)
shared_react = false         # Use globalThis.React (auto-set when V8 layered pipeline active)
cache_ttl = 60               # Response cache TTL in seconds (default: 60)
cache_swr = 300              # Stale-while-revalidate window in seconds (default: 300)
max_shell_size = 524288      # Max site shell bundle size in bytes (default: 512KB)

CSS Build

[build.css]
extra_sources = ["../shared/ui/src"]   # Additional dirs to scan for Tailwind classes
extra_css = [                          # CSS files to concatenate into styles.css
  "../shared/ui/src/styles/tokens.css",
  "../shared/ui/src/styles/global.css",
  "../shared/ui/src/styles/components.css",
]

Generate CSS with: bext-server css [dir] or bext-server css --all sites/

Admin Panel

[admin]
enabled = true
jwt_secret = "your-admin-jwt-secret"

[[admin.users]]
username = "admin"
password_hash = "sha256:<sha256-hash>"   # echo -n 'password' | sha256sum

Access at /__bext/admin/. JSON login endpoint at /__bext/admin/api/login/json.

Generate credentials with the CLI instead of manual hashing:

bext config credentials create --username admin --role super_admin

Endpoint Visibility

Control which built-in endpoint groups are exposed. Disabled groups return 404.

[endpoints]
health = true       # GET /health (default: true)
metrics = false     # GET /metrics — Prometheus (default: true)
api = true          # /api/* management — requires super_admin (default: true)
obs = true          # /__bext/obs/* observability — requires viewer (default: true)
admin = true        # /__bext/admin/* panel — overrides [admin].enabled when set

When admin is omitted, it follows [admin].enabled. See Endpoints & Credentials for CLI tools and full endpoint listing.