Hacker Newsnew | past | comments | ask | show | jobs | submit | sammycage's commentslogin

Thank you for your kind words and for noticing the work behind this. Building an HTML and CSS rendering engine has been a long journey with many surprises. I have been maintaining https://github.com/sammycage/lunasvg for years, so I was familiar with interpreting specs and rendering engines. That experience gave me the confidence to tackle HTML.

At first, my plan was simple. I wanted to make an HTML rendering library. But soon, I realized it could be even more useful if it focused on paged output so I could make PDFs directly. C and C++ do not have an HTML-to-PDF library that is not a full web engine. I started coding and thought I could finish in a year by working a few hours each day. But reality came fast. HTML and CSS are much harder than SVG, and even small things caused big problems.

I studied KHTML and WebKit to see how real HTML and CSS engines work. The official specs were very helpful. Slowly, everything started to come together. It felt like discovering a hidden world behind the web pages we see every day.

The hardest part has been TableLayout. Tables look simple, but handling row and column spans, nested tables, alignment, page breaks, and box calculations was very hard. I spent many hours fixing layout bugs that only appeared in some situations. It was frustrating, humbling, and also very satisfying when it worked.

I am still learning and improving. I hope other people enjoy PlutoPrint and PlutoBook as much as I do.


Sounds like a wild ride! Thanks for making this open-source.

Quick question:

1. I see you've hand-written parsers yourself both css & html, why not use existing parsers? was minimizing dependencies one of your goals?

2. Does the project recongnize headers / footers and other such @page css rules?

3. Fragmentation(pagination) logic has a huge set of challenges (at least from what I read about Chrome implementing fragmentation) - did you come across this? - https://developer.chrome.com/docs/chromium/renderingng-fragm....

Was fragmentation logic really that difficult to implement?


Thanks for your questions!

1. The documentation for HTML and CSS parsers is pretty straightforward and easier to implement, so I thought it was better to write them myself.

2. It fully supports margin boxes (headers and footers) using properties like @top-left and @bottom-center inside @page rules. You can see more here: https://github.com/plutoprint/plutobook/blob/main/FEATURES.m...

3. Yes, I did come across this. Fragmentation logic is as difficult as it sounds. Right now PlutoBook works with a single, consistent page size throughout a document and does not support named pages, which simplifies things a lot.

Feel free to contact me via email if you have more questions.


Hi! We haven’t specifically tested Colab notebooks. They’re tricky because of dynamic layouts and tables, but simpler notebook exports to HTML might work better. Any feedback or test cases would be super helpful to improve support.


Typst and PlutoPrint serve somewhat different purposes. Typst is more like a modern typesetting language, focusing on fully programmatic document layouts with its own syntax, while PlutoPrint is a Python library built on a C++ rendering engine that converts HTML or XML into PDFs and PNGs. PlutoPrint’s strengths are fast rendering, strong SVG support, and integration with existing Python workflows, whereas Typst is great if you want a typesetting DSL with precise layout control from the ground up.


Interesting. I will give it a try. By the way, why is converting to HTML first a problem for you?


PlutoPrint supports a large subset of CSS, including flexbox for most common layouts, but it’s not a full browser engine, so there are some limitations. You can see a more complete list of supported features here: https://github.com/plutoprint/plutobook/blob/main/FEATURES.m.... We’re also actively tracking bugs and improvements on the GitHub repo: https://github.com/plutoprint/plutoprint/issues, and contributions or test cases are always appreciated to help expand coverage.


Thanks for the feedback. We’ve tested PlutoPrint on multiple platforms, including Windows and Linux, and it generally works well there. Mac-specific issues like crashes or empty outputs are definitely on our radar, and we’re investigating potential causes such as font handling, reverse mtime warnings, or system library differences. We’re also tracking bugs and improvements on the GitHub repo: https://github.com/plutoprint/plutoprint/issues. Contributions, bug reports, and additional test results from different environments are very helpful and appreciated as we continue to improve stability across all platforms.


That’s a good point. Using Puppeteer or a headless browser gives you essentially full web platform support. The tradeoff is that it comes with a heavier runtime and more moving parts (Chromium, Node, etc.). PlutoPrint aims to be much lighter: no browser dependency, just a compact C++ engine with a Python wrapper. It does not cover the entire browser feature set but it is fast, portable, and easy to drop into projects without the overhead of a full browser.


Interesting. I was not aware of PlutoBook!

We're doing a very similar thing (custom lightweight engine) over at https://github.com/DioxusLabs/blitz. We have more of a focus on UI, but there's definitely overlap (we support rendering to image, but don't have pagination/fragmentation implemented).

Have you run the WPT tests against your engine to test spec conformance?


I did this for a project recently, using Firefox and Selenium. It totally worked, but was very heavy on the dependencies and felt very clumsy.

This is exactly what I was looking for a few months ago. I might revisit that project with it.


Excellent response


Your approach is also more predictable. Trying to figure out why Chromium is doing something strange with a complicated page is not practical, while a simple, lean package like this means you can look at the code, trace it and patch it if need be.


WeasyPrint is great, but PlutoPrint takes a different angle: the engine is all C++, so it’s faster and lighter on memory. It can render directly to PNG as well as PDF, and has stronger SVG support.


PlutoBook looks very impressive. Is it based on another renderer?


Doesn't look like it:

> PlutoBook depends on the following external libraries:

> Required: cairo, freetype, harfbuzz, fontconfig, expat, icu

> Optional: curl, turbojpeg, webp (enable additional features)


Clean, thoughtful, and practical. Curious, have you tried benchmarking your Haskell solver against an SMT solver (like Z3 or CVC5) to compare performance or expressiveness?


Thanks. Yes, there are comparisons with Z3 towards the end of the post.

I don't think expressiveness applies here.


I feel this so much. File IO on flaky or network drives is a nightmare, and blocking calls make it worse. It’s good to see the async iterator and substring search moving forward, though it still feels a bit fragile with the thread workaround.

One thing I wonder is how you plan to handle cases where files vanish or change mid‑operation. Will the API just bubble up errors, or do you plan to hide some of that under retries or caching?

Overall, really enjoying these devlogs. Seeing the tradeoffs laid out like this is helpful for anyone building similar tools. Keep it up.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: