Modelence modules support a configSchema that lets you define typed, named
configuration values. These values can be managed through Modelence Cloud and
accessed at runtime via typed accessors.
This is the recommended way to store settings like API keys, feature toggles,
default values, and any other configuration your module needs — without
hardcoding them or relying solely on environment variables.
Version Requirements
Configuration accessors in this guide require:
Module.getConfig() - available since modelence@0.15.0
createClientModule(...).getConfig() - available since modelence@0.15.0
Defining a Config Schema
Add a configSchema to your module definition. Each key becomes a configuration
value namespaced under the module name:
src/server/payments/index.ts
import { Module } from 'modelence/server';
export default new Module('payments', {
configSchema: {
apiKey: {
type: 'secret',
default: '',
isPublic: false,
},
currency: {
type: 'string',
default: 'USD',
isPublic: true,
},
maxRetries: {
type: 'number',
default: 3,
isPublic: false,
},
},
});
Each config field requires three properties:
| Property | Type | Description |
|---|
type | ConfigType | The data type — see Config Types below |
default | (matches type) | Default value used when no value has been set |
isPublic | boolean | Whether this value is accessible on the client |
Config Types
The type field accepts one of five values:
| Type | Value Type | Description |
|---|
'string' | string | A short text value (single line) |
'text' | string | A longer text value (multi-line, rendered as a textarea in Cloud) |
'number' | number | A numeric value |
'boolean' | boolean | A true/false toggle |
'secret' | string | A sensitive value like an API key or token. Masked in the Cloud dashboard. Cannot be isPublic. |
Config values with type: 'secret' cannot have isPublic: true. Modelence
will throw an error at startup if this rule is violated.
Reading Config Values
Server-side
Call getConfig directly on the module instance. The return type is inferred
automatically from the schema — no casts needed:
Module.getConfig() is available since modelence@0.15.0.
src/server/payments/index.ts
import { Module } from 'modelence/server';
const paymentsModule = new Module('payments', {
configSchema: {
apiKey: { type: 'secret', default: '', isPublic: false },
maxRetries: { type: 'number', default: 3, isPublic: false },
},
mutations: {
async charge({ amount }) {
const apiKey = paymentsModule.getConfig('apiKey'); // string
const retries = paymentsModule.getConfig('maxRetries'); // number
// ...
},
},
});
export default paymentsModule;
Client-side
Use createClientModule to create a typed accessor for a module’s public config values.
Pass the module type via import type — no server code is bundled on the client.
createClientModule(...).getConfig() is available since modelence@0.15.0.
import type paymentsModule from '../server/payments';
import { createClientModule } from 'modelence/client';
export const payments = createClientModule<typeof paymentsModule>('payments');
src/components/Checkout.tsx
import { payments } from '../client/payments';
function Checkout() {
const currency = payments.getConfig('currency'); // string | undefined
return <div>Currency: {currency}</div>;
}
Only values marked isPublic: true are available on the client. Private and
secret values are not sent to the client and will not appear as valid keys.
For typed query and mutation wrappers, see:
Managing Values in Modelence Cloud
Once your module defines a configSchema, the configuration fields appear
automatically in the Modelence Cloud dashboard:
- Go to cloud.modelence.com
- Select your environment
- Open the Application tab
- Find your module’s configuration section
- Set values and save
Changes sync to your running application automatically (within ~10 seconds).
Config values set in Modelence Cloud take precedence over defaults defined in
your code. Environment variables take precedence over both.
Examples
Storing a third-party API key
import { Module } from 'modelence/server';
const aiModule = new Module('ai', {
configSchema: {
apiKey: {
type: 'secret',
default: '',
isPublic: false,
},
model: {
type: 'string',
default: 'gpt-4o',
isPublic: false,
},
},
mutations: {
async generateResponse({ prompt }: { prompt: string }) {
const apiKey = aiModule.getConfig('apiKey'); // string
const model = aiModule.getConfig('model'); // string
if (!apiKey) {
throw new Error('AI API key not configured');
}
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model,
messages: [{ role: 'user', content: prompt }],
}),
});
return response.json();
},
},
});
export default aiModule;
Feature toggle with a boolean config
src/server/notifications/index.ts
import { Module } from 'modelence/server';
const notificationsModule = new Module('notifications', {
configSchema: {
emailEnabled: {
type: 'boolean',
default: true,
isPublic: false,
},
footer: {
type: 'text',
default: 'You are receiving this because you signed up for our service.',
isPublic: false,
},
},
mutations: {
async sendNotification({ userId, message }: { userId: string; message: string }) {
const emailEnabled = notificationsModule.getConfig('emailEnabled'); // boolean
if (!emailEnabled) {
return { skipped: true };
}
const footer = notificationsModule.getConfig('footer'); // string
// Send email with message + footer...
},
},
});
export default notificationsModule;
Exposing config to the client
import { Module } from 'modelence/server';
export default new Module('app', {
configSchema: {
appName: {
type: 'string',
default: 'My App',
isPublic: true,
},
maintenanceMode: {
type: 'boolean',
default: false,
isPublic: true,
},
},
});
import type appModule from '../server/app';
import { createClientModule } from 'modelence/client';
export const app = createClientModule<typeof appModule>('app');
src/components/Header.tsx
import { app } from '../client/app';
function Header() {
const appName = app.getConfig('appName'); // string | undefined
const maintenance = app.getConfig('maintenanceMode'); // boolean | undefined
if (maintenance) {
return <div>We are currently undergoing maintenance. Please check back soon.</div>;
}
return <h1>{appName}</h1>;
}
Type Reference
See the full API reference for config types: