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 🙏

© 2026 – Pkg Stats / Ryan Hefner

manifest-core

v1.0.1

Published

Smart JSON composition with inheritance, immutable rules, and intelligent merging. Build complex configurations from simple manifests.

Downloads

12

Readme

manifest-core

Smart JSON composition with inheritance, immutable rules, and intelligent merging

Transform complex configuration hierarchies into a single, validated JSON structure. Built for production systems that need composability, auditability, and cryptographic integrity.

npm version License: MIT TypeScript


What is manifest-core?

A TypeScript library that solves one problem extremely well: compose JSON manifests with inheritance.

// base.json
{ "patch": { "database": "postgres", "cache": "redis" } }

// app.json
{ "extends": "./base.json", "patch": { "port": 3000 } }

// Result
{ "database": "postgres", "cache": "redis", "port": 3000 }

That's it. No schema validation, no data fetching, no YAML parsing. Just pure composition.


Why manifest-core?

✅ What it does

  • Inheritance (extends) - Hierarchical configuration composition
  • Immutable rules (tail) - Enforce base policies that can't be overridden
  • Intelligent merging - Myers algorithm for smart array operations
  • Integrity verification - SHA256 checksum for every resolution
  • Pluggable loaders - Load from files, databases, S3, or memory

❌ What it doesn't do

  • Schema validation - Use your own validation layer
  • Data fetching - Implement in your loaders
  • File parsing - Parse JSON/YAML before passing in
  • External references - Handle in your application layer

Core principle: Do one thing, do it well, make it pluggable.


Installation

npm install manifest-core
# or
pnpm add manifest-core

Single dependency: json-myers (intelligent diff/patch)


Quick Start

Basic Inheritance

base.json

{
  "name": "base",
  "patch": {
    "database": "postgresql",
    "cache": "redis",
    "features": ["auth", "logging"]
  }
}

production.json

{
  "name": "production",
  "extends": "./base.json",
  "patch": {
    "features": ["auth", "logging", "analytics"],
    "environment": "production"
  }
}

Usage:

import { ManifestCore } from 'manifest-core';

const core = new ManifestCore();
const config = await core.resolveFile('./production.json');

console.log(config);
// {
//   database: "postgresql",
//   cache: "redis",
//   features: ["auth", "logging", "analytics"],
//   environment: "production"
// }

Core Concepts

1. Inheritance with extends

Build configurations hierarchically. Present overwrites past.

{
  "extends": "./base.json",
  "patch": { "newFeature": true }
}

Chain inheritance by making each file extend the previous one:

// app.json
{ "extends": "./with-security.json" }

// with-security.json
{ "extends": "./base.json", "patch": { ... } }

2. Immutable Rules with tail

Enforce base policies that cannot be overridden. Past overwrites present.

security-policy.json (immutable foundation)

{
  "name": "security-policy",
  "patch": {
    "security": {
      "encryption": "AES-256",
      "mfa": "required"
    }
  }
}

app.json

{
  "name": "app",
  "tail": "./security-policy.json",
  "patch": {
    "security": {
      "encryption": "AES-128"  // ❌ Will be OVERRIDDEN!
    },
    "customFeature": true       // ✅ Preserved
  }
}

Result:

{
  security: {
    encryption: "AES-256",    // ← Enforced by tail!
    mfa: "required"           // ← From tail
  },
  customFeature: true         // ← Your data
}

Use cases:

  • Compliance policies (SOX, HIPAA, GDPR)
  • Security baselines
  • Organizational standards
  • Immutable contracts

3. Intelligent Merging (Myers Algorithm)

Arrays aren't replaced - they're intelligently merged using json-myers.

Why json-myers? Standard object merging always replaces arrays completely. json-myers enables array versioning - tracking additions, removals, updates, and moves - something traditional merge strategies cannot do.

Base:

{
  "patch": {
    "permissions": [
      { "role": "admin", "access": "full" },
      { "role": "user", "access": "read" }
    ]
  }
}

Child (using $__arrayOps):

{
  "extends": "./base.json",
  "patch": {
    "permissions": {
      "$__arrayOps": [
        {
          "type": "update",
          "index": 1,
          "item": { "role": "user", "access": "write" }
        },
        {
          "type": "add",
          "index": 2,
          "item": { "role": "guest", "access": "readonly" }
        }
      ]
    }
  }
}

Result:

{
  "permissions": [
    { "role": "admin", "access": "full" },
    { "role": "user", "access": "write" },      // ✅ Updated
    { "role": "guest", "access": "readonly" }   // ✅ Added
  ]
}

⚠️ Important: Putting arrays directly in patch will replace them, not merge! Use $__arrayOps for intelligent merging, or use merge field if you want full replacement.

Learn more: json-myers documentation


4. Raw Mode (Bypass Processing)

Load JSON without processing extends or tail in that file.

{
  "extends": {
    "path": "./legacy-config.json",
    "raw": true
  }
}

