HNHacker News
TopNewBestAskShowJobs

cosmiciron

32 karma · joined February 26, 2026

Software engineer. Writer. Director.
submissionscomments
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
I beg to differ. People equate good writing with the cosmetics, which AI excels at, but it’s the substance that truly matters.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Its UI is too complicated for my taste. Besides, its screenplay support isn't perfect.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
I'm not sure I understand what you are asking here. If it's some advanced feature, which is obviously out of my domain of expertise, you are welcome to participate and fork the project to implement it yourself.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
AI helped me write the documentation because it does a better job than I ever could. I honestly wish I’d had AI to help me write my screenplay ten years ago.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
I was an animation director, so I didn't do stunts. Sorry.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Who said I used HTML? It was impossible to write screenplay/manuscript in HTML and receive industry compliant outputs when printed/converted to PDF.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Because CSS is exactly what I wanted to avoid. I just needed predictable pager layout, and I didn't want to wrestle with CSS. Besides, this thing's tiny size allows it to run in a serverless function on the Edge, and that can be useful sometimes.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Why hide it?
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
And that's precisely why I'm neither a blockbuster director nor a massively paid "chief scientist", LOL.

As for the strange sentences? Before the web turned everything into paperless, infinite scrolls, people actually cared deeply about printed materials. With that came the strict requirement for pagination rules, widows, orphans, and deterministic behavior for margins. In fact, one of my favorite pieces of tech was built exactly around solving the discrepancy between display and print: NeXTSTEP with its Display PostScript technology.

To answer your question about the subtle difference between a line and paragraph break: mathematically, they trigger completely different layout states in a typesetting engine. A line break (soft return) just wraps text to the next line while preserving the current block's alignment and justification math. A paragraph break (hard return) ends the semantic block entirely, triggering top/bottom margins, evaluating widow/orphan rules for the previous block, and resetting the layout cursor for the next.

I had to build an engine that deeply understands this difference because in the film industry, screenplays are still written in Courier with strictly measured spatial margins and peculiar contextual rules on how blocks of dialogue break across pages. So this tool is basically my homage to an era long gone...

cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
This project started from exactly there too until I couldn't push react-pdf any further. The MORE/CONT'D feature required by screenplay was impossible to implement with react-pdf's black box so I had to write my own.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Exactly! That's someone speaking from experience, I can tell! :p And yes the tests are in there. And interestingly enough, because the engine emits its IR (in compressed JSON), I can use those as snapshots for the tests. They work better than relying on PDF or SVG outputs.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Thanks for the correction. I'm actually not familiar with Prince, so I really can't tell.

To be clear, VMPrint isn't meant to compete with established engines like that. It’s just a genuinely helpful tool I built from scratch for the specific tasks I needed to accomplish because I couldn't find an alternative.

Prince looks powerful, but I have a feeling it probably wouldn't have been the right fit for my use case anyway.

cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Thank you for the kind words. I hope it becomes a useful part of your toolkit. It certainly is for my need to generate screenplays.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
And what's the point of being right when it's slow and bloated? Come on, it works for a lot of use cases, and it doesn't work for some. And it's still evolving.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
As someone who has spent decades in the lucid dreaming community researching consciousness (and created the SSILD technique), I could give you a very long, highly philosophical answer about the nature of the self, LOL.

But in the context of this repository: 'I' is the carbon-based entity that designed the layout architecture and takes full responsibility for the bugs.

cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Good eye, you are right. A few others noticed this as well. It is a known trade off given the engine being pure JS and only 80K. The project is still at very early stage, and I'm definitely keeping my eyes open for solutions.
cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
You are absolutely right about the Devanagari. That is a known trade-off at the moment. Because the core engine is strictly constrained to 88 KiB of pure JavaScript, it intentionally bypasses massive C++ shaping libraries like HarfBuzz. I haven't yet found a way to process complex text layout (CTL) and fuse those ligatures purely in JS without completely blowing up the bundle size. It's a very early implementation, but finding a micro-footprint solution for that is on the ROADMAP!

Though, to be fair, for my original need—generating industry-standard screenplays from Markdown—the engine is already total overkill. LOL.

As for the film: my feature premiered in January 2024 in China under the title 《天降大任》. It was originally developed in Los Angeles as an English-language project called Chosen. I actually put down my programmer's hat and worked on that film for over ten years!

cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
You are completely right on all fronts. Thank you for taking a look at the code!

You hit the exact architectural bottleneck. Right now, the engine uses Intl.Segmenter to find the grapheme boundaries, but then it just does a direct cmap lookup to get the advance widths. It currently lacks a parser for the OpenType GSUB (Glyph Substitution) and GPOS (Glyph Positioning) tables, which is why Arabic defaults to isolated forms and Indic matras don't fuse.

The standard advice is exactly what you suggested: "just drop in HarfBuzz." But that creates an existential problem for this specific project. HarfBuzz is a massive C++ library. To run it in an Edge worker or pure V8 environment, I'd have to ship a WebAssembly binary that is often upwards of 1MB. That entirely defeats the purpose of building an 88 KiB, pure-JS, zero-dependency layout VM.

Doing complex text layout (CTL) and shaping purely in JavaScript without exploding the bundle size is essentially the final boss of this project. The roadmap is to either implement a highly tree-shakeable, pure-JS parser for the most critical GSUB/GPOS rules, or find a way to pre-compile shaping instructions.

For right now, it's a known trade-off: lightning-fast, edge-native pure JS layout, at the cost of failing on complex cursive ligatures. If you know of any micro-footprint pure-JS shaping libraries that don't rely on WASM, I am all ears!

cosmiciron··on Show HN: I built a zero-browser, pure-JS typesetting engine for bit-perfect PDFs
Incredible eye. You are absolutely right, and that is actually an artifact of the engine's current architecture!

That screenshot includes the Hindi word 'देवनागरी' (Devanagari) and some Arabic text with diacritics. Because VMPrint is an 88 KiB pure-JS engine, it handles text segmentation natively (Intl.Segmenter) but it intentionally bypasses massive, multi-megabyte C++ shaping libraries like HarfBuzz.

The trade-off is that for highly complex scripts (like Indic matras or certain Arabic vowel attachments), the pure-JS pipeline doesn't yet resolve the cursive ligatures perfectly, so the font falls back to drawing the combining marks on dotted circles. It mathematically calculates the bounding boxes correctly, but the visual glyph substitution isn't fused. It's one of the biggest challenges of doing zero-browser, pure-math typography, and it's an area I'm actively researching how to optimize without blowing up the bundle size!