config()
The config() function sets global dev configuration — namespace and value overrides that are applied before rendering main.ct.
Values passed here are deep-merged on top of your values.json (or values.yaml), allowing you to toggle dev-specific behavior without changing production config.
Signature
Section titled “Signature”function config(options: ConfigOptions): void| Parameter | Type | Required | Description |
|---|---|---|---|
options | ConfigOptions | yes | Configuration object with namespace and/or values. |
Returns void.
ConfigOptions
Section titled “ConfigOptions”interface ConfigOptions { namespace?: string; values?: Record<string, any>;}Fields
Section titled “Fields”namespace
Section titled “namespace”namespace?: stringKubernetes namespace to deploy to during dev mode. Overrides the namespace from main.ct.
If not set, the namespace from the rendered resources is used as-is.
config({ namespace: "myapp-dev-john",});A common pattern is to use prompt() to create per-developer namespaces:
const USERNAME = prompt("Your username?");
config({ namespace: `myapp-dev-${USERNAME}`,});values
Section titled “values”values?: Record<string, any>Key-value pairs that are deep-merged on top of values.json before rendering main.ct.
This lets you override any value in your template — toggle dev mode, change domains, set replica counts, etc.
config({ values: { dev: true, replicas: 1, hosts: [ { name: "api", host: "api-dev.example.com" }, ], },});Deep merge behavior
Section titled “Deep merge behavior”Values are merged recursively using DeepMergeValues(base, overlay):
- Primitive values — overlay replaces base.
- Nested objects — merged recursively (both sides preserved, overlay wins on conflicts).
- Arrays — overlay replaces base (no element-level merge).
- Neither
basenoroverlayare mutated — a new object is returned.
Example
Section titled “Example”Given values.json:
{ "replicas": 3, "features": { "cache": true, "metrics": true }, "hosts": ["prod.example.com"]}And config() call:
config({ values: { replicas: 1, features: { cache: false, }, hosts: ["dev.example.com"], },});The merged values passed to main.ct will be:
{ "replicas": 1, "features": { "cache": false, "metrics": true }, "hosts": ["dev.example.com"]}Note how features.metrics is preserved (recursive merge), while hosts is fully replaced (array override).
When config() runs
Section titled “When config() runs”config() is evaluated synchronously during dev.ct execution. The flow is:
dev.ctis bundled and executed.config()stores namespace + values in the result.values.jsonis loaded from disk.config.valuesis deep-merged on top ofvalues.json.main.ctis rendered with the merged values and namespace.- Dev targets from
dev()are resolved against the rendered resources.
This means config() should be called before dev() — although order doesn’t strictly matter at the JS level (both just register data), it reads better and matches the execution flow.
Full example
Section titled “Full example”const USERNAME = prompt("Your username?");const NAMESPACE = `myapp-dev-${USERNAME}`;const BASE_DOMAIN = "dev.example.com";
config({ namespace: NAMESPACE, values: { dev: true, replicas: 1, hosts: [ { name: "api", host: `api-${USERNAME}.${BASE_DOMAIN}` }, { name: "web", host: `web-${USERNAME}.${BASE_DOMAIN}` }, ], features: { hotReload: true, debugLogging: true, }, },});