Use case: Extending configs that use reserved field names as data.


API Reference

ManifestCore (High-Level API)

import { ManifestCore } from 'manifest-core';

const core = new ManifestCore({
  // Custom manifest loader
  manifestProvider?: {
    load(source: string): Promise<Manifest>
  },

  // Cache settings
  cache?: {
    enabled?: boolean;
    directory?: string;
  },

  // Debug mode
  debug?: boolean
});

// Resolve from file/URL
await core.resolveFile(path: string): Promise<ResolvedManifest>

// Resolve from object
await core.resolve(manifest: Manifest): Promise<ResolvedManifest>

ManifestResolver (Low-Level API)

import { ManifestResolver } from 'manifest-core';

const resolver = new ManifestResolver({
  // Custom loaders (file, http, s3, etc.)
  loaders?: {
    file: Loader,
    http: Loader,
    s3: Loader,
    // ... any protocol
  },

  cache?: { enabled?: boolean; directory?: string },
  debug?: boolean,
  logger?: (message: string) => void
});

await resolver.resolve(source: string): Promise<ResolvedManifest>

Types

import type {
  Manifest,
  ResolvedManifest,
  ManifestProvider,
  Loader,
  LoaderRegistry,
  MergeStrategy,
  ExtendsSpec,
  TailSpec
} from 'manifest-core';

Custom Loaders (Dependency Injection)

Load manifests from any source - just implement the Loader interface.

Loader Interface

interface Loader {
  load(source: string): Promise<string>;
}

Database Loader (PostgreSQL)

import { ManifestCore } from 'manifest-core';
import { Pool } from 'pg';

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

const core = new ManifestCore({
  manifestProvider: {
    async load(source: string) {
      const result = await pool.query(
        'SELECT data FROM manifests WHERE id = $1',
        [source]
      );
      return result.rows[0].data;
    }
  }
});

// Load from database by ID
const config = await core.resolveFile('tenant-123');

S3 Loader

import { ManifestResolver } from 'manifest-core';
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';

const s3 = new S3Client({ region: 'us-east-1' });

const resolver = new ManifestResolver({
  loaders: {
    s3: {
      async load(source: string) {
        // s3://bucket/path/to/manifest.json
        const [, bucket, ...keyParts] = source.replace('s3://', '').split('/');
        const key = keyParts.join('/');

        const command = new GetObjectCommand({ Bucket: bucket, Key: key });
        const result = await s3.send(command);
        return await result.Body!.transformToString();
      }
    }
  }
});

const config = await resolver.resolve('s3://my-bucket/config.json');

Redis Cache + HTTP

import Redis from 'ioredis';

const redis = new Redis();

const core = new ManifestCore({
  manifestProvider: {
    async load(source: string) {
      // Try cache first
      const cached = await redis.get(`manifest:${source}`);
      if (cached) return JSON.parse(cached);

      // Fetch from HTTP
      const response = await fetch(source);
      const manifest = await response.json();

      // Cache for 1 hour
      await redis.setex(`manifest:${source}`, 3600, JSON.stringify(manifest));

      return manifest;
    }
  }
});

In-Memory Loader (Testing)

const manifests = new Map([
  ['base', { patch: { debug: true } }],
  ['app', { extends: 'base', patch: { port: 3000 } }]
]);

const core = new ManifestCore({
  manifestProvider: {
    async load(source: string) {
      const manifest = manifests.get(source);
      if (!manifest) throw new Error(`Manifest not found: ${source}`);
      return manifest;
    }
  }
});

// Instant, zero I/O
const config = await core.resolveFile('app');

Architecture

Resolution Pipeline (5 Steps)

┌─────────────┐
│   Input     │  manifest.json
└──────┬──────┘
       ↓
┌─────────────┐
│ 1. Load     │  Load manifest via loaders
└──────┬──────┘
       ↓
┌─────────────┐
│ 2. Tail     │  Resolve tail chain → Store immutable rules
└──────┬──────┘
       ↓
┌─────────────┐
│ 3. Extends  │  Resolve extends chain
└──────┬──────┘
       ↓
┌─────────────┐
│ 4. Merge    │  Myers intelligent merge
└──────┬──────┘
       ↓
┌─────────────┐
│ 5. Apply    │  Enforce tail rules (FINAL)
└──────┬──────┘
       ↓
┌─────────────┐
│   Output    │  Resolved manifest + SHA256 checksum
└─────────────┘

Design Principles

  1. Single Responsibility - Only composition and merging
  2. Dependency Injection - All I/O is pluggable
  3. Immutability - Original manifests never modified
  4. Transparency - Full resolution metadata
  5. Zero Dependencies* - Only json-myers for merging

Real-World Examples

Multi-Environment Config

config/
├── base.json              # Common settings
├── development.json       # extends base
├── staging.json           # extends base
└── production.json        # extends base + tail security-policy.json
const env = process.env.NODE_ENV || 'development';
const config = await core.resolveFile(`./config/${env}.json`);

