Complete specification
The grammar, data model, limits, diagnostics, and API behaviour are written down — not inferred from one implementation.
Lima is a small data format with a complete specification, matching TypeScript, Rust, and Go implementations, and none of YAML’s unused machinery.
title: A smaller formatpublished: 2026-09-08authors: - name: Michael role: authortags:
01 / Why Lima
Fifteen lines of frontmatter do not need every feature of a general-purpose serialization format. Lima makes the small language the whole language.
The grammar, data model, limits, diagnostics, and API behaviour are written down — not inferred from one implementation.
No tags, anchors, aliases, merge keys, directives, or multi-document streams. The machinery that is not there cannot misbehave.
TypeScript, Rust, and Go run the same versioned corpus, including exact error codes and source positions.
02 / Why not
Frontmatter is a few lines of key–value data. Each obvious choice carries a cost Lima was built to avoid.
Frontmatter uses a small fraction of it. The unused parts are exactly where implementations diverge from each other and where the past CVEs sit.
Its [section] / key = value
form is noisier than indentation for nested metadata, and it has no equivalent of References.
No comments, every key and string quoted, no multi-line strings — workable for machines, tedious to write and diff as frontmatter.
03 / Measurements
The comparison that does the frontmatter job on both sides: Lima Core 1.0 against js-yaml’s
load() path. About a third less code, and under a sixth of the download.
load()11,787words338KB† The @limaformat/lima
0.5.0 package also bundles References 2.0 — an optional layer (~3,500 more words) with no YAML
counterpart — so the download comparison is conservative. js-yaml’s path additionally carries
anchors and aliases, merge keys, multi-document streams, directives, and 21 tag implementations that
ordinary frontmatter never needs — the same constructs behind the two CVEs below. Lima Core’s
7,471 words also carry 4,136 words of comments, many tying an implementation line to a spec section. The
full accounting — including the Lima Core 1.0 spec at 7,784 words against YAML 1.2.2’s 21,961
— is in the
README.
04 / Security scope
Not a claim that Lima is unhackable — a narrower one: two well-known YAML attack classes have no construct to target, because Lima never implemented the construct. This is worth something only where it applies — when something in your pipeline parses frontmatter you don’t fully control (a CMS, user submissions, a multi-tenant platform), not for your own files.
Executable tags
PyYAML’s !!python/object/new
tag allowed arbitrary code execution (CVE-2020-1747). Lima has no tags, custom or built-in — a
scalar is a string, number, boolean, null, or date, and nothing else.
Alias expansion
Repeated alias expansion let a few kilobytes of YAML allocate gigabytes (CVE-2019-11253, the Kubernetes API server’s “Billion Laughs”). Lima has no alias expansion; References 2.0 resolves by bounded structural copy, capped at 65,536 result nodes — a few kilobytes cannot balloon without limit.
05 / Packages
Choose the package native to your stack. The supported syntax and conformance fixtures remain the same.
npm i @limaformat/lima npm · v0.5.0 → Rust cargo add lima crates.io · v0.5.0 → Go go get github.com/limaformat/lima/go pkg.go.dev · v0.5.0 → Editor support: a VS Code extension ships today; more editors run on a language server.