Meridian reads configuration from several sources. Each source is optional, and later sources only replace values that they define explicitly. This makes local development convenient without changing the project’s committed defaults.
Precedence
The final configuration is assembled in the following order, from lowest to highest priority.
| Source | Scope | Typical use |
|---|---|---|
| Built-in defaults | All projects | Safe baseline behavior |
meridian.json | Current project | Shared settings |
| Environment | Current machine | Credentials and deployment values |
| Runtime options | Current process | Temporary overrides |
Nested objects are merged by key. Arrays and scalar values replace the earlier value as a unit. An explicit
null is preserved and does not cause Meridian to fall back to a lower-priority source.
Loading a configuration file
Use loadConfig() when the configuration path is known at startup. The function returns a frozen
object so application code cannot mutate shared state accidentally.
import { loadConfig } from "@meridian/config";
const config = await loadConfig({
file: "./meridian.json",
environment: process.env,
});
// Values are validated before the object is returned.
server.listen(config.http.port);
Validation errors
Invalid values produce a ConfigurationError with the source, property path, and expected type.
Report the original error message to preserve that context for operators.
Default values
Keep defaults conservative and portable. Settings that depend on a particular host, region, or credential should be supplied by the environment instead of being committed to the project file.