Multi-Tenant SaaS

// Each tenant extends their tier
const config = await core.resolveFile(`tenants/${tenantId}/config.json`);

// tenant-123/config.json
{
  "extends": "../../tiers/premium.json",
  "patch": {
    "customDomain": "acme.app",
    "features": { "sso": true, "analytics": true }
  }
}

Infrastructure as Code

{
  "name": "infrastructure-prod",
  "extends": "./infra-base.json",
  "tail": "./security-policy.json",
  "patch": {
    "database": {
      "type": "postgresql",
      "instances": 3,
      "storage": "1TB"
    },
    "cache": {
      "type": "redis",
      "instances": 2
    }
  }
}

Feature Flags

{
  "extends": "./base-features.json",
  "patch": {
    "features": [
      { "name": "darkMode", "enabled": true, "rollout": 100 },
      { "name": "newUI", "enabled": true, "rollout": 50 },
      { "name": "aiChat", "enabled": false, "rollout": 0 }
    ]
  }
}

Integrity Verification

Every resolution includes a SHA256 checksum.

const config = await core.resolveFile('./production.json');

console.log(config.resolution.checksum);
// "sha256-abc123def456..."

// Store checksum for immutable deployments
const expectedChecksum = config.resolution.checksum;

// Later, verify integrity
const newConfig = await core.resolveFile('./production.json');
if (newConfig.resolution.checksum !== expectedChecksum) {
  throw new Error('Configuration has been modified!');
}

Use cases:

  • Immutable deployments
  • Audit trails
  • Configuration drift detection
  • Compliance verification

Manifest Format

Minimal Manifest

{
  "patch": {
    "database": "postgres"
  }
}

Full Manifest

{
  // Metadata (optional)
  "name": "my-app",
  "version": "1.0.0",
  "description": "Application configuration",

  // Inheritance (optional)
  "extends": "./base.json",
  // or with options
  "extends": {
    "path": "./base.json",
    "hash": "sha256-abc123...",  // Verify integrity
    "raw": true                   // Bypass processing
  },

  // Immutable rules (optional)
  "tail": "./security-policy.json",
  // or
  "tail": {
    "path": "./security-policy.json",
    "hash": "sha256-def456..."
  },

  // Merge strategy (optional)
  "mergeStrategy": {
    "features": "myers",      // Smart array merge
    "config": "deep",         // Deep merge (arrays replace)
    "routes": "replace"       // Complete replacement
  },

  // Payload (ONE of these)
  "patch": { ... },  // Myers merge (intelligent)
  "merge": { ... },  // Deep merge (arrays replace)

  // Or raw payload (when no extends/tail)
  "database": "postgres",
  "cache": "redis"
}

Testing

Built for testability with in-memory providers.

import { describe, it, expect } from 'vitest';
import { ManifestCore } from 'manifest-core';

describe('Configuration Resolution', () => {
  it('should merge tenant config with tier defaults', async () => {
    const manifests = new Map([
      ['tier-basic', {
        patch: { maxUsers: 10, features: ['core'] }
      }],
      ['tenant-acme', {
        extends: 'tier-basic',
        patch: { customDomain: 'acme.app' }
      }]
    ]);

    const core = new ManifestCore({
      manifestProvider: {
        async load(source) {
          return manifests.get(source.replace('.json', ''))!;
        }
      }
    });

    const config = await core.resolveFile('tenant-acme');

    expect(config.maxUsers).toBe(10);
    expect(config.features).toEqual(['core']);
    expect(config.customDomain).toBe('acme.app');
  });
});

Zero I/O. Instant. Deterministic.


Advanced: Custom Post-Processing

Extend ManifestCore for custom validation or transformation.

import { ManifestCore } from 'manifest-core';

class ValidatedManifestCore extends ManifestCore {
  async resolve(manifest: Manifest) {
    // 1. Core composition and merging
    const resolved = await super.resolve(manifest);

    // 2. Your custom validation
    this.validate(resolved);

    // 3. Your custom transformation
    const transformed = this.transform(resolved);

    return transformed;
  }

  private validate(manifest: any): void {
    // Add your validation logic
    if (!manifest.database) {
      throw new Error('Database configuration required');
    }
  }

  private transform(manifest: any): any {
    // Add your transformation logic
    return manifest;
  }
}

Contributing

Contributions welcome!

# Install dependencies
pnpm install

# Run tests
pnpm test

# Run tests with coverage
pnpm test:coverage

# Type check
pnpm typecheck

# Build
pnpm build

Guidelines:

  1. Add tests for new features
  2. Ensure all tests pass
  3. Maintain TypeScript strict mode
  4. Update documentation

Documentation


License

MIT © 2025 Anderson D. Rosa


Links


manifest-core - Smart JSON composition for production systems

Simple. Powerful. Pluggable.