Environment Variables
Declare SvelteKit environment variables with Effect Schema validators.SvelteKit 3 declares environment variables in src/env.ts and
validates every value at startup. DefineEnvVars is a thin wrapper over
SvelteKit's defineEnvVars that lets those declarations use Effect Schema
directly, so configuration validation speaks the same language as the rest of
an Effect application.
Declare variables
Export the declarations as variables from src/env.ts :
import { DefineEnvVars } from "svelte-effect-runtime";
import { Schema } from "effect";
export const variables = DefineEnvVars({
PORT: {
schema: Schema.NumberFromString,
description: "Port used by the server.",
},
DATABASE_URL: {
schema: Schema.RedactedFromValue(Schema.String),
},
PUBLIC_ORIGIN: {
public: true,
static: true,
schema: Schema.URLFromString,
},
});Every SvelteKit field passes through unchanged:
| Field | Default | Purpose |
|---|---|---|
public | false | Exposes the variable to browser code through $app/env/public. |
static | false | Inlines the build-time value so dead code can be eliminated. |
description | — | Editor hover documentation for the generated export. |
schema | — | An Effect Schema or Standard Schema decoding the raw string. |
Effect Schemas are converted with Schema.toStandardSchemaV1, existing
Standard Schema validators pass through untouched, and a declaration without a
schema keeps SvelteKit's non-empty-string default.
Consume decoded values
SvelteKit validates each value once at startup, so the generated exports are
plain constants with the schema's decoded types. Import them directly — no
wrapper, no yield*:
import { DATABASE_URL, PORT } from "$app/env/private";
import { Redacted } from "effect";
export const connect = () =>
open_pool({
port: PORT,
url: Redacted.value(DATABASE_URL),
});PORT arrives as a number, PUBLIC_ORIGIN as a URL, and DATABASE_URL as a Redacted<string> that prints as <redacted> if it
ever reaches a log line or serialized output. SvelteKit keeps ownership of
loading, visibility, and the server-only import guard: importing $app/env/private from browser code fails the build.