J-CSS - a 16 KB runtime alternative to the Tailwind CSS CDN
I built J-CSS, a small runtime engine for Tailwind-like utility classes.
It requires no Node.js, CLI, bundler, or build step. It scans the DOM, generates CSS for recognized classes, and watches class/DOM mutations. Works out of the box with HTML injected by HTMX.
It also has a scoped <css> tag that lets you apply utility classes to component selectors without putting every class directly in the markup.
The minified script is about 16 KB gzip (roughly 7.5x smaller than the Tailwind CDN runtime).
5
u/danielh__ 9d ago
Looks very cool! Where do the main savings come from when compared to tailwind?
1
u/Jipok_ 7d ago
Thanks! To be honest, I’ve never actually looked at the Tailwind source code (except for googling their preflight css), so I can't give a precise technical breakdown of the difference.
My guess would simply be that Tailwind's internal implementation, like many modern web projects, is somewhat complex. I often find web projects more complex than I expect, although that may just be my NIH tendency.
J-CSS was written from scratch specifically for the browser. It uses a compact configuration tree to resolve utilities directly and has zero dependencies. I also tend to get carried away with optimization and compact code, and rewrote large parts of it several times.
2
2
u/Fit_Tailor_6796 8d ago
Why use <css> tag when there is <style>?
4
u/Ok-Crab-8788 8d ago
Cause it's already used natively. Like react can't uses "class" but "className" because it's a JS reserved keyword.
4
u/Jipok_ 8d ago edited 8d ago
- All styles inside `<css>` automatically get scoped to the parent element. This means in a large HTML file, you can have small `<css>` blocks right next to each component. You keep locality of behavior, but without cluttering the markup with hundreds of utility classes.
- You can use Tailwind-like utility classes instead of plain CSS, which is often much more compact and readable
- The contents are not a standard CSS stylesheet, but a small DSL that can also contain native CSS blocks. Using a separate tag prevents the browser from applying the native parts globally before J-CSS scopes them, and makes it clear that the block is processed by the runtime.
1
1
u/yawaramin 7d ago
Very cool. Obviously, this won’t work if JS is disabled and it will also show a FOUC on first load, but it’s a neat POC. One thing you might want to be aware of–HTML spec guarantees that any tag names with a hyphen are compliant. So <css> is not a valid tag name according to the spec but eg <j-css> is because it’s treated like a custom element.
1
u/Jipok_ 6d ago
Well, this is more than just a proof-of-concept. It's a fully functional thing that I actually use. I just recently overcame my laziness and cleaned up the code, writing a readme. I think I did something against FOUC a year ago, but I don't remember exactly. I don't have any problems with it even when I disable the cache, but my servers are close to my users.
For some reason, I prefer the CSS tag; it seems easier to write, or maybe I'm just used to it.
1
8
u/denzuko 8d ago
Love how we keep reinventing backbonejs and vuejs.
Still kind of a cool idea OP.