Skip to content

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 09:39
· 6 commits to main since this release
d07818f

tiny

Change one import

npx tinyswap

tinyswap finds js-yaml, yaml, yamljs, @std/yaml, json5, strip-json-comments, jsonc-parser, comment-json, jju, ini and @one-ini/wasm in your project, picks the subpath for the version you have installed, shows the diff, then rewrites the imports and swaps the dependencies. Or do it by hand:

- import yaml from "js-yaml";
+ import yaml from "tinyaml/js-yaml";

- import JSON5 from "json5";
+ import JSON5 from "tinyjson5/json5";

- import ini from "ini";
+ import ini from "tinyini/ini";

The calls, options, output and errors stay the same.

What you get

You use Switch to Size, gzip Parses Stringifies
yaml tinyaml/yaml 29.8 → 16.9 KiB 12.0× faster 2.8× faster
js-yaml 4 tinyaml/js-yaml 14.4 → 11.6 KiB 1.6× faster 1.7× faster
json5 2.2.3 tinyjson5/json5 7.5 → 3.2 KiB 7.4× faster 4.7× faster
comment-json 4.6.2 tinyjson5/comment-json 35.3 → 18.2 KiB 1.8× faster 1.3× faster
@one-ini/wasm 0.2.1 tinyini/one-ini 36.0 → 1.7 KiB 12.4× faster —
ini 7.0.0 tinyini/ini 1.6 → 1.5 KiB 1.8× faster 2.9× faster

Writing new code? The root tinyaml API is 7.7 KiB. It parses 18.7× faster than yaml, stringifies 12.9× faster, and gets all 373 yaml-test-suite cases with an expected result right. js-yaml, yaml, yamljs and @std/yaml each get some wrong.

The full table lists all 18 drop-ins. Measured on an Apple M4 with Node 26.13.0.

How we know they match

A drop-in only helps if nothing breaks. Each one passes the original library's own test suite and is fuzzed against the original: a million inputs per subpath for tinyjson5 and tinyini, and thousands per subpath for tinyaml. Each one also covers the edges, from errors and warnings to getters, proxies and sloppy-mode writes. Every known difference is listed in that package's README, along with bugs in the original that tiny doesn't copy.

Typed config imports

VS Code: importing config.yaml gives it a TypeScript type, and a misspelled key is an error

All three parsers are TypeScript 7.1 content mappers. Register one in tsconfig.json, and an import config from "./config.yaml" (or .json5, .jsonc, .ini) is typed the way a .json import is. A typo in a key becomes a type error, and a syntax error shows up at its line and column.

A YAML linter

VS Code with tinyaml/eslint: draft: no and published: 2026-11-01 are underlined, because other YAML readers load them as a boolean and a date

tinyaml-lint catches YAML that other readers load differently, such as no as a boolean or 2026-11-01 as a date. It runs from the CLI, as a library (tinyaml/linter), as an ESLint plugin (tinyaml/eslint) and as a Vite Doctor extension (tinyaml/doctor).

Install

pnpm add tinyaml tinyjson5 tinyini

Each package is published on its own, so install only what you use. Docs at tiny.onmax.me.

👉 Changelog

