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

@cryptoteep/jsoncraft

v0.1.0

Published

A zero-dependency, TypeScript-first JSON toolkit for querying, transforming, and converting JSON data.

Readme

jsoncraft


jsoncraft is a single, focused library and CLI for everything you do with JSON: query it (JSONPath), transform it (pick, omit, flatten, groupBy, ...), convert between formats (JSON ↔ YAML/CSV/JSONL/Properties/TOML), format it with colors, diff and merge it, and validate it against a lightweight schema — all with zero runtime dependencies.

It runs anywhere JavaScript does: Node.js, Bun, Deno, and modern browsers.

✨ Features

  • 🔍 Query — A practical JSONPath engine with filters, slices, wildcards, and recursive descent.
  • 🔁 Transformpick, omit, map, filter, renameKeys, flatten, unflatten, groupBy, sortBy, chunk, unique.
  • 🔄 Convert — Bidirectional conversion between JSON, YAML, CSV, JSONL, Java Properties, and TOML.
  • 🎨 Format — Pretty-print with ANSI colors, key sorting, depth limiting, compact mode.
  • 📊 Diff & Patch — Structural deep diff with JSONPath locations and patch application.
  • 🧬 Merge — Configurable deep merge with array strategies (replace / concat / merge-by-index), plus intersect and union.
  • ✅ Validate — A tiny Zod-inspired schema validator with coercion, enums, ranges, and defaults.
  • 🖥️ CLI — A friendly jc command for the terminal, reading from files or stdin.
  • 📦 Zero dependencies — Only your runtime. Nothing else.
  • 🔒 Type-safe — Strict TypeScript with full type inference.

📦 Installation

npm install jsoncraft
# or
bun add jsoncraft
# or
pnpm add jsoncraft

For CLI-only usage, install globally:

npm install -g jsoncraft

🚀 Quick start

As a library

import {
  query, pick, omit, flatten, groupBy, sortBy,
  convert, format, diff, merge, validate,
} from 'jsoncraft';

// ── Query with JSONPath ─────────────────────────────────
const data = {
  store: {
    book: [
      { category: 'reference', author: 'Nigel Rees', price: 8.95 },
      { category: 'fiction', author: 'Herman Melville', price: 8.99 },
      { category: 'fiction', author: 'J.R.R. Tolkien', price: 22.99 },
    ],
  },
};

query(data, '$.store.book[*].author');
// → ['Nigel Rees', 'Herman Melville', 'J.R.R. Tolkien']

query(data, '$..book[?(@.price < 10)].author');
// → ['Nigel Rees', 'Herman Melville']

// ── Transform ──────────────────────────────────────────
const users = [{ id: 1, name: 'Alice', password: 'x' }, { id: 2, name: 'Bob', password: 'y' }];
users.map((u) => pick(u, ['id', 'name']));
// → [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]

flatten({ a: { b: { c: 1 } } });
// → { 'a.b.c': 1 }

groupBy([{ role: 'admin' }, { role: 'user' }, { role: 'admin' }], 'role');
// → { admin: [...], user: [...] }

// ── Convert formats ────────────────────────────────────
convert('[{"id":1},{"id":2}]', 'json', 'yaml');
// →
// - id: 1
// - id: 2

convert('a: 1\nb: 2', 'yaml', 'json');
// → '{"a":1,"b":2}'

// ── Diff & merge ───────────────────────────────────────
diff({ a: 1, b: 2 }, { a: 1, c: 3 });
// → [
//     { path: '$.b', type: 'remove', oldValue: 2 },
//     { path: '$.c', type: 'add', value: 3 },
//   ]

merge({ a: 1, b: { x: 1 } }, { b: { y: 2 }, c: 3 });
// → { a: 1, b: { x: 1, y: 2 }, c: 3 }

// ── Validate ───────────────────────────────────────────
const schema = {
  type: 'object',
  properties: {
    name: { type: 'string', required: true },
    age: { type: 'number', min: 0, max: 150 },
    role: { type: 'string', enum: ['admin', 'user'] },
  },
};
validate({ name: 'Alice', age: 30, role: 'admin' }, schema);
// → { valid: true, errors: [], value: {...} }

As a CLI

# Query JSON with JSONPath
jc query '$.store.book[*].author' books.json
jc query '$..book[?(@.price < 10)].title' books.json

# Pipe through stdin
cat data.json | jc query '$.users[*].name'

# Pick / omit keys
jc pick id,name users.json
jc omit password,token users.json

# Convert formats
jc convert --to yaml package.json
jc convert --from yaml --to json config.yaml
jc convert --to csv users.json

# Pretty-print with colors
jc format data.json
cat data.json | jc format --color

