Open sourcing SnapDOM changed everything. Suddenly the audience wasn’t just me, but anyone with their own browser, CSS, and HTML quirks. That’s when I realized how immense the attack surface really is. Every combination of engines, DOM structures, styles, and external resources can break in unexpected ways. At times it felt overwhelming, but I’ve learned to treat each bug as a reproducible pattern: isolate it, fix it, and carry the lesson forward.
From the beginning, two principles guided the work: fidelity and speed. Capturing “every detail” would not matter if the process was unbearably slow, so I spent a lot of time on caching strategies, incremental updates, and efficient DOM cloning. Benchmarking against existing libraries became part of the routine. Performance was never an afterthought — it was always as important as accuracy.
On the technical side, SnapDOM pushed me into DOM cloning strategies, caching, font embedding heuristics, browser-specific hacks, and the constant tradeoffs between fidelity and performance. On the personal side, it has been just as educational: patience, humility, and learning to really listen to users. Some of the best moments have been receiving thoughtful PRs and clear reproduction cases — collaboration that genuinely made the project better. The respect shown in these contributions has been one of the most motivating parts of the journey.
Another milestone: only a few months in, SnapDOM already has its first two GitHub Sponsors and has passed 6k stars on GitHub. Knowing that people found enough value to sponsor the project, and that thousands more cared enough to star it, has been incredibly rewarding.
I’ve also been designing a plugin system, so the core stays lean while features like cropping, filters, or alternative exporters can live as extensions. It’s not merged into the mainline yet, but it’s a direction I’m excited about — and another layer of complexity to manage as the project evolves.
It’s still early days, but reflecting on the journey from April to now has been meaningful. What started as a small internal helper for a zoomable UI turned into an open source project with real users, contributions, sponsors, and community respect. Balancing the technical struggles with the human side of open source has made this one of the most rewarding experiences I’ve had so far.
Thank you, Martin
Repo: https://github.com/zumerlab/snapdom
For this project, I tried to manage my expectations, but anyway, I feel horrible. How do you balance the need to promote your project with the fear of being too self-promotional? Any tips or advice would be greatly appreciated!
During development, I faced several challenges, including testing different features. I noticed that CSS linters and other tools didn't allow me to see why something wasn't working, even if there were no basic errors. Another typical CSS problem was seeing how it was shared across different browsers. Fortunately, I discovered that certain new CSS features can be used to create a series of real-time tests. These features are @support, @container, and :has().
By combining these features, I developed a testing system not only to check if the framework works in the browser but also, and most importantly, to see if we are applying HTML correctly according to the browser's requirements and avoiding involuntary errors when developing an application.
Since my CSS framework necessarily uses features that only the newest browsers have, such as trigonometric functions like cos() and sin(), I created a series of rules to test if they are supported by the browser. If they're not, a message appears asking to update the browser. Similarly, if the browser doesn't support :has(), which is used throughout the framework.
There are also typical cases of browser incompatibility, so in some non-critical cases, I use @support or @container to hide certain Orbit features that don't affect its use. For example, Safari doesn't accept SVG context-stroke, so I hide them.
However, beyond those critical checks and compatibility, the most common issue when using a CSS framework is not knowing how to use it properly. That's why I created other CSS rules that allow analyzing if a parent element has the required child elements and not others. Here, visual alerts also appear while developing to give a hint about where the error is in the code.
I'll leave some links in the comments below for further reading.
By combining these features, I developed a testing system not only to check if the framework works in the browser but also, and most importantly, to see if we are applying HTML correctly according to the browser's requirements and avoiding involuntary errors when developing an application.
Since my CSS framework necessarily uses features that only the newest browsers have, such as trigonometric functions like `cos()` and `sin()`, I created a series of rules to test if they are supported by the browser. If they're not, a message appears asking to update the browser. Similarly, if the browser doesn't support `:has()`, which is used throughout the framework.
There are also typical cases of browser incompatibility, so in some non-critical cases, I use `@support` or `@container` to hide certain Orbit features that don't affect its use. For example, Safari doesn't accept SVG `context-stroke`, so I hide them.
However, beyond those critical checks and compatibility, the most common issue when using a CSS framework is not knowing how to use it properly. That's why I created other CSS rules that allow analyzing if a parent element has the required child elements and not others. Here, visual alerts also appear while developing to give a hint about where the error is in the code.
I don't want to bore you with the details specific to Orbit, but I'll leave you the link to the support source and related documentation.
Repo: https://github.com/zumerlab/orbit
Source file: https://github.com/zumerlab/orbit/blob/main/src/scss/_support.scss
Orbit related documentation: https://zumerlab.github.io/orbit-docs/tools/support/
Good to go deeper: https://heydonworks.com/article/testing-html-with-modern-css
edited: typo Suorce -> Source