npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@ultra-lean-code/yamjam

v1.0.0

Published

Composable YAML configuration loader for @ultra-lean-code/yam - load and compose YAML files with inheritance

Readme

YamJam - Composable YAML Configuration Loader

Load YAML configuration files with inheritance and composition. Built on @ultra-lean-code/yam, YamJam lets you compose configurations from multiple files using an extends keyword, supporting file references, same-file property inheritance, and JSON path selection with $ delimiter.

Installation

npm install @ultra-lean-code/yamjam

Usage

Basic File Loading

import YamJam from '@ultra-lean-code/yamjam';

const config = await YamJam.load('./config.yaml');
console.log(config);

File Inheritance

base.yaml:

database:
  host: localhost
  port: 5432
  timeout: 30

features:
  auth: true
  cache: false

prod.yaml:

extends: base

database:
  host: prod-db.example.com
  port: 5433

features:
  cache: true

Result when loading prod.yaml (extension is optional, base resolves to base.yaml):

{
  database: {
    host: 'prod-db.example.com',
    port: 5433,
    timeout: 30
  },
  features: {
    auth: true,
    cache: true
  }
}

Nested Property Selection

Inherit from a specific nested property in another file using $ as the path delimiter:

common.yaml:

environments:
  development:
    debug: true
    port: 3000
  production:
    debug: false
    port: 8080

my-config.yaml:

extends: common.yaml$environments.production

app:
  name: MyApp

Result:

{
  debug: false,
  port: 8080,
  app: {
    name: 'MyApp'
  }
}

Property-Level Composition

Any property at any depth can inherit from external files:

db-configs.yaml:

postgres:
  host: localhost
  port: 5432
  ssl: false

redis:
  host: localhost
  port: 6379

app-config.yaml:

app:
  name: MyApp

database:
  extends: db-configs.yaml$postgres
  host: prod.example.com
  ssl: true

cache:
  extends: db-configs.yaml$redis
  host: cache.example.com

Result:

{
  app: {
    name: 'MyApp'
  },
  database: {
    host: 'prod.example.com',  // overridden
    port: 5432,                 // inherited
    ssl: true                   // overridden
  },
  cache: {
    host: 'cache.example.com',  // overridden
    port: 6379                  // inherited
  }
}

Internal References

Use $ without a filename to inherit from another property in the same file:

config.yaml:

defaults:
  timeout: 30
  retries: 3
  debug: false

development:
  extends: $defaults
  debug: true

production:
  extends: $defaults
  timeout: 60

Result:

{
  defaults: {
    timeout: 30,
    retries: 3,
    debug: false
  },
  development: {
    timeout: 30,     // inherited
    retries: 3,      // inherited
    debug: true      // overridden
  },
  production: {
    timeout: 60,     // overridden
    retries: 3,      // inherited
    debug: false     // inherited
  }
}

Path and Extension Rules

Optional file extensions - uses the current file's extension:

# In config.yaml:
extends: base           # Looks for base.yaml

# In config.yml:
extends: base           # Looks for base.yml

# Explicit extension always works:
extends: base.yaml      # Looks for base.yaml

Relative paths - resolved relative to the extending file:

# In /project/config/app.yaml:
extends: ../shared/base              # /project/shared/base.yaml
extends: ./local                     # /project/config/local.yaml

Absolute paths - start with /:

extends: /etc/myapp/base             # /etc/myapp/base.yaml

Combined with nested property selection:

extends: ../shared/db$postgres       # /project/shared/db.yaml, postgres property
extends: /etc/app/config$database    # /etc/app/config.yaml, database property

Features

  • File Loading: Load YAML files from the filesystem
  • File-Level Inheritance: Use extends: filepath at the root to inherit configuration
  • Property-Level Inheritance: Use extends: filepath on any property at any depth
  • Internal References: Use extends: $path.to.property to inherit from the same file
  • Nested Property Selection: Use extends: filepath$path.to.property to inherit specific nested properties
  • Optional File Extensions: File extensions are optional (uses current file's extension, e.g., .yaml, .yml)
  • Relative Paths: File paths resolved relative to the extending file (unless absolute)
  • Absolute Paths: Paths starting with / are treated as absolute
  • Configurable Keyword: Customize the extends property name (default: "extends")
  • Deep Merging: Objects are merged recursively, arrays and primitives are replaced
  • Circular Dependency Detection: Prevents infinite loops in extends chains

API

YamJam.load(filePath, options) (async)

Loads and parses a YAML file, resolving all inheritance and composition.

Parameters:

  • filePath (string): Path to the YAML file (absolute or relative to CWD)
  • options (object): Optional configuration
    • extendsKeyword (string): Property name to use for extends (default: "extends")

Returns: Promise - Parsed JavaScript object

Throws: Error if file not found, circular dependency detected, or invalid YAML

Example with custom keyword:

const config = await YamJam.load('./config.yaml', { extendsKeyword: 'inherits' });

Merge Behavior

  • Objects: Deep merged (nested properties combined)
  • Arrays: Replaced (child array completely replaces parent array)
  • Primitives: Replaced (child value overrides parent value)

Examples

See the tests/ directory for more examples.

License

MIT