Skip to content

Configuration

The ConfigBuilder constructor requires a validate function. This function receives two arguments: the final merged configuration and a Zod instance (v4). It must return the validated configuration.

import { ConfigBuilder } from "@layerfig/config";
// config will be type `z.infer<typeof schema>` (the actual object type)
export const config = new ConfigBuilder({
validate: (finalConfig, z) => {
const schema = z.object({
appURL: z.url(),
port: z.number(),
});
return schema.parse(finalConfig);
},
})
.addSource("base.json")
.build();

You can also use other validation libraries. Return the result of the schema validation from the validate function, and the config object will be typed accordingly:

import { ConfigBuilder } from "@layerfig/config";
import * as v from "valibot";
export const configSchema = v.object({
appURL: v.pipe(v.string(), v.url()),
});
export const config = new ConfigBuilder({
validate: (finalConfig) => v.parse(configSchema, finalConfig),
})
.addSource("base.json")
.build();

Default: './config'

By default, file-based sources added via addSource are loaded from a config folder in the project’s root. You can customize this path using the configFolder option:

const config = new ConfigBuilder({
validate: (finalConfig) => schema.parse(finalConfig),
configFolder: "./path/to/config-folder",
})
.addSource("base.json")
.build();

In this example, the library will look for <root>/path/to/config-folder/base.json.

Default: simple json parser

This option allows you to define a custom parser for non-JSON file types, such as .yaml, .jsonc, or .toml.

import yarmlParser from "@layerfig/yaml";
const config = new ConfigBuilder({
validate: (finalConfig) => schema.parse(finalConfig),
parser: yarmlParser,
})
.addSource("base.yaml")
.build();

In this case, the library will look for <root>/config/base.yaml and load it.

Default: "$"

A string that identifies placeholders to be replaced with environment variables.

By default, Layerfig looks for placeholders prefixed with $. You can customize this prefix to avoid conflicts or to match a team’s convention.

For example, to use a double underscore (__) as the prefix:

const config = new ConfigBuilder({
validate: (finalConfig) => schema.parse(finalConfig),
slotPrefix: "__",
})
.addSource("base.json")
.build();

Layerfig will now look for placeholders like __PORT in your configuration files.

config/base.json
{
"appURL": "http://localhost:__PORT",
"port": "__PORT"
}

Assuming the PORT environment variable is set, the resolved configuration will be:

config.appURL; // http://localhost:3000
config.port; // 3000