🚀 Enhancements

  • type .yaml, .json5, .jsonc and .ini imports with TypeScript 7.1 content mappers (#18)
  • add tinymigrate, a wizard that moves a project to the drop-ins (#15)
  • add a YAML linter and a Vite Doctor extension (#6)
  • tinyjson5: add tinyjson5/jju, a drop-in for jju 1.4.0 (ae4853f)
  • tinyjson5: add tinyjson5/comment-json, a drop-in for comment-json 4.6.2 (3c1dd49)
  • tinyjson5: add tinyjson5/jsonc-parser, a drop-in for jsonc-parser 3.3.1 (76c48ba)
  • tinyjson5: add drop-ins for strip-json-comments 2, 3 and 5 (0e9401e)
  • tinyjson5: add tinyjson5/json5-v1, a drop-in for json5 1.0.2 (553025e)
  • tinyjson5: give the root json5 3's rules and a strict jsonc option (787ee99)
  • tinyini: add tinyini/one-ini and tinyini/one-ini-v0.1 (74e11b1)
  • tinyini: add tinyini/ini-v1 and tinyini/ini-v2 from the shared core (10c6206)
  • tinyini: give the root its own INI API, without ini's legacy (2f34e60)
  • add drop-in entries for js-yaml 4 and 5, yaml, yamljs and @std/yaml (a69764c)
  • add tinyaml, a YAML loader and dumper with js-yaml JSON_SCHEMA semantics (ed8e6b4)

🔥 Performance

  • tinyjson5/jsonc-parser: look for control characters in the string itself, not with a regex that reruns at each line (c654727)
  • tinyjson5/jju: make jju's silent writes with one sloppy-mode function, not Reflect (d1101d9)

🩹 Fixes

  • remove five more quadratic paths, close the twelfth review's findings, and list the bugs tinyaml doesn't copy (1b909b5)
  • read byte order marks and warnings in linear time, and close the eleventh review's findings (ed604d1)
  • close the tenth review's findings (9452614)
  • close the ninth review's findings (23797f4)
  • close the seventh review's findings (e4bc01e)
  • tinyaml/js-yaml-v5: build the null limit without a chained type assertion (ce8f288)
  • close the fifth and sixth reviews' findings, and make the linter use the parser (c5c516c)
  • tinyjson5/jsonc-parser: build the enums, error names and format comparison without built-ins jsonc-parser doesn't call (0ae91ee)
  • tinyjson5/comment-json: keep the faster paths only with this realm's Array, String and Object prototypes (9e7e675)
  • tinyjson5/jsonc-parser: read characters as jsonc-parser does in string errors and comment lookahead, and document sliced token values (6478451)
  • tinyini: check each package specifier loads its own mode, and read typed-array lengths across realms (8212df6)
  • tinyini: probe each bundle's mode behaviour, compare other one-ini builds by version field only, and match boxed strings and shadowed typed-array lengths (a21b2cd)
  • tinyini: keep one-ini's working data out of arrays, read root arrays as JSON does, and reject invalid fuzz counts (ae6c212)
  • tinyini: build the one-ini AST after parsing, as serde does, and stop root arrays at their first length (84707df)
  • tinyini: fail the oracle scripts on a broken harness, and match toJSON, inherited AST names and the glue's length read (d663ec0)
  • tinyjson5/comment-json: restore an outer stringify's cache, throw the engine's TypeError, check constructors before reading them, convert odd keys at each lookup (0e95043)
  • tinyjson5/jsonc-parser: scan strings a character at a time as jsonc-parser does, without a fast path that reads some twice (80b2607)
  • tinyjson5/comment-json: read Symbol.for at each comment lookup as comment-json does, and bind only a call whose name and length are data (8980d5c)
  • close the fourth review's findings, and find yaml's second document where yaml does (7332668)
  • tinyjson5/comment-json: split comment keys with the captured string built-ins, step aside when the global Symbol changes, and keep undefined as a prop (0623075)
  • tinyjson5/comment-json: read every built-in from globalThis's descriptors and probe it on private receivers; look up comments by prefix and prop (44681e4)
  • tinyjson5/comment-json: check each kept built-in does its own job, not another's of the same name (883ecc6)
  • tinyjson5/comment-json: know the engine's own built-ins by name, and read them without running getters (f20c101)
  • tinyjson5: typecheck without fetched fixtures, and run CommonJS originals' own tests on Node 22 (e2eef3a)
  • tinyjson5/comment-json: take the faster paths only with the engine's own built-ins (60db330)
  • tinyjson5/comment-json: read comments without the array and map methods a program can patch (5721823)
  • tinyjson5/comment-json: read comments once only while Symbol.for is the native one (d46968c)
  • tinyjson5/comment-json: read comments once only on the standard prototype chain (8b911f2)
  • tinyjson5: make every write in the ported sloppy-mode functions fail silently as there (0751ca3)
  • tinyjson5/comment-json: keep array-timsort's class strict (a28e031)
  • tinyjson5/comment-json: write to the array array-timsort sorts as its sloppy-mode code does (8b41c1d)
  • tinyjson5/comment-json: write parsed values as sloppy mode does, and drop the comment cache when stringify throws (0c7b27d)
  • tinyjson5: assign to primitives as sloppy mode does, and need Node 22.12 (c32abbf)
  • tinyjson5: keep comment-json's sloppy-mode writes, and jju's Node assert (0fcfbcb)
  • tinyjson5: keep jju's sloppy-mode writes, its option reads and its call types, and declare jsonc-parser's enums as enums (c8fbd17)
  • tinyjson5/jsonc-parser: type its enums as enums, and keep its formatter's tables and its scanner's bounds (f28096b)
  • tinyjson5: convert the text before setting a call's state, and iterate v1 replacer lists as Babel does (efdb8c5)
  • tinyjson5/json5-v1: throw where json5 1.0.2's strict-mode delete throws (678ab4c)
  • tinyjson5: make each original's reads, in its order, for hooks, getters and proxies (7f9c4f3)
  • tinyjson5: hold every entry to its own original, and check every mode file's exports (cd81e5f)
  • tinyini: follow ini's read order, pass toJSON its key, and make every test gate fail on a broken harness (c17fc21)
  • tinyini: read options and values as often as ini does, match odd one-ini lengths, and run one-ini's own tests (b58b90e)
  • tinyini: measure each entry's default export, isolate old ini versions, and cover every export (c3fe038)
  • docs: show the generated drop-in table on the home page, since #11 removed drop-ins.svg (87d317b)
  • close the gaps the third review found (7df325f)
  • close the gaps the second review found in round one's fixes (d34dd36)
  • follow the spec in more corners of the root, and match each original on more options, tags and errors (c12097e)
  • tinyjson5: keep a property the reviver can't delete, as json5 does (3f70b8a)
  • match js-yaml 4, js-yaml 5, @std/yaml and yaml errors and warnings more closely (9ea7b62)
  • match js-yaml 4, js-yaml 5, yaml, yamljs and @std/yaml on more inputs (6dbcc9c)

💅 Refactors

  • tinyswap: rename tinymigrate to tinyswap, since npm blocks tinymigrate as too close to tiny-migrate (#21)
  • tinyini: call the typed-array length getter through Reflect.get, not an unbound reference (1b52b25)
  • tinyjson5: move the parser and stringifier into a shared core with one build per mode (51e9e9e)
  • tinyini: shrink the root so it stays the smallest entry (1e25df9)
  • tinyini: move the parser into a shared core with per-mode builds, and add tinyini/ini (036730d)
  • shrink every entry with a build mode per library and less duplicated code (0136e59)

📖 Documentation

  • document the tinyswap codemod (#12)
  • add bundle sizes to the package overview (#22)
  • show typed imports, the linter and Vite Doctor at the top of their sections (#19)
  • tinyini: measure the size of parse alone on the M4 (ac89989)
  • draw 🤏 as Noto Emoji does, whole and unmirrored in the banners (#17)
  • tinyini: measure size, speed and stack depth on the M4, and rewrite the website's pages for the root and subpaths (11eade0)
  • one Copy page button with a menu for View as Markdown, ChatGPT, and Claude (#14)
  • import swaps in tabs, and plain wording across the website (#16)
  • rebrand around the 🤏 emoji: logo, favicons, hero, banners and charts (#13)
  • tinyjson5: list the bugs tinyjson5 doesn't copy, and the M4 speed of every operation from scripts/speed-table.ts (3b9a87b)
  • measure every drop-in on the M4, count all 18 in the root banner, and say strip-json-comments' time is for stripping (dfcd37b)
  • tinyini: list the bugs the originals have and tinyini doesn't, and drop the ini 3–4 Windows line-ending note (dd0a414)
  • tinyjson5: introduce the root's differences from json5 2 without saying all follow JSON (5a595ee)
  • tinyjson5: say stringify looks for toJSON5 and toJSON on every value but null and undefined, as json5 does (8449fe2)
  • tinyjson5: say stringify runs toJSON5, toJSON, the replacer and its BigInt check as JSON.stringify does (8b8036c)
  • tinyjson5: say how stringify looks up toJSON5 and toJSON (7282940)
  • tinyjson5: a trailing comma ends each object or array written with a member (2c720de)
  • tinyjson5: describe the reviver as json5 3 calls it, and when space adds trailing commas (6db9b2b)
  • tinyjson5: describe space as it works, and the reviver without describing JSON.parse's context (f75f50c)
  • tinyjson5: say any truthy jsonc turns the mode on (e389c20)
  • tinyjson5: say the reviver gets no context argument, and quote takes null for its default (6e660d3)
  • tinyjson5: align the getting-started option table (8d3d7bf)
  • tinyjson5: say bigint takes null as false (a8fbb90)
  • tinyjson5: list the fields jju's assertion error keeps off Node (34ceb7b)
  • tinyjson5: say require() loads the subpaths, which fuzz options are picked at random, and that throwing stringify calls match by error (ca0f9e3)
  • tinyjson5: say which numbers bigint makes BigInts, which comments end at a line break, and that the ports keep their tokenizers (2659522)
  • tinyjson5: point the banners at tinyjson5/json5, call strip-json-comments' timings stripping, and count fuzz seeds apart from edits (fd7ce58)
  • tinyini: document every subpath, its differences and how it's checked, and add its rows to the drop-in tables (ddba103)
  • point json5 users at tinyjson5/json5, and give the tinyjson5 card its measured size and speed (1f9adb6)
  • tinyjson5: rewrite the website's pages for the root and subpaths, measure again, and correct the jju test count and the tsconfig's lines (f054376)
  • tinyjson5: measure the drop-ins again after the speed and fidelity fixes, and update the size tables (f0766ed)
  • tinyjson5: the speed of every operation next to its original, and say substring and fromCharCode are called otherwise in jsonc-parser (49a8d40)
  • tinyaml: list the linter pages in the sidebar, and link the rules to the website (d98f352)
  • tinyjson5: measure each subpath next to its original, and say where each package was measured (b08fdcc)
  • record tinyjson5's root next to its drop-ins, for its size badge (6b08c26)
  • give each tinyjson5 subpath a drop-in row, with stringify optional for parse-only libraries (d2188e1)
  • restructure the READMEs, and generate their badges and drop-in tables with automd (#11)
  • add the tiny website at tiny.onmax.me (#10)
  • add a family logo, favicon, banners and one drop-in chart for the root README (#9)
  • lead the README with the size, speed and drop-in numbers (a8aecf9)
  • add a logo and redraw the banner (b2f4edc)

📦 Build

  • docs: Nuxt 5 nightly, @vite-hub/content, and the Worker config in nuxt.config.ts (6c65371)

🏡 Chore

  • tinyjson5: ship the licenses of the code the subpaths port (08252c9)
  • tinyini: benchmark every entry, from the built dist (fc590f2)
  • tinyini: add scripts/versions.ts, which fuzzes each ini version against the next (c4bd92c)
  • turn the repository into a pnpm workspace for tinyaml, tinyjson5 and tinyini (#8)
  • turn the repository into a pnpm workspace for tinyaml, tinyjson5 and tinyini (17efe0a)
  • import tinyini into packages/tinyini (f33e1c8)
  • import tinyjson5 into packages/tinyjson5 (c3e4080)
  • move tinyaml into packages/tinyaml (8f60c57)
  • add Pullfrog review through CLIProxy (#5)

✅ Tests

  • tinyswap: expect the version range tinyswap writes, not latest (#24)
  • tinyaml: compare n with 8n in the scaling tests, with room for a busy CI runner (c971605)
  • tinyaml: warm up and take the best of five in the scaling tests (49f774d)
  • tinyjson5: fuzz jju's legacy option too, and count the benchmark tsconfig's lines right (863b9da)
  • remove redundant proof and strengthen test guards (#7)

🤖 CI

  • install without git hooks, so the packages' vp config prepare scripts don't race for .git/config (15ea32e)
  • publish a preview package for every commit on main (7381331)

🎉 New Contributors

❤️ Contributors