# Diff and merge
jc diff old.json new.json
jc merge base.json override.json

# Validate against a schema
jc validate schema.json data.json

# Stats and structure
jc stats big-file.json
jc flatten nested.json

📖 Documentation

Query (JSONPath)

The query engine supports a practical subset of JSONPath:

| Expression | Meaning | |------------|---------| | $ | The root object | | .key | Object property | | ['key'] | Object property (bracket form) | | [index] | Array index (supports negative) | | [start:stop] | Array slice | | [*] | Wildcard — all elements / all keys | | ..key | Recursive descent | | [?(expr)] | Filter expression |

Filter expressions support:

  • @ — current node
  • @.field — field of current node
  • Comparisons: == != < <= > >=
  • exists(@.field) — existence check
query(data, '$.store.book[0].title');          // first book's title
query(data, '$.store.book[-1]');                // last book
query(data, '$.store.book[0:2]');               // first two books (slice)
query(data, '$..author');                       // all authors anywhere
query(data, '$.store.book[?(@.price < 10)]');   // books under 10
query(data, '$.store.book[?(@.category == "fiction")]');
query(data, '$.store.*');                       // all store children

Transform

import { pick, omit, map, filter, renameKeys, flatten, unflatten,
         groupBy, sortBy, chunk, unique, clone } from 'jsoncraft';

clone(value);                    // deep clone
pick(obj, ['id', 'name']);       // keep only these keys
omit(obj, ['password']);         // remove these keys
map(arr, fn);                    // map array
filter(arr, predicate);          // filter array
renameKeys(obj, { old: 'new' }); // rename keys
flatten(obj);                    // { a: { b: 1 } } → { 'a.b': 1 }
unflatten(obj);                  // { 'a.b': 1 } → { a: { b: 1 } }
groupBy(arr, 'role');            // group array by key
sortBy(arr, 'age', 'desc');      // sort array
chunk(arr, 3);                   // split into chunks
unique(arr);                     // deduplicate

Convert

import { convert, parse, stringify } from 'jsoncraft';

convert(input, 'json', 'yaml');         // JSON string → YAML string
parse(input, 'csv');                    // parse CSV into JSON
stringify(value, 'toml');               // serialize to TOML

Supported formats: json, yaml, csv, jsonl, properties, toml.

Note: The YAML and TOML implementations cover the common subset used in configuration files. They are not full-spec implementations. For complex documents, consider a dedicated parser.

Format

import { format, formatCompact, colorize, size, countNodes, depth } from 'jsoncraft';

format(value, { indent: 2, color: true, sortKeys: true });
formatCompact(value);
colorize(jsonString);
size(value);        // bytes when JSON-stringified
countNodes(value);  // total nodes in tree
depth(value);       // max nesting depth

Diff & Merge

import { diff, applyPatch, merge, mergeMany, intersect, union } from 'jsoncraft';

const entries = diff(before, after);
const restored = applyPatch(before, entries);

merge(a, b, { arrays: 'concat' });
mergeMany([a, b, c]);
intersect(a, b);   // keys in both, deeply equal
union(arrA, arrB); // deduplicated concatenation

Validate

import { validate, formatErrors } from 'jsoncraft';

const schema = {
  type: 'object',
  properties: {
    port: { type: 'number', min: 1, max: 65535, default: 3000 },
    host: { type: 'string', required: true },
    debug: { type: 'boolean', coerce: true },
    mode: { type: 'string', enum: ['dev', 'staging', 'prod'] },
  },
};

const result = validate(config, schema);
if (!result.valid) {
  console.error(formatErrors(result));
}

Schema nodes support: type, required, default, enum, min, max, pattern (strings), coerce, items (arrays), properties (objects).

🌳 Browser & Deno support

jsoncraft ships as ESM with no Node.js-specific imports in the core library (only the CLI uses node:fs and node:process). Import it directly in a browser or Deno project:

<script type="module">
  import { query } from 'https://esm.sh/jsoncraft';
  console.log(query(data, '$.users[*].name'));
</script>

🤝 Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines on how to get started, coding standards, and the pull-request process.

Some areas where help is especially appreciated:

  • 🐛 Bug reports and reproducible test cases
  • 📝 Documentation improvements and translations
  • 🧪 More format edge cases (YAML/TOML/CSV roundtrips)
  • 🔌 New transform operators and query filter functions
  • 🎨 CLI enhancements (interactive mode, autocompletion)

📜 License

MIT © Cryptoteep

See LICENSE for the full text.

💖 Sponsors

If jsoncraft saves you time, consider sponsoring the project or just starring the repo — it really helps.