Latest Socket ResearchMalicious Chrome Extension Performs Hidden Affiliate Hijacking.Details
Socket
Book a DemoInstallSign in
Socket

dozen

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dozen

Load config from a dozen sources, normalize and validate with Zod, Valibot or ArkType

Source
npmnpm
Version
1.2.0
Version published
Weekly downloads
71
44.9%
Maintainers
1
Weekly downloads
 
Created
Source

Dozen

Load config from a dozen sources, normalize and validate with Zod, Valibot or ArkType

npm package   Buy me a beer


Dozen is a TypeScript library that loads configuration for your app from various sources, such as config files, .env files, environment variables, CLI arguments, plain objects and others. It then normalizes the values (e.g. coerces to numbers and booleans) and keys (e.g. converts to camelCase), merges them into a single object and validates it against a schema if required. It can watch the sources for changes and automatically rebuild the config and notify the user.

The library is designed to be extensible by using a plugin system similar to that of Rollup/Vite. Every step of the pipeline can be customized by adding or disabling a plugin or source. For example, you can add a plugin that reads from a database or parses TOML syntax.

Currently, Dozen ships .ts files and can be used only in an environment that runs TypeScript, such as Node.js v23.6+ or Bun.js.

Quickstart

npm install dozen
// The simplest case.

import dozen from 'dozen'

// - Reads from:
//     1. .env, .env.local, .env.${NODE_ENV}, .env.${NODE_ENV}.local files
//     2. Environment variables (process.env)
// - Coerces strings to numbers and booleans when applicable
// - Merges into a single object
// - Converts keys to camelCase

const config = await dozen().build()
// An advanced case.

import dozen from 'dozen'
import { z } from 'zod'

const dz = dozen({
  // Giving a name makes dozen look for config files with that name
  name: 'myapp',
  // The merged config object will be validated against this schema.
  // This can be any standard schema, e.g. from Zod, Valibot, ArkType, etc.
  schema: z.object({
    host: z.string(),
    port: z.number(),
    enabled: z.boolean(),
  })
})

// Sources can be added later
dz.add(dozen.file('config.json'))

// CLI arguments aren't read by default, but supported via dozen.argv()
dz.add(dozen.argv())

// It accepts plain objects as well
dz.add({ port: 8008 })

// .get() returns the cached config without building it
console.log(dz.get()) // => {} because dz.build() has not been called yet

// - Reads from:
//     1. The "myapp" field in package.json
//     2. myapp.config.json, myapprc.yaml, .myapprc and other config files with the given name
//     3. .env, .env.local, .env.${NODE_ENV}, .env.${NODE_ENV}.local files
//     4. Environment variables (process.env)
//     5. The config.json file in the current working directory
//     5. CLI arguments (process.argv)
//     6. The config object passed to dz.add()
// - For env values, keeps only those with the MYAPP_ prefix, then removes the prefix
// - Coerces strings to numbers and booleans for env and argv values when applicable
// - Converts keys to camelCase
// - Validates with the schema

const config = await dzn.build()

console.log(dz.get()) // => { host: 'localhost', port: 8008, enabled: true }

API

dozen(options?: Options): Instance

Creates an instance of Dozen with the default preset merged with the given options.

Instance

The default preset includes plugins and sources tuned for Node.js-compatible runtimes.

It loads from the following sources:

  • The "myapp" field in package.json (if the "name" option is "myapp");
  • myapp.config.json, myapprc.yaml, .myapprc and other config files with the given name (if the "name" option is "myapp");
  • .env, .env.local, .env.${NODE_ENV}, .env.${NODE_ENV}.local files;
  • Environment variables (process.env);

After that, for env values, it keeps only those with the MYAPP_ prefix, then removes the prefix from them. Then, it coerces strings to numbers and booleans for env and argv values when applicable, then merges and validates the config object with the given schema (if provided).

async .build(): Promise\<object\>

Builds the config object (if needed) and returns it.

If there have been changes in the sources since the last build, the corresponding sources (and only them) will be loaded and mapped, and the config object will be rebuilt, otherwise the cached config object will be returned.

.get(): object

Returns the currently cached config object. If the config object has not been built yet, returns an empty object.

.add(items: Source | object | undefined | null | false | (Source | object | undefined | null | false)[]): Instance

Adds one or more sources or values to the pipeline. Falsy values are ignored.

If watching is enabled, this will trigger a rebuild, otherwise build() has to be called manually.

.fork(options?: Options): Instance

Creates a new instance of Dozen that inherits the current instance's options, sources and plugins, and adds its own. When building, the fork will first call build() on the parent instance, then build on top of it.

.watch(cb?: (config: object) => void): Watcher

Starts watching for changes in sources and rebuilds the config object so that get() always returns an up-to-date config. If a callback is provided, it will be called with the updated config.

Returns a watcher object that can be used to control the watching and catch errors.

.unwatch(cb?: (config: object) => void): void

Stops watching for changes. If a callback is provided, only the corresponding watcher will be removed, otherwise removes all watchers.

Options

These options are used by Dozen itself:

OptionTypeDescription
sourcesundefined | (Source | Entry | Entry[] | undefined | null | false)[]An array of sources to load from.
pluginsundefined | (PluginFactory | Plugin | undefined | null | false)[]An array of plugins to use.
disableSourcesundefined | (Source | Entry | Entry[] | undefined | null | false)[]An array of sources to disable. Use to disable default sources.
disablePluginsundefined | (PluginFactory | Plugin | undefined | null | false)[]An array of plugins to disable. Use to disable default plugins.

These are options used by the default plugins (if a plugin is disabled, its options are ignored):

OptionTypeDescription
nameundefined | stringThe name of the app. Used to search config files and package.json fields, and as a prefix for env vars.
schemaundefined | StandardSchemaV1The schema to validate against. By default, any Standard Schema library is supported (e.g. Zod, Valibot, ArkType).
prefixundefined | { filter?: boolean | string; remove?: boolean | string; byFormat?: Record<string, { filter?: boolean | string; remove?: boolean | string }> }filter: when true, only keys starting with name will be kept.; when a string, only keys starting with that string will be kept; when false, all keys will be kept.
remove: when true, the prefix matching name will be removed from keys; when a string, the prefix matching that string will be removed; when false, no prefix will be removed.
byFormat: an object that specifies prefix options for each format separately (e.g. env: { filter: true, remove: false }).
keyCaseundefined | 'camel' | 'pascal' | 'kebab' | 'snake' | 'constant' | 'upper' | 'upperFirst' | 'lower' | 'lowerFirst' | 'swap' | 'capital' | 'dot' | 'none' | 'path' | 'title'The string case to convert keys to. Defaults to camel.
coerceStringsundefined | { boolean?: boolean; number?: boolean; byFormat?: Record<string, boolean | { boolean?: boolean; number?: boolean }> }boolean: when true, converts strings "true", "1", "false" and "0" to their boolean counterparts.
number: when true, converts numerical strings to numbers ("12" → 12).
byFormat: an object that specifies coerceStrings options for each format separately (e.g. env: { boolean: true, number: false }).
extendsPropertyundefined | stringThe property to use as a file path for extending the config object. For example, if the value is "extends", and one of the sources has this property set to "base.json", Dozen will attempt to load "base.json".

Keywords

config

FAQs

Package last updated on 07 Apr 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts