Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Config

per-environment config (app.Config)

app.Config = [ new Setting("Name") { Default = "…" } ]; … Config.Name

`app.Config` declares your app's per-environment settings — values that differ between development and production, like an invite base URL or a from-address. Each is `new Setting("Name")` with an optional `Default`; the real per-environment values come from checked-in `.env.development` / `.env.production` files. Read a setting anywhere with the `Config.Name` handle — in a function body and in a component — and it resolves to the value for the environment the app is running in.

stable1 example compiled by CIconfigenvironmentsettings

Summary#

app.Config declares the per-environment settings your application uses — non-secret values that differ between development and production, such as an invite base URL (http://localhost:8099 locally, https://app.example.com in production) or a from-address. It is the non-secret twin of declaring secrets (app.Secrets): you declare a setting's name in source and supply its per-environment values out of band, but — unlike a secret — a setting's value is public and is readable everywhere through the Config.Name handle, in a function body and in a component alike.

app.Config = [
  new Setting("InviteBaseUrl") { Default = "http://localhost:8099" },
  new Setting("FromAddress")   { Default = "noreply@localhost" },
];

// read it anywhere by handle — it resolves to the running environment's value:
string invite = Config.InviteBaseUrl + "/accept?token=" + token;

Signature#

app.Config = [                                       // one entry per named setting
  new Setting("Name") { Default = "…" },             // Default: the value used when no .env supplies one
  new Setting("Name"),                               // no Default: the value is REQUIRED from a .env file
];

Config.Name                                          // the setting's value for the running environment (a string)

app.Config is a list — an app may declare as many named settings as it needs.

Description#

A setting has a name (a string literal, the Config.Name read key) and an optional Default. The name and the Default are the only things that live in source. The actual per-environment values come from two checked-in files that sit next to your app.osy:

  • .env.development and .env.production — plain KEY=VALUE files (# comments and blank lines ignored). A key names a setting; its value is that setting's value for that environment.

These .env files are compile inputs, not runtime reads: when you compile, both value sets are baked into the app, so one compiled app carries its development and its production values and needs no per-environment recompile. For each setting, the value in each environment is the .env override if present, otherwise the setting's Default.

At runtime the app selects the set matching the environment it is running in — a local dev server resolves the development values, a production deployment resolves the production ones — so Config.InviteBaseUrl reads http://localhost:8099 locally and https://app.example.com in production, from the same build.

Reading a setting. Config.Name is a plain string value. Use it in a function body (building an email link, choosing a from-address) and in a component (a link, a label). Reading a setting that is not declared in app.Config is a compile error — a typo never silently reads as empty.

Required vs. defaulted. A setting with a Default always has a value. A setting without a Default is required: if either .env.development or .env.production does not supply it, the compile fails — you cannot ship a build that is missing a value in an environment it targets. An .env key that matches no declared setting is likewise a compile error, so a stale or mistyped key is caught rather than silently ignored.

Not for secrets. app.Config values are stored and served in the clear — they are meant to be public (a URL, an address), and a component can read them. An API key, token, or password belongs in declaring secrets (app.Secrets), which keeps its value out of source and never sends it to a browser. A config value that looks like a secret (a long random token, an sk-… key) is flagged with a warning nudging you toward app.Secrets.

Examples#

Declare two settings with development defaults, and read one in a function that builds an invite link:

app.Config = [
  new Setting("InviteBaseUrl") { Default = "http://localhost:8099" },
  new Setting("FromAddress")   { Default = "noreply@localhost" },
];

string InviteLink(string token) {
  return Config.InviteBaseUrl + "/accept?token=" + token;
}

To give production a different value, add a checked-in .env.production next to your app.osy:

InviteBaseUrl=https://app.example.com
FromAddress=hello@example.com

Now Config.InviteBaseUrl reads http://localhost:8099 when the app runs locally and https://app.example.com when it runs in production — from one compiled build, with no code change.

See also#

Related

declaring secrets (app.Secrets)

`app.Secrets` declares the named secrets your app uses — API keys, tokens, client secrets. Each is `new…

embedding provider (app.Embedding)

`app.Embedding` declares the embedding model the app uses to turn text into vectors for semantic search over…

default LLM model (app.DefaultModel)

Declares the app's default LLM — the provider, model, API-key secret, and optional endpoint — as a single app-level…