Breathing Check
Paste a draft and get two numbers: words per non-paragraph element, and bold spans per 100 words. Handles Chinese, where counting words takes a stated convention before any score exists — ideographs are counted by character and converted with a stated, arbitrary divisor. Runs in the page. No account.
How this page was produced
Drafted by an AI agent. Reviewed line by line against its sources and raw data by a model from a different family than the one that produced it, with no unresolved P0 findings. Not yet read in full by a person. Evidence last verified 2026-09-09.
A long piece of writing needs places to rest. Headings, lists, tables, pulled quotes — the things that are not another paragraph. Without them a reader who skims finds nothing to land on and leaves.
This tool measures two proxies for that, and it is honest about the fact that most of our own long pages did not clear them.
The two numbers
| Check | Threshold | What it is asking |
|---|---|---|
| Words per non-paragraph element | ≤ 150 | How far can you scroll before something breaks the grey? |
| Bold spans per 100 words | ≥ 1 | Is there anything for a skimming eye to catch? |
| Long-form floor | > 800 words | Below this, neither check applies |
Under the floor, the tool reports not judged — not zero, not a fail. "There was no basis to evaluate this" and "this was evaluated and it is terrible" are different facts, and a tool that prints the same thing for both is lying about one of them.
The part a word count cannot do on its own: Chinese
Readability tools count words. Chinese does not have whitespace word boundaries, so "how many words" has no answer until someone picks one. A score built on counting words cannot say anything about Chinese until it commits to a convention — and one that does not tell you which convention it picked is reporting a preference, not a measurement.
The convention here is fixed and stated:
words = Latin tokens + (Unified Ideograph characters ÷ 1.7)
The 1.7 is arbitrary. It was chosen because a gate cannot exist without a number, not because it is true. Any other constant would work as long as one constant is fixed. That is exactly why the tool prints the split — "1607 Latin + 0 ideographs ÷ 1.7" — on every result instead of handing you a single authoritative-looking total.
"Unified Ideograph" means the base CJK Unified Ideographs block,
U+4E00–U+9FFF, taken from the Unicode Character Database. That is a
deliberately narrow reading: the database lists eleven blocks under that name
(the base plus Extensions A–J), and counting the whole family would be the
more generous choice. We count the base block only, because that is what the
build gate enforcing this rule on our own repository counts — one rule with
two implementations that disagree is worse than either reading. The cost:
a rare Extension ideograph is not counted as a word. Kana, Hangul, fullwidth
forms and CJK punctuation are outside the range too: 。,、「」 are not words.
One consequence worth knowing before you compare a translation to its
original. Across the seven articles this site had published in
both languages at a746249, every Chinese version carries the same headings
and lists as its English original — element counts match exactly, pair for
pair. The word counts do not: they land anywhere from 8% below the English
to 9% above it, four of the seven longer in Chinese and three shorter.
So the shared threshold is not uniformly harsher on Chinese. It bites harder on the pages whose translation ran long and easier on the ones that ran short, and which way a given pair went is a fact about that translation, not about the language. Two of the three pairs in the table below went the other way: the Chinese is shorter and scores the better ratio. Measure the pair in front of you instead of inferring its direction.
What counts as an element
- Each list item is one element — a bullet is its own resting point.
- A table is one element, not one per row. Same for a blockquote.
##and###headings count; the#title does not, because an article has exactly one and it is not breathing.- A fenced code block is one element — it breaks the grey like a table does — but the code inside it is not prose, so none of its words count. A list marker inside a fence is not a list item either.
- h4 to h6 are folded in with
##and###. R4.2 names only the latter; counting a deeper subhead as breathing is the honest reading. - An image on its own line is one element.
- A component or block tag that opens a line is one element — the
<BreathingCheck />further down this page, a<figure>, a<table>. Something visibly not-a-paragraph is sitting there, so it counts as a place to rest.
We fail our own check — and our first attempt to measure that was wrong
Running this on the six long-form pages this site had published as of commit
a746249, before any remediation:
| Page | Words | Words/element | Bold/100 words |
|---|---|---|---|
| Research → executive report (en) | 1342 | 53.7 | 0.67 |
| Research → executive report (zh) | 1459 | 58.4 | 0.62 |
| Lock-in has a file format (en) | 1524 | 138.5 | 0.52 |
| Lock-in has a file format (zh) | 1458 | 132.5 | 1.10 |
| The export is the product (en) | 1607 | 160.7 | 0.44 |
| The export is the product (zh) | 1475 | 147.5 | 0.88 |
Five of six missed the bold threshold, and one missed the element threshold too. Those pages were live while this tool was being written.
The interesting part is the number that is not there. Our first pass at this measurement reported six of six failing. It was wrong, and it was wrong in a way worth showing you, because the bug is one anybody writing this kind of tool will hit:
The bold counter used a regular expression that forbade a line break inside a bold span. This repository hard-wraps its source at about 80 columns, so every bold phrase that happened to straddle two lines was invisible to it. The Chinese version of Lock-in has a file format actually had 16 bold spans, not 11 — it had been passing all along.
A second, subtler bug sat behind it: stripping inline code before counting
pushes whitespace in front of a closing **, and CommonMark then refuses to
read it as emphasis. The fix is to mask code spans to the same length rather
than delete them.
Both were found by re-counting with a real MDX parser and comparing. The counter you are about to use now produces identical numbers to the build gate that enforces this rule on our own repository — that agreement is asserted by a unit test, not by hope.
The lesson generalizes past this tool: approximating a format that has a real parser gives you a number that looks reasonable and is systematically skewed. We had the wrong figure about our own archive in writing, and only caught it by re-measuring against the parser. A metric you have not tried to break is a metric whose error bars you do not know.
Worked example
Here is the tool's own output for the worst of them — our article The export
is the product, English, as it stood at a746249. The text below is
generated by running the tool's logic on that file, not written by hand:
Long-form and short of breath — R4.2 checks below.
Words: 1607 (1607 Latin + 0 ideographs ÷ 1.7)
Words per non-paragraph element: 160.7 (10 elements, threshold ≤ 150) — fail
Bold per 100 words: 0.44 (7 bold spans, threshold ≥ 1) — fail
Measured with the AtomStorm Breathing Check (atomstorm.ai/en/tools/breathing-check/). Adding ** to hit the bold number does not add breathing — split the wall instead.
Paste a draft
Markdown or MDX. Nothing is uploaded — the count runs in this page. Frontmatter and fenced code are excluded before anything is measured.
The trap in the second number
Bold density is a proxy. You can hit it in ninety seconds by scattering
** through a wall of text, and the page will be exactly as unreadable
afterward — with a better score.
The honest moves are the ones that raise the number as a side effect:
- Cut a long section in two and give each half a heading.
- Turn a three-clause sentence into three bullets.
- Put the comparison you described in prose into a table.
- Pull the caveat out into a quote.
If the number went up and the page did not get easier to skim, the edit was wrong. That is the whole reason this page shows you a table of our own shortfalls instead of just a threshold.
What we verified, and what we did not
- Verified. This counter returns the same words, elements and bold spans
as
scripts/readability-verify.mjs, the build gate that enforces this rule on our own repository, for every content file in it — a unit test runs the gate and compares the two, file by file, so the pair cannot drift apart in silence. That gate's bold counter was itself cross-checked against the real MDX compiler. Ratios divide the unrounded word count; rounding first shifts the last digit. The example above is regenerated from the frozen commit it names. - Not verified. That either threshold predicts anything about real reading behaviour. They encode an editorial preference, tested against our own archive and nobody else's. We have run no reader studies. The reference card gives both numbers the same standing: thresholds this site holds itself to.
Sources
Unicode Consortium
Unicode Character Database — Blocks.txt (the CJK Unified Ideographs block ranges)unicode.org · Checked 2026-09-09
Unicode Consortium
UAX #29: Unicode Text Segmentation — why word boundaries are not a whitespace problemunicode.org · Checked 2026-09-09
Nielsen Norman Group
Nielsen Norman Group — How Users Read on the Webnngroup.com · Checked 2026-09-09