New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@andreas-timm/config

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@andreas-timm/config

Bun-first TOML config loading with Zod validation

latest
Source
npmnpm
Version
0.2.0
Version published
Maintainers
1
Created
Source

@andreas-timm/config

Bun-first utilities for loading layered TOML config files and validating the merged result with Zod.

Features

  • Load global.toml, local.toml, or custom TOML file lists in order.
  • Resolve config files relative to a project root, from absolute paths, or from ~.
  • Deep-merge files with later files overriding earlier values.
  • Inject root_dir before schema validation.
  • Report Zod validation issues with the resolved source file paths.
  • Post-process known string values such as secret = "!pass show secret" as command-backed secrets.

Install

pnpm add @andreas-timm/config zod

Usage

// src/config.ts
import { join } from "node:path";
import { z } from "zod";
import { load } from "@andreas-timm/config";

export const ConfigSchema = z
    .object({
        root_dir: z.string(),
    })
    .strict();

export type Config = z.infer<typeof ConfigSchema>;

const rootDir = join(import.meta.dir, "..");
const configFiles = ["global.toml", "local.toml"];

let cached: Promise<Config> | undefined;

export function loadConfig(): Promise<Config> {
    cached ??= load(ConfigSchema, rootDir, configFiles);
    return cached;
}

export function resetConfig(): void {
    cached = undefined;
}

loadConfig() caches the promise in module scope, so files are read and parsed only on the first call and concurrent callers share the in-flight load. Call resetConfig() to force a reload in tests or after editing a TOML file.

Command-backed secrets

Use command-backed values when an application should keep the secret in a password manager or external secret store, but still describe how to fetch it in TOML:

secret = "!pass show secret"
literal = "!!starts-with-bang"

Post-process only the specific field that may contain a command:

import { load, resolveShellCommand } from "@andreas-timm/config";

const config = await load(ConfigSchema, rootDir, configFiles);
const secret = await resolveShellCommand(config.secret, { cwd: rootDir });

This keeps loading as plain TOML/Zod validation and makes command execution an application-level decision. The config schema should validate the placeholder as a string, and the application should validate or use the resolved secret at the point where it is needed.

You can also write the resolved value back into your application config object:

const config = await load(ConfigSchema, rootDir, configFiles);
config.secret = await resolveShellCommand(config.secret, { cwd: rootDir });

By default, command resolution uses ! as the prefix, !! as a literal escape, strips one final newline from command output, applies a 10 second timeout, and rejects stdout or stderr above 16 KiB. Treat any value passed to resolveShellCommand() as trusted executable input.

For the full setup pattern and usage guidance, see skills/bun-config/SKILL.md.

Keywords

bun

FAQs

Package last updated on 09 Jul 2026

Related posts