Reference

API reference#

createConfig(options)#

This is the main function of the library. It takes a few options and returns the final configuration object.

Example
const config = createConfig({
  envPrefix: 'APP_',
  loaders: [
    loaders.environment(),
    loaders.file('.env'),
  ],
  schema: z.object({
    server: z.object({
      port: z.coerce.number(),
      host: z.string().default('localhost'),
    }),
  }),
});

loadersKeyLoader[]required

The list of loaders to use. The loaders are the source of the final configuration object. If you have no loaders, the configuration will be an empty object.

You can import loaders from @neato/config to use the built-in loaders. You can also create your own loaders by implementing the KeyLoader type, read more about plugins.

Find all the built-in loaders here.

schemaSchemaTransformer<T> | ZodSchema | JoiSchema | undefined

  • Default: undefined

The schema to use for validation and transformation of the configuration object. The schema is used to validate the final configuration object and transform it to the expected type.

You can use Zod, Joi or custom schemas. The schema is optional, but it is recommended to use it to ensure the configuration is valid and has the expected types.

Naming conventions are automatically detected from the schema, read more about naming conventions here.

envPrefixstring?

  • Default: ""

This is the prefix to use for environment variables. If it is set, the prefix is used to filter the environment variables that are loaded by the environment variable based loaders.

If no prefix is set, all environment variables are loaded. Loading all environment variables is not recommended as it will load variables that are unrelated to your app.

The prefix is stripped from the environment variable names before they are processed. This means that if you have an environment variable APP_SERVER__PORT, it will be parsed as SERVER__PORT.

freezeboolean?

  • Default: true

This option is used to freeze or unfreeze the configuration object. By default, the configuration object is deep frozen to prevent accidental mutations. If you set this option to false, the configuration object will not be frozen and can be mutated.

assertstring | ((error: NeatConfigError) => void) | undefined

  • Default: "pretty"

This option is used to handle errors. By default it is set to pretty, which means the library will exit with a colored and formatted error message in the console. You can change this behaviour by setting the assert option to plain (plain text) or throw (throws an error).

Alternatively, you can set this option to a function that will be called with the error object. Use this to implement custom error handling logic, such as logging the error to a file or sending it to an external service.

Read more about error handling here.

namingConventionNamingConventionFunc?

  • Default: naming.camelCase

This option is used to set the naming convention for the configuration object. By default, the library will detect the naming convention from the schema. If you don't have a schema, you can use this option to set the default naming convention.

There are a few built-in naming conventions, you can use those or create your own by passing a function.

presetKeystring?

  • Default: "configPresets"

When using presets, this is they key used to identify which presets to load. It defaults to configPresets, meaning you can use CONFIG_PRESETS=abc,foo to load the abc and foo presets.

You don't need to set this option if you are not using presets.

presetsRecord<string, Preset>?

  • Default: undefined

An object containing the presets to use. Presets are a way to make standardize your configuration and make it easier to use in different environments. You can use presets to load different configurations for different environments, such as local development, dev containers, or similar.

zodCoercedBoolean()#

This utility function is used to create a Zod primitive that coerces a string value to a boolean. It is used to handle boolean values in the configuration object.

Why use this?
// Without util
z.coerce.boolean().parse("true"); // => true
z.coerce.boolean().parse("false"); // => true
z.coerce.boolean().parse("yes"); // => true
z.coerce.boolean().parse("no"); // => true
z.coerce.boolean().parse(""); // => false
 
// With util
zodCoercedBoolean().parse("true"); // => true
zodCoercedBoolean().parse("false"); // => false
zodCoercedBoolean().parse("yes"); // => true
zodCoercedBoolean().parse("no"); // => false
zodCoercedBoolean().parse(""); // => false
Example
const config = createConfig({
  loaders: [
    loaders.environment(),
  ],
  schema: z.object({
    serverPort: z.coerce.number(),
    useStrictHeaders: zodCoercedBoolean().default(false),
  }),
});

loaders - Built-in loaders#

Loaders are the source of the final configuration object. To load anything into your configuration you must specify at least one loader.

loaders.environment()#

This loader loads environment variables from process.env into the configuration object. It respects the envPrefix option if specified.

Example
const config = createConfig({
  envPrefix: 'APP_',
  loaders: [
    loaders.environment(),
  ],
});

loaders.file(path, options?)#

This loader loads configuration from a file. It supports the following file types:

  • JSON
  • ENV - Respects the envPrefix option if specified.

It will automatically detect the file type based on the file extension. If file type can't be determined then an error is thrown. For those cases the filetype can be specified manually in the options.

Example
const config = createConfig({
  envPrefix: 'APP_',
  loaders: [
    loaders.file('.env'),
    loaders.file('config.json'),
    loaders.file('config.txt', { type: 'JSON' }),
  ],
});

loaders.cli(options?)#

This loader loads configuration from the command line arguments. You can optionally set a prefix to only load arguments that start with the supplied prefix.

It supports both --key value and --key=value formats.

If set, prefix is stripped from the key before it is processed. So with a prefix of app-, the CLI argument --app-server__port=8080 will be parsed as server.port=8080.

Example
const config = createConfig({
  loaders: [
    loaders.cli({ prefix: 'app-' }),
  ],
});

loaders.dir(path, options?)#

This loader loads in data from a directory structure, the filename is used as the key and the contents of the file is the value

Optionally a prefix can be set to strip from the key before it is processed.

Example
const config = createConfig({
  loaders: [
    loaders.dir("/var/run/secrets", { prefix: 'APP_' }),
  ],
});

naming - Built-in naming conventions#

The library comes with a few built-in naming conventions.

naming.camelCase#

This naming convention uses camel case for the keys. It is the default naming convention.

Camel case looks like this: camelCase, myKey, anotherKey

naming.pascalCase#

This naming convention uses pascal case for the keys.

Pascal case looks like this: PascalCase, MyKey, AnotherKey

naming.screamingSnakeCase#

This naming convention uses screaming snake case for the keys.

Screaming snake case looks like this: SCREAMING_SNAKE_CASE, MY_KEY, ANOTHER_KEY

naming.snakeCase#

This naming convention uses snake case for the keys.

Snake case looks like this: snake_case, my_key, another_key