chenglou/pretext
46.0
Weak · 28 September 2026
18.9k
lines of production code
TypeScript
primary language
4
measurements over time
What this system is
This system is a high-fidelity text layout engine, published as the @chenglou/pretext npm package, designed to replicate the precise line-breaking, bidirectional text, and whitespace handling of major browser engines like Blink, WebKit, and Gecko. It provides explicit locale control and supports complex layout scenarios such as masonry grids, dynamic routing, and rich text rendering. The project includes a comprehensive testing harness and validation tools to ensure consistency across different browser implementations and environments.
Features
New and updated demo pages for layout capabilities
The demos location now includes several new interactive examples: an Accordion demo that calculates section heights without DOM measurement, a Bubbles demo demonstrating tight multiline message sizing, a Dynamic Layout demo with obstacle-aware text routing around logos, an Editorial Engine demo featuring animated orbs and multi-column flow, a Justification Comparison demo, a Rich Text demo, a Markdown Chat demo, and a Masonry demo. The index page has been updated to list these new demos, and the previous demo page structure has been replaced by this new organized set.
pages/demos · high confidence
New build and validation scripts for demo site and engine data
Added scripts to automate the build and deployment of the demo site, including \build-demo-site.ts\ which compiles HTML entrypoints and rewrites asset URLs and links for static hosting, and \generate-engine-break-data.ts\ which extracts and packs line-break and grapheme cluster tables from browser engine data (Chrome, Safari, Firefox) into generated source files. Also added \generate-webkit-generic-families.ts\ to derive Safari's generic font family mappings from Core Text data, and \package-smoke-test.ts\ to verify the published npm package's JavaScript and TypeScript exports.
scripts · high confidence
New grapheme segmentation validation tooling
Added a new suite of scripts in scripts/grapheme-check to validate the project's custom grapheme segmentation logic against the browser's native Intl.Segmenter. The tooling builds a web page that runs the check in real browsers (Chrome, Firefox, WebKit) via the harness, and supports offline execution under Node or Bun. It compares the internal findGraphemeEnds implementation against the engine's segmenter using corpus texts, specific Unicode contexts, and randomized fuzzing, reporting any discrepancies to help ensure consistent text breaking across environments.
scripts/grapheme-check · high confidence
New layout testing harness for browser engine comparison
A new harness has been added to record, predict, and score text layout behavior across Chrome, Firefox, and WebKit. It introduces commands to record browser layouts, check predictions against pinned cases, run performance benchmarks, and compare builds offline using a stand-in Canvas. The harness includes a comprehensive case catalog, accepted failure lists for known browser-specific deviations, and a benchmarking suite to measure library performance across various text operations.
harness · high confidence
New masonry layout demo with virtualized rendering
A new interactive demo has been added at pages/demos/masonry that showcases a virtualized masonry layout engine. The implementation pre-renders text using a specific font configuration and applies word-breaking rules consistent with the Pretext library. It features a custom layout algorithm that calculates proportional column widths and centers the grid, while using an array-based DOM cache to efficiently manage visibility and positioning for large datasets (up to 10k cards) without impacting performance.
pages/demos/masonry · high confidence
Behavioural changes
Cursor rule file converted from symlink to regular file
The rule file located at .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc has been converted from a symbolic link to a standard file. This change ensures the rule content is stored directly within the repository rather than pointing to an external location, which may improve reliability in environments where symbolic links are not preserved or supported.
.cursor · high confidence
Introduce browser-accurate text layout engine with explicit locale control
The text layout system has been rewritten to replicate the line-breaking, white-space collapsing, and bidirectional text (Bidi) rules of Blink (Chrome), WebKit (Safari), and Gecko (Firefox) with high accuracy. This change introduces explicit locale control for text analysis, allowing the layout engine to adapt its behavior to the page language (e.g., handling CJK, Arabic, or Thai specific rules). It also adds support for \letterSpacing\ and \lineHeight\ as explicit layout-time inputs, ensuring that character spacing and line height are measured and applied consistently with browser rendering. The new engine uses generated data tables for line-break states and Bidi levels, replacing the previous generic segmentation logic.
src · high confidence
Introduce oxlint configuration and update AI agent documentation
The project now uses oxlint for linting, defined in the new \.oxlintrc.json\ file, which enforces strict TypeScript rules such as exhaustive switch checks and nullish coalescing. Additionally, \CLAUDE.md\ has been renamed to \AGENTS.md\ to reflect the updated development guidelines and agent instructions.
(repo-wide) · high confidence
Redirect home page to demos and remove obsolete placeholder pages
Visiting the root path now automatically redirects to the /demos section, replacing the previous home page. The standalone placeholder pages for accuracy, benchmark, demo, and interleaving have been removed, as their content has been consolidated or moved into the demos directory.
pages · high confidence
Updated Chrome 153 line-break iterator data
The line-break behavior for Chrome 153 has been updated with new inline data in \break\_iterator\_data\_inline\_header.h\. This change modifies the internal tables used to determine where text can be broken across lines, ensuring the engine's line-breaking rules align with the latest Chrome specifications.
scripts/engine-data · high confidence
Dependencies
Publish @chenglou/pretext package with TypeScript 6 support
The project has been renamed to @chenglou/pretext and published as a public npm package, exposing layout and rich-inline APIs via ESM exports. The package now targets TypeScript 6.0.2 (upgraded from peer dependency ^5) and includes dev dependencies for knip and marked. The package surface is defined with specific entry points, side-effect-free marking, and file inclusions for distribution.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 41 → 46 (+5.4)
- Rubric changed (rubric-2026.08.15 → rubric-2026.09.16) — scores are not directly comparable.
Lenses
- Code Health 64 → 39 (-25.0)
- Architecture 99 (new)
- Maturity 52 → 54 (+1.9)
- Readiness 23 → 40 (+17.4)
- Security 68 → 76 (+7.2)
- Performance 60 (new)
Resolved (21)
- Boundary-crossing change coupling: benchmark.ts ↔ benchmark-check.ts (pages/benchmark.ts)
- Boundary-crossing change coupling: benchmark.ts ↔ corpus-font-matrix.ts (pages/benchmark.ts)
- Boundary-crossing change coupling: corpus.ts ↔ corpus-check.ts (pages/corpus.ts)
- Boundary-crossing change coupling: corpus.ts ↔ corpus-font-matrix.ts (pages/corpus.ts)
- Boundary-crossing change coupling: corpus.ts ↔ corpus-sweep.ts (pages/corpus.ts)
- Boundary-crossing change coupling: probe.ts ↔ probe-check.ts (pages/probe.ts)
- Change coupling: corpus-font-matrix.ts ↔ corpus-sweep.ts (scripts/corpus-font-matrix.ts)
- Change coupling: layout.ts ↔ line-break.ts (src/layout.ts)
- Change coupling: line-break.ts ↔ measurement.ts (src/line-break.ts)
- Change coupling: probe-check.ts ↔ layout.ts (scripts/probe-check.ts)
- Dimension evaluation failed
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- No automated tests
- No exposed public API
- No tests found
- Scanner failed to run — not a clean result
- …and 1 more
New (193)
- Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (the committed lockfile resolved no direct production dependency)
- FileTooLong: sets/sample.ts (harness/sets/sample.ts)
- FileTooLong: src/line-break.ts (src/line-break.ts)
- FileTooLong: src/line-breaks.ts (src/line-breaks.ts)
- FileTooLong: src/rich-inline.ts (src/rich-inline.ts)
- FunctionTooLong: gecko-bidi-levels.getParagraphLevels (src/gecko-bidi-levels.ts)
- FunctionTooLong: gecko-line-breaks.markWordBreaks (src/gecko-line-breaks.ts)
- FunctionTooLong: line-break.walkPreparedComplexLines (src/line-break.ts)
- FunctionTooLong: prepare.measureAnalysis (src/prepare.ts)
- FunctionTooLong: rich-inline.prepareRichInline (src/rich-inline.ts)
- FunctionTooLong: rich-inline.stepRichInlineLine (src/rich-inline.ts)
- High CVE: [GHSA redacted] (bun.lock)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Hotspot: harness/bench/report.ts (harness/bench/report.ts)
- Hotspot: harness/bench/run.ts (harness/bench/run.ts)
- Hotspot: harness/bench/texts.ts (harness/bench/texts.ts)
- …and 173 more
Changes since last survey
- 300 commits — 288 feature/other, 12 fixes
By area
- (root) — 107 commits
- (repo) — 63 commits
- harness/README.md — 12 commits
- src/line-break.ts — 12 commits
- pages/demos — 11 commits
- harness/recordings — 10 commits
- tests/wrapping — 10 commits
- src/layout.test.ts — 9 commits
- src/layout.ts — 8 commits
- src/analysis.ts — 7 commits
- benchmarks/chrome.json — 6 commits
- harness/cases — 4 commits
- harness/sets — 4 commits
- harness/accepted — 3 commits
- scripts/generate-engine-break-data.ts — 3 commits
- src/gecko-line-breaks.ts — 3 commits
- src/measurement.ts — 3 commits
- accuracy/chrome.json — 2 commits
- harness/bench — 2 commits
- harness/cli.ts — 2 commits
Notable commits
- fix: Fix the getWebKitLineBreaks() and compactBreakRules() comments
- fix: Give the soft-hyphen line fix its PR number in the changelog
- fix: Lint with the repo's rules in bun run check, and fix what they find
- fix: Merge pull request #324 from chenglou/platform-bugs-safari-stale-scroll
- fix: Merge pull request #326 from chenglou/platform-bugs-webkit-324310
- fix: Pin the emoji correction fix and refresh validation snapshots
- fix: Pin the rich-inline unfit soft hyphen fix and refresh validation snapshots
- fix: Record WebKit's upstream fix for stale scroll positions and file the dropped wheel input
- fix: Record the gaps the emoji correction fix exposes
- fix: Refresh benchmark snapshots for the emoji correction fix
- fix: Refresh benchmark snapshots for the rich-inline unfit soft hyphen fix
- fix: Say how to fix a mismatch, and drop the CLAUDE.md link
- change: Accept the hybrid's failures, one reason per shape
- change: Add a guide to the Markdown chat demo's patterns
- change: Add a right-to-left message near the end of the Markdown chat
- change: Add equal --offline: two builds' src/ on the invariants' stand-in Canvas in about 10 s
- change: Add the PR number to the layout() changelog line
- change: Add the bench, and count each set's Canvas work in equal
- change: Add the case sets: the real-usage sample, the behaviour catalog, engine facts, rich inline, filed reports and oracles
- change: Add the new harness: record the browser's layout once, predict and score against it
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
chenglou/pretext was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 28 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit e73081fc409c49eaff47f58908abd73995c380cd — the exact code this score is about.
- Scored under rubric-2026.09.16 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-eb9197011364.