Nothing lost without a word
In strict mode every line belongs to a key, a block, or a scalar, or it is an error at its line —
with a hint where a YAML habit such as
description: > is the cause.
Lima is a small data format for frontmatter in which every line has one meaning — written down in a complete specification, the same in TypeScript, Rust, and Go, and with none of YAML’s unused machinery.
title: A smaller formatpublished: 2026-09-08authors: - name: Michael role: authortags:
01 / Guarantees
Fifteen lines of frontmatter deserve the same answer everywhere. Lima writes that answer down — grammar, types, limits, and errors — and three independent implementations show that they give it.
In strict mode every line belongs to a key, a block, or a scalar, or it is an error at its line —
with a hint where a YAML habit such as
description: > is the cause.
TypeScript, Rust, and Go pass the same 479 Core and 141 References cases, error codes and lines included, and agree on 100,000 random documents in every CI run.
true and false are the only booleans, so country: NO stays "NO". Fixed date formats, safe integers, hard limits — one behaviour, no schema to choose.
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 / Security scope
No tags, anchors, aliases, merge keys, directives, or multi-document streams: the machinery that is not there cannot misbehave. 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.
04 / Measurements
Lima is smaller because it does less — the evidence, not the goal. The comparison that does the
frontmatter job on both sides, Lima Core 1.2 against js-yaml’s
load() path: less code, and js-yaml’s download is 4.7 times Lima’s.
load()11,787words338KB† The @limaformat/lima
0.7.0 package also bundles References 2.1 — an optional layer (4,171 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
8,615 words also carry 5,310 words of comments, many tying an implementation line to a spec section. The
full accounting — including the Lima Core 1.2 spec at 10,408 words against YAML 1.2.2’s 21,961
— is in the
README.
05 / Packages
Choose the package native to your stack. The supported syntax and conformance fixtures remain the same.
npm i @limaformat/lima npm · v0.7.0 → Rust cargo add lima crates.io · v0.7.0 → Go go get github.com/limaformat/lima/go pkg.go.dev · v0.7.0 → Editor support: a VS Code extension ships today; more editors run on a language server.