@jungvonmatt/config-loader
TypeScript icon, indicating that this package has built-in type declarations

0.5.2 • Public • Published

@jungvonmatt/config-loader

npm version build status coverage sonarcloud status

Load configuration from files, environment variables, and interactively prompt for missing values

A flexible configuration loader that extends c12 with additional features for environment variable mapping and interactive user prompts. Built on top of the unjs ecosystem for modern Node.js applications.

Features

  • 🔍 Multiple config sources: Load from package.json, rc files, config files, and more
  • 🌍 Environment variable support: Automatic dotenv loading and environment variable mapping
  • 💬 Interactive prompts: Ask users for missing required configuration values
  • 🔄 Config merging: Smart merging of configuration from multiple sources with overrides
  • 📁 Flexible file formats: Support for JSON, YAML, JS, TS, and more
  • 🛡️ TypeScript support: Full TypeScript support with type safety
  • 🔗 Config extension: Built-in support for extending configurations from other files or remote sources

Installation

# ✨ Auto-detect (supports npm, yarn, pnpm, deno and bun)
npx nypm install @jungvonmatt/config-loader

Usage

ESM (Node.js, Bun, Deno)

import { loadConfig } from "@jungvonmatt/config-loader";

Basic Example

import { loadConfig } from "@jungvonmatt/config-loader";

const { config } = await loadConfig({
  name: "myapp",
  defaultConfig: {
    port: 3000,
    host: "localhost",
  },
});

console.log(config.port); // 3000

With Required Fields and Prompts

import { loadConfig } from "@jungvonmatt/config-loader";

const { config } = await loadConfig({
  name: "myapp",
  required: ["apiKey", "databaseUrl"],
  prompts: [
    {
      name: "apiKey",
      type: "password",
      message: "Enter your API key:",
    },
    {
      name: "databaseUrl",
      type: "input",
      message: "Enter database URL:",
    },
  ],
});

Environment Variable Mapping

const { config } = await loadConfig({
  name: "myapp",
  envMap: {
    DATABASE_URL: "databaseUrl",
    API_KEY: "apiKey",
    PORT: "port",
  },
  defaultConfig: {
    port: 3000,
  },
});

Extending Configurations

// config.ts
export default {
  extends: "./base.config.ts",
  port: 8080,
  database: {
    url: "postgresql://localhost/mydb"
  }
};

// base.config.ts
export default {
  port: 3000,
  host: "localhost",
  database: {
    url: "postgresql://localhost/default"
  }
};

Configuration Files

The loader searches for configuration in the following locations (in order):

  • package.json (in a myapp property)
  • .myapprc.json
  • .myapprc.yaml / .myapprc.yml
  • .myapprc.js / .myapprc.ts / .myapprc.mjs / .myapprc.cjs
  • .config/.myapprc.*
  • myapp.config.js / myapp.config.ts / myapp.config.mjs / myapp.config.cjs

Where myapp is the name you provide in the options.

Example Config Files

.myapprc.json

{
  "port": 8080,
  "database": {
    "url": "postgresql://localhost/mydb"
  }
}

myapp.config.js

export default {
  port: process.env.PORT || 3000,
  database: {
    url: process.env.DATABASE_URL,
  },
};

Environment Variables

Automatic Environment Loading

Environment variables are automatically loaded from .env files:

  • .env.{NODE_ENV} (e.g., .env.production)
  • .env

Configuration Override Pattern

Any configuration can be overridden using environment variables with the pattern:

{NAME}_CONFIG_{PATH}

For example, with name: "myapp":

  • MYAPP_CONFIG_PORT=8080 sets config.port = 8080
  • MYAPP_CONFIG_DATABASE_URL=... sets config.databaseUrl = ...

API

loadConfig<T>(options: LoadConfigOptions<T>): Promise<ResolvedConfig<T>>

Options

Option Type Default Description
name string Required Name of the configuration (used for file searching)
defaultConfig Partial<T> {} Default configuration values
overrides Partial<T> {} Configuration overrides (highest priority)
required Array<keyof T> | ((config: T) => Array<keyof T> | Promise<Array<keyof T>>) [] Array of required configuration keys or a function that returns them. The function receives the current config as an argument.
envMap Record<string, keyof T> {} Map environment variable names to config keys
dotenv boolean true Whether to load .env files
envName string | false process.env.NODE_ENV Environment name for .env.{envName} file
cwd string process.cwd() Working directory for file searching
configFile string undefined Path to a specific config file to load
prompt Array<keyof T> | ((config: T) => Array<keyof T> | Promise<Array<keyof T>>) [] Array of configuration keys to prompt for, even if they exist in the config. Can be a function that returns the keys. Keys will be sorted based on the order in prompts if provided.
prompts PromptOptions[] | ((config: T) => PromptOptions[]) [] Interactive prompts for missing values. See enquirer for syntax details. The order of prompts determines the order of fields in the prompt sequence.

Returns

interface ResolvedConfig<T> {
  config: T; // The merged configuration object
  filepath: string | undefined; // Path to the config file that was loaded
  missing: string[]; // Array of missing required fields
  layers: Array<{
    type: "module" | "file" | "env" | "overrides" | "default" | "prompt";
    filepath: string | undefined;
    config: Partial<T> | undefined;
    cwd: string | undefined;
  }>; // Array of configuration layers in order of application
}

Prompt Options

Prompts use enquirer under the hood:

interface PromptOptions {
  name: string; // Configuration key name
  type: string; // Prompt type: 'input', 'password', 'select', etc.
  message: string; // Prompt message
  choices?: string[]; // For select/multiselect prompts
  initial?: any; // Default value
  // ... other enquirer options
}

License

Published under the MIT license. Made by Jung von Matt TECH 💚


🤖 auto updated with automd

Readme

Keywords

none

Package Sidebar

Install

npm i @jungvonmatt/config-loader

Weekly Downloads

240

Version

0.5.2

License

MIT

Unpacked Size

35.1 kB

Total Files

8

Last publish

Collaborators

  • jvm-tech
  • peter.klostermann
  • bezoerb
  • sebil
  • conuko