For the best experience and access to advanced features like playgrounds and interactive previews, please visit the Grimoire CSS site. The documentation is the same in both places.
- Everything in Its Place
- A Spell System
- Scroll: Crafting Reusable, Dynamic CSS with Infinite Flexibility
- Variables and Built-in Functions: Total Control Over Styles and Sizes
- Predefined Scrolls and Built-In Animations: Flexibility at Your Fingertips
- External Scrolls & Variables
- Language-Agnostic Parser: Extracting Spells from Any File, Any Format
- CSS Optimization: Minification, Vendor Prefixes, and Deduplication - All with CSS Cascade in Mind
- Professional-Grade Color Toolkit
- Projects
- Shared and Critical CSS: Optimizing Your Styles for Maximum Efficiency
- Performance By Design: Built for Speed and Efficiency
- A Streamlined CLI with a Strict and Straightforward API
- Easy Migration with Transmutator
- Usage and Distribution
- MCP Server
- The Arcane Circle
- Release Information
Grimoire CSS is a comprehensive CSS engine crafted in Rust, focusing on unmatched flexibility, reusable dynamic styling, and optimized performance for every environment. Whether you need filesystem-based CSS generation or pure in-memory processing, Grimoire CSS adapts to your needs without compromising on performance or features.
Everything in Its Place
- True CSS engine. Exceptionally powerful and endlessly flexible. Independent and self-sufficient. No bundlers, optimizers, deduplicators, preprocessors or postprocessors required — it outputs final CSS on its own.
- Performance. Every part is optimized for maximum efficiency, outperforming any specialized tools. It processes almost 200k classes per second. It is 5× faster and 28× more efficient than TailwindCSS v4.x. All while truly generating CSS.
- Universality. The native parser handles any source file without plugins or configuration, running in both filesystem-based and in-memory modes. Available as a standalone binary, a Rust crate, and an npm library.
- Intelligent CSS Generation. Respects the CSS cascade and applies necessary vendor prefixes. Uses your .browserslistrc to guarantee target browser support.
- Spell and Scroll Systems. Turn CSS into your personal styling language — no arbitrary class names, no hidden abstractions. Write clear property=value Spells, complete with area__, {focus} and effect: modifiers for breakpoints, selectors and pseudo-classes. Bundle them into Scrolls — named, parameterized, inheritable style modules for consistent systems at any scale.
- Color Toolkit. A powerful module compliant with CSS Color Module Level 4, enabling precise and high-performance color manipulations. Grimoire CSS also serves as a standalone color toolkit, with its color features available via a public API.
- Configuration. Grimoire CSS uses a single JSON configuration file per repository. Its format is straightforward yet robust, supporting monorepos with hundreds of projects or individual configurations — variables, scrolls, generation modes, shared and critical CSS, external files — all out of the box.
- Gradual Migration. The Transmutator converts supported class-based CSS rules to Scrolls. Compatible class names can stay in your components. Unsupported names, rules, and source-order dependencies are reported explicitly; keep those styles in CSS files connected through
shared.styleswhile migrating incrementally.
A Spell System
At the heart of Grimoire CSS lies the Spell, the foundational entity of the system. Spell takes a different approach from traditional utility classes, like those you’d find in Tailwind. While utilities in Tailwind feel like slightly enhanced Bootstrap classes, Grimoire CSS takes things to a new level. In Tailwind, you’re expected to memorize arbitrary names like rounded-md for border-radius: 0.375rem - which doesn’t even make things look rounded. And then there’s tracking-tight for letter-spacing: -0.025em. How are you supposed to know that’s related to letter spacing?
Grimoire CSS cuts through that confusion by introducing Spell - an approach that is both simple and infinitely flexible. At its core, a Spell is just a CSS declaration, written in a format everyone understands: property=value. For example, border-radius: 0.375rem in Grimoire CSS becomes border-radius=0.375rem. If you prefer something shorter, bd-rad=0.375rem works too, or even bd-rad=.375rem (yes, Grimoire CSS respects CSS's own shorthand capabilities). Unlike pre-baked utility classes, Spells follow the natural structure of CSS: property: value becomes component=target.
If you don’t know any shorthands yet, you can always write out full components (each full component directly maps to its corresponding CSS property) and then run the shorten command to convert all full components in your files (that defined in config) into their shorthand forms. Easy as it should be!
This isn't just another syntax. It’s the whole system reimagined. You’re free to write any value in the target, whether it's custom units, functions, or even complex animations. Everything CSS supports is fair game, and all you need to do is escape spaces with underscores (_). That’s it. Of course, we didn't stop at the basics. Spells also introduce optional enhancements: area, focus, and effects, which give you deeper control over media queries, pseudo-classes, attributes, and more.
-
area: Theareadefines conditions like screen size and sits at the start of your spell, separated from the rest by double underscores (__). For example,(width>=768px)__bd-rad=0.375remwill activate the rule only for screens wider than 768px. Prefer a shorthand? You can use built-in names likemd__bd-rad=0.375rem. It’s still valid CSS, but with all the magic ofSpell. -
focus: Sometimes, you need more than a class or a media query.focuslets you wrap anything - attributes, pseudo-classes, or nested selectors - inside your spell. Placed as the second part of the spell (or first if there's noarea), it’s enclosed in curly brackets. For example:{[hidden]_>_p:hover:active}color=redbecomes this CSS:}It’s not just readable - it’s intuitive. What you see is exactly what you get.
-
effects: Sometimes, you need quick pseudo-classes without the full complexity offocus. That’s whereeffectscome in. Just add pseudo-classes directly in the spell like this:hover,active:color=blue. Witheffect, you keep it compact without losing any power. Simply separate it from thecomponentandtargetwith a colon (:).
The entire Spell system is built on clarity and explicitness. There are no magical, arbitrary strings for targets like you find in other systems. And we don’t compromise on clarity for the sake of brevity. Targets are full, valid CSS values - because that’s how it should be. Components mirror actual CSS properties, but they can be shortened if you want. In this way, Grimoire CSS is both a CSS declaration and a methodology. It’s so powerful because every Spell is valid CSS - there’s no abstraction that gets in the way of what you need to achieve.
So, why call it a Spell? Because, like magic, it’s composed of multiple elements: area, focus, effect, component, and target. And each of these pieces works together to create something far greater than the sum of its parts. With Grimoire CSS, you’re not just writing styles - you’re casting spells. The name Grimoire comes from ancient magical texts. Just as those books hold the knowledge to perform spells, Grimoire CSS provides you the knowledge and tools to perform CSS magic - without relying on pre-baked solutions. You’re in full control.
Recap
- The structure of a spell follows this format:
area__{focus}component=targetorarea__effect:component=target. - Use dashes (
-) to separate words. - Use underscores (
_) to escape spaces.
Scroll: Crafting Reusable, Dynamic CSS with Infinite Flexibility
A Scroll is like a Spell, but with one crucial difference - it’s something you build from scratch. Think of it as a customized collection of styles, bundled into one reusable class. Sometimes, you need to combine multiple styles into a single class for consistency, reusability, or just to make your life easier. With Scroll, you can do just that. Combine spells, give your new creation a name, and you’ve got a Scroll ready to use across your projects.
And here's the best part: everything you love about Spells works seamlessly with Scrolls too - area, focus, effect, and even target. But there's even more: when you define a Scroll, you can introduce variables to make your styles dynamic. Just use the $ symbol, and the target becomes a placeholder, waiting for the actual value to be filled in. Want to create a button class that accepts variable values? No problem. Here’s an example:
"scrolls":
This btn scroll expects four target values, and if you pass fewer or more, Grimoire CSS will kindly let you know. The targets are applied in order, giving you incredible flexibility. But we're not done yet.
Inheritance with Scrolls: The Power of Composition
One of the most exciting aspects of Scrolls is inheritance. Yes, you can extend a Scroll with another Scroll. Combine and compose them endlessly to create complex, reusable styles. Let's take a look:
"scrolls":
In this example, danger-btn extends btn, meaning it inherits all of btn's spells plus its own. So, danger-btn.spells will look like btn.spells + danger-btn.spells, with the parent scroll's styles taking priority at the top.
But the fun doesn’t stop there - danger-btn-rnd extends both danger-btn and round. This means that danger-btn-rnd.spells equals btn.spells + danger-btn.spells + round.spells, combined in the correct order. And yes, the order matters. This layered inheritance allows you to build complex style structures effortlessly.
Why Scrolls Matter: Unlimited Possibilities
The real magic of Scrolls lies in their unlimited possibilities. You can chain styles together, extend them endlessly, and define variables as placeholders to create flexible, reusable patterns across your entire project. With Scrolls, Grimoire CSS goes far beyond being Yet Another CSS Framework. In fact, you could even recreate the entire structure of Tailwind or Bootstrap using nothing but the flexibility of Spells and Scrolls.
It’s pure, beautiful madness - without limits.
Variables and Built-in Functions: Total Control Over Styles and Sizes
Grimoire CSS allows you to define your own variables within its settings, making your styling even more dynamic and customizable. Unlike custom properties, these variables don’t compile and remain in your settings and are only compiled when used - keeping your CSS clean and efficient.
How to Use Variables
You can define any value as a variable - font sizes, colors, dimensions, anything. To reference them in your styles, just add the $ symbol before the variable name (you’ll remember this from the Scroll section). Here’s how you define and use a variable:
Defining a Variable
Using the Variable
Hero text
In this example, the hero-fs variable holds the value 42px, which is then applied to the font-size of the <h1> element. Variables in Grimoire CSS offer a simple and effective way to maintain consistency across your styles, while keeping your code flexible and DRY.
Built-in Areas: Responsive Design, Simplified
Grimoire CSS follows a mobile-first approach and comes with built-in responsive areas, including sm, md, lg, xl, and 2xl. When you define a spell with one of these areas, like md__width=100px, the spell will apply only when the screen width is equal to or greater than the specified area.
For example, md__width=100px is equivalent to this media query:
(width>=768px)__width=100px.
Of course, you’re not limited to the built-in areas. You can define your own media queries just as easily, like this:
()__
With these areas, you have full control over your responsive design, but without the hassle of constantly writing and rewriting media queries.
Adaptive Size Functions: mrs and mfs
Grimoire CSS takes responsive design even further with built-in functions like mrs (Make Responsive Size) and mfs (Make Fluid Size). These functions allow you to adapt font sizes, widths, and more based on the viewport size.
mrs: Make Responsive Size
This function dynamically adjusts the size of an element between a minimum and maximum value, depending on the viewport width. Here are the arguments:
min_size: The minimum size for the element.max_size: The maximum size for the element.min_vw: (Optional) The minimum viewport width.max_vw: (Optional) The maximum viewport width.
Example Usage of mrs
Font size of this text will dynamically change based on the screen size
In this example, the font size will automatically adjust between 12px and 36px, depending on the screen size, with fluid adjustments in between. This makes responsive design not only easier but more precise, without the need for complex calculations or multiple breakpoints.
mfs: Make Fluid Size – Creates fully fluid sizes without media queries for seamless scaling
Here are the arguments:
min_size: The minimum size for the element.max_size: The maximum size for the element.
Example Usage of mfs
Font size smoothly scales between 12px and 36px based on the viewport size.
The Power of Grimoire’s Variables and Functions
With Grimoire CSS, you don’t just write styles - you take control of them. By leveraging variables, responsive areas, and adaptive size functions, you can make your CSS dynamic, scalable, and ready for any device or screen size. It’s flexibility without the fuss, and it’s all built right in.
Predefined Scrolls and Built-In Animations: Flexibility at Your Fingertips
Grimoire CSS doesn’t just give you the tools to build powerful styles from scratch - it also comes with a set of predefined scrolls to help you get started right away. All predefined scrolls follow the same convention: they begin with the prefix g-. This makes it easy to distinguish built-in scrolls from the ones you define yourself.
Built-In Animations: Ready When You Are
Grimoire CSS comes loaded with hundreds of built-in animations (700+ at the moment). These animations are lightweight and efficient - they are only compiled if you actually use them. To trigger one, simply use its name in either the animation-name or animation CSS rule. But Grimoire CSS doesn’t stop at just applying animations; it also simplifies the process of adding associated rules.
For example, the predefined scroll g-anim allows you to apply an animation and its associated rules at the same time. Here, g- is the prefix, and anim is a short version of the spell animation. With this scroll, you can quickly inject an animation along with the necessary rules - saving time and keeping your styles clean and organized.
- back-in-down
- back-in-left
- back-in-right
- back-in-up
- back-out-down
- back-out-left
- back-out-right
- back-out-up
- bg-pan-bl
- bg-pan-bottom
- bg-pan-br
- bg-pan-left
- bg-pan-right
- bg-pan-tl
- bg-pan-top
- bg-pan-tr
- blink-1
- blink-2
- blur-out-contract
- blur-out-contract-bck
- blur-out-expand
- blur-out-expand-fwd
- bounce
- bounce-bottom
- bounce-in
- bounce-in-bck
- bounce-in-bottom
- bounce-in-down
- bounce-in-fwd
- bounce-in-left
- bounce-in-right
- bounce-in-top
- bounce-in-up
- bounce-left
- bounce-out
- bounce-out-bck
- bounce-out-bottom
- bounce-out-down
- bounce-out-fwd
- bounce-out-left
- bounce-out-right
- bounce-out-top
- bounce-out-up
- bounce-right
- bounce-top
- color-change-2x
- color-change-3x
- color-change-4x
- color-change-5x
- fade-in
- fade-in-bck
- fade-in-bl
- fade-in-bottom
- fade-in-bottom-left
- fade-in-bottom-right
- fade-in-br
- fade-in-down
- fade-in-down-big
- fade-in-fwd
- fade-in-left
- fade-in-left-big
- fade-in-right
- fade-in-right-big
- fade-in-tl
- fade-in-top
- fade-in-top-left
- fade-in-top-right
- fade-in-tr
- fade-in-up
- fade-in-up-big
- fade-out
- fade-out-bck
- fade-out-bl
- fade-out-bottom
- fade-out-bottom-left
- fade-out-bottom-right
- fade-out-br
- fade-out-down
- fade-out-down-big
- fade-out-fwd
- fade-out-left
- fade-out-left-big
- fade-out-right
- fade-out-right-big
- fade-out-tl
- fade-out-top
- fade-out-top-left
- fade-out-top-right
- fade-out-tr
- fade-out-up
- fade-out-up-big
- flash
- flicker-1
- flicker-2
- flicker-3
- flicker-4
- flicker-5
- flicker-in-1
- flicker-in-2
- flicker-out-1
- flicker-out-2
- flip
- flip-2-hor-bottom-1
- flip-2-hor-bottom-2
- flip-2-hor-bottom-bck
- flip-2-hor-bottom-fwd
- flip-2-hor-top-1
- flip-2-hor-top-2
- flip-2-hor-top-bck
- flip-2-hor-top-fwd
- flip-2-ver-left-1
- flip-2-ver-left-2
- flip-2-ver-left-bck
- flip-2-ver-left-fwd
- flip-2-ver-right-1
- flip-2-ver-right-2
- flip-2-ver-right-bck
- flip-2-ver-right-fwd
- flip-diagonal-1-bck
- flip-diagonal-1-bl
- flip-diagonal-1-fwd
- flip-diagonal-1-tr
- flip-diagonal-2-bck
- flip-diagonal-2-br
- flip-diagonal-2-fwd
- flip-diagonal-2-tl
- flip-horizontal-bck
- flip-horizontal-bottom
- flip-horizontal-fwd
- flip-horizontal-top
- flip-in-diag-1-bl
- flip-in-diag-1-tr
- flip-in-diag-2-br
- flip-in-diag-2-tl
- flip-in-hor-bottom
- flip-in-hor-top
- flip-in-ver-left
- flip-in-ver-right
- flip-in-x
- flip-in-y
- flip-out-diag-1-bl
- flip-out-diag-1-tr
- flip-out-diag-2-br
- flip-out-diag-2-tl
- flip-out-hor-bottom
- flip-out-hor-top
- flip-out-ver-left
- flip-out-ver-right
- flip-out-x
- flip-out-y
- flip-scale-2-hor-bottom
- flip-scale-2-hor-top
- flip-scale-2-ver-left
- flip-scale-2-ver-right
- flip-scale-down-diag-1
- flip-scale-down-diag-2
- flip-scale-down-hor
- flip-scale-down-ver
- flip-scale-up-diag-1
- flip-scale-up-diag-2
- flip-scale-up-hor
- flip-scale-up-ver
- flip-vertical-bck
- flip-vertical-fwd
- flip-vertical-left
- flip-vertical-right
- focus-in-contract
- focus-in-contract-bck
- focus-in-expand
- focus-in-expand-fwd
- head-shake
- heart-beat
- heartbeat
- hinge
- jack-in-the-box
- jello
- jello-diagonal-1
- jello-diagonal-2
- jello-horizontal
- jello-vertical
- kenburns-bottom
- kenburns-bottom-left
- kenburns-bottom-right
- kenburns-left
- kenburns-right
- kenburns-top
- kenburns-top-left
- kenburns-top-right
- light-speed-in-left
- light-speed-in-right
- light-speed-out-left
- light-speed-out-right
- ping
- puff-in-bl
- puff-in-bottom
- puff-in-br
- puff-in-center
- puff-in-hor
- puff-in-left
- puff-in-right
- puff-in-tl
- puff-in-top
- puff-in-tr
- puff-in-ver
- puff-out-bl
- puff-out-bottom
- puff-out-br
- puff-out-center
- puff-out-hor
- puff-out-left
- puff-out-right
- puff-out-tl
- puff-out-top
- puff-out-tr
- puff-out-ver
- pulsate-bck
- pulsate-fwd
- pulse
- roll-in
- roll-in-blurred-bottom
- roll-in-blurred-left
- roll-in-blurred-right
- roll-in-blurred-top
- roll-in-bottom
- roll-in-left
- roll-in-right
- roll-in-top
- roll-out
- roll-out-blurred-bottom
- roll-out-blurred-left
- roll-out-blurred-right
- roll-out-blurred-top
- roll-out-bottom
- roll-out-left
- roll-out-right
- roll-out-top
- rotate-90-bl-ccw
- rotate-90-bl-cw
- rotate-90-bottom-ccw
- rotate-90-bottom-cw
- rotate-90-br-ccw
- rotate-90-br-cw
- rotate-90-ccw
- rotate-90-cw
- rotate-90-horizontal-bck
- rotate-90-horizontal-fwd
- rotate-90-left-ccw
- rotate-90-left-cw
- rotate-90-right-ccw
- rotate-90-right-cw
- rotate-90-tl-ccw
- rotate-90-tl-cw
- rotate-90-top-ccw
- rotate-90-top-cw
- rotate-90-tr-ccw
- rotate-90-tr-cw
- rotate-90-vertical-bck
- rotate-90-vertical-fwd
- rotate-bl
- rotate-bottom
- rotate-br
- rotate-center
- rotate-diagonal-1
- rotate-diagonal-2
- rotate-diagonal-bl
- rotate-diagonal-br
- rotate-diagonal-tl
- rotate-diagonal-tr
- rotate-hor-bottom
- rotate-hor-center
- rotate-hor-top
- rotate-in
- rotate-in-2-bck
- rotate-in-2-bl-ccw
- rotate-in-2-bl-cw
- rotate-in-2-br-ccw
- rotate-in-2-br-cw
- rotate-in-2-ccw
- rotate-in-2-cw
- rotate-in-2-fwd
- rotate-in-2-tl-ccw
- rotate-in-2-tl-cw
- rotate-in-2-tr-ccw
- rotate-in-2-tr-cw
- rotate-in-bl
- rotate-in-bottom
- rotate-in-br
- rotate-in-center
- rotate-in-diag-1
- rotate-in-diag-2
- rotate-in-down-left
- rotate-in-down-right
- rotate-in-hor
- rotate-in-left
- rotate-in-right
- rotate-in-tl
- rotate-in-top
- rotate-in-tr
- rotate-in-up-left
- rotate-in-up-right
- rotate-in-ver
- rotate-left
- rotate-out
- rotate-out-2-bck
- rotate-out-2-bl-ccw
- rotate-out-2-bl-cw
- rotate-out-2-br-ccw
- rotate-out-2-br-cw
- rotate-out-2-ccw
- rotate-out-2-cw
- rotate-out-2-fwd
- rotate-out-2-tl-ccw
- rotate-out-2-tl-cw
- rotate-out-2-tr-ccw
- rotate-out-2-tr-cw
- rotate-out-bl
- rotate-out-bottom
- rotate-out-br
- rotate-out-center
- rotate-out-diag-1
- rotate-out-diag-2
- rotate-out-down-left
- rotate-out-down-right
- rotate-out-hor
- rotate-out-left
- rotate-out-right
- rotate-out-tl
- rotate-out-top
- rotate-out-tr
- rotate-out-up-left
- rotate-out-up-right
- rotate-out-ver
- rotate-right
- rotate-scale-down
- rotate-scale-down-diag-1
- rotate-scale-down-diag-2
- rotate-scale-down-hor
- rotate-scale-down-ver
- rotate-scale-up
- rotate-scale-up-diag-1
- rotate-scale-up-diag-2
- rotate-scale-up-hor
- rotate-scale-up-ver
- rotate-tl
- rotate-top
- rotate-tr
- rotate-vert-center
- rotate-vert-left
- rotate-vert-right
- rubber-band
- scale-down-bl
- scale-down-bottom
- scale-down-br
- scale-down-center
- scale-down-hor-center
- scale-down-hor-left
- scale-down-hor-right
- scale-down-left
- scale-down-right
- scale-down-tl
- scale-down-top
- scale-down-tr
- scale-down-ver-bottom
- scale-down-ver-center
- scale-down-ver-top
- scale-in-bl
- scale-in-bottom
- scale-in-br
- scale-in-center
- scale-in-hor-center
- scale-in-hor-left
- scale-in-hor-right
- scale-in-left
- scale-in-right
- scale-in-tl
- scale-in-top
- scale-in-tr
- scale-in-ver-bottom
- scale-in-ver-center
- scale-in-ver-top
- scale-out-bl
- scale-out-bottom
- scale-out-br
- scale-out-center
- scale-out-hor-left
- scale-out-hor-right
- scale-out-horizontal
- scale-out-left
- scale-out-right
- scale-out-tl
- scale-out-top
- scale-out-tr
- scale-out-ver-bottom
- scale-out-ver-top
- scale-out-vertical
- scale-up-bl
- scale-up-bottom
- scale-up-br
- scale-up-center
- scale-up-hor-center
- scale-up-hor-left
- scale-up-hor-right
- scale-up-left
- scale-up-right
- scale-up-tl
- scale-up-top
- scale-up-tr
- scale-up-ver-bottom
- scale-up-ver-center
- scale-up-ver-top
- shadow-drop-2-bl
- shadow-drop-2-bottom
- shadow-drop-2-br
- shadow-drop-2-center
- shadow-drop-2-left
- shadow-drop-2-lr
- shadow-drop-2-right
- shadow-drop-2-tb
- shadow-drop-2-tl
- shadow-drop-2-top
- shadow-drop-2-tr
- shadow-drop-bl
- shadow-drop-bottom
- shadow-drop-br
- shadow-drop-center
- shadow-drop-left
- shadow-drop-lr
- shadow-drop-right
- shadow-drop-tb
- shadow-drop-tl
- shadow-drop-top
- shadow-drop-tr
- shadow-inset-bl
- shadow-inset-bottom
- shadow-inset-br
- shadow-inset-center
- shadow-inset-left
- shadow-inset-lr
- shadow-inset-right
- shadow-inset-tb
- shadow-inset-tl
- shadow-inset-top
- shadow-inset-tr
- shadow-pop-bl
- shadow-pop-br
- shadow-pop-tl
- shadow-pop-tr
- shake
- shake-bl
- shake-bottom
- shake-br
- shake-horizontal
- shake-left
- shake-lr
- shake-right
- shake-tl
- shake-top
- shake-tr
- shake-vertical
- shake-x
- shake-y
- simple-fade-in
- simple-fade-out
- slide-bck-bl
- slide-bck-bottom
- slide-bck-br
- slide-bck-center
- slide-bck-left
- slide-bck-right
- slide-bck-tl
- slide-bck-top
- slide-bck-tr
- slide-bl
- slide-bottom
- slide-br
- slide-fwd-bl
- slide-fwd-bottom
- slide-fwd-br
- slide-fwd-center
- slide-fwd-left
- slide-fwd-right
- slide-fwd-tl
- slide-fwd-top
- slide-fwd-tr
- slide-in-bck-bl
- slide-in-bck-bottom
- slide-in-bck-br
- slide-in-bck-center
- slide-in-bck-left
- slide-in-bck-right
- slide-in-bck-tl
- slide-in-bck-top
- slide-in-bck-tr
- slide-in-bl
- slide-in-blurred-bl
- slide-in-blurred-bottom
- slide-in-blurred-br
- slide-in-blurred-left
- slide-in-blurred-right
- slide-in-blurred-tl
- slide-in-blurred-top
- slide-in-blurred-tr
- slide-in-bottom
- slide-in-br
- slide-in-down
- slide-in-elliptic-bottom-bck
- slide-in-elliptic-bottom-fwd
- slide-in-elliptic-left-bck
- slide-in-elliptic-left-fwd
- slide-in-elliptic-right-bck
- slide-in-elliptic-right-fwd
- slide-in-elliptic-top-bck
- slide-in-elliptic-top-fwd
- slide-in-fwd-bl
- slide-in-fwd-bottom
- slide-in-fwd-br
- slide-in-fwd-center
- slide-in-fwd-left
- slide-in-fwd-right
- slide-in-fwd-tl
- slide-in-fwd-top
- slide-in-fwd-tr
- slide-in-left
- slide-in-right
- slide-in-tl
- slide-in-top
- slide-in-tr
- slide-in-up
- slide-left
- slide-out-bck-bl
- slide-out-bck-bottom
- slide-out-bck-br
- slide-out-bck-center
- slide-out-bck-left
- slide-out-bck-right
- slide-out-bck-tl
- slide-out-bck-top
- slide-out-bck-tr
- slide-out-bl
- slide-out-blurred-bl
- slide-out-blurred-bottom
- slide-out-blurred-br
- slide-out-blurred-left
- slide-out-blurred-right
- slide-out-blurred-tl
- slide-out-blurred-top
- slide-out-blurred-tr
- slide-out-bottom
- slide-out-br
- slide-out-down
- slide-out-elliptic-bottom-bck
- slide-out-elliptic-bottom-fwd
- slide-out-elliptic-left-bck
- slide-out-elliptic-left-fwd
- slide-out-elliptic-right-bck
- slide-out-elliptic-right-fwd
- slide-out-elliptic-top-bck
- slide-out-elliptic-top-fwd
- slide-out-fwd-bl
- slide-out-fwd-bottom
- slide-out-fwd-br
- slide-out-fwd-center
- slide-out-fwd-left
- slide-out-fwd-right
- slide-out-fwd-tl
- slide-out-fwd-top
- slide-out-fwd-tr
- slide-out-left
- slide-out-right
- slide-out-tl
- slide-out-top
- slide-out-tr
- slide-out-up
- slide-right
- slide-rotate-hor-b-bck
- slide-rotate-hor-b-fwd
- slide-rotate-hor-bottom
- slide-rotate-hor-t-bck
- slide-rotate-hor-t-fwd
- slide-rotate-hor-top
- slide-rotate-ver-l-bck
- slide-rotate-ver-l-fwd
- slide-rotate-ver-left
- slide-rotate-ver-r-bck
- slide-rotate-ver-r-fwd
- slide-rotate-ver-right
- slide-tl
- slide-top
- slide-tr
- slit-in-diagonal-1
- slit-in-diagonal-2
- slit-in-horizontal
- slit-in-vertical
- slit-out-diagonal-1
- slit-out-diagonal-2
- slit-out-horizontal
- slit-out-vertical
- swing
- swing-bottom-bck
- swing-bottom-fwd
- swing-bottom-left-bck
- swing-bottom-left-fwd
- swing-bottom-right-bck
- swing-bottom-right-fwd
- swing-in-bottom-bck
- swing-in-bottom-fwd
- swing-in-left-bck
- swing-in-left-fwd
- swing-in-right-bck
- swing-in-right-fwd
- swing-in-top-bck
- swing-in-top-fwd
- swing-left-bck
- swing-left-fwd
- swing-out-bottom-bck
- swing-out-bottom-fwd
- swing-out-left-bck
- swing-out-left-fwd
- swing-out-right-bck
- swing-out-right-fwd
- swing-out-top-bck
- swing-out-top-fwd
- swing-right-bck
- swing-right-fwd
- swing-top-bck
- swing-top-fwd
- swing-top-left-bck
- swing-top-left-fwd
- swing-top-right-bck
- swing-top-right-fwd
- swirl-in-bck
- swirl-in-bl-bck
- swirl-in-bl-fwd
- swirl-in-bottom-bck
- swirl-in-bottom-fwd
- swirl-in-br-bck
- swirl-in-br-fwd
- swirl-in-fwd
- swirl-in-left-bck
- swirl-in-left-fwd
- swirl-in-right-bck
- swirl-in-right-fwd
- swirl-in-tl-bck
- swirl-in-tl-fwd
- swirl-in-top-bck
- swirl-in-top-fwd
- swirl-in-tr-bck
- swirl-in-tr-fwd
- swirl-out-bck
- swirl-out-bl-bck
- swirl-out-bl-fwd
- swirl-out-bottom-bck
- swirl-out-bottom-fwd
- swirl-out-br-bck
- swirl-out-br-fwd
- swirl-out-fwd
- swirl-out-left-bck
- swirl-out-left-fwd
- swirl-out-right-bck
- swirl-out-right-fwd
- swirl-out-tl-bck
- swirl-out-tl-fwd
- swirl-out-top-bck
- swirl-out-top-fwd
- swirl-out-tr-bck
- swirl-out-tr-fwd
- tada
- text-blur-out
- text-flicker-in-glow
- text-flicker-out-glow
- text-focus-in
- text-pop-up-bl
- text-pop-up-bottom
- text-pop-up-br
- text-pop-up-left
- text-pop-up-right
- text-pop-up-tl
- text-pop-up-top
- text-pop-up-tr
- text-shadow-drop-bl
- text-shadow-drop-bottom
- text-shadow-drop-br
- text-shadow-drop-center
- text-shadow-drop-left
- text-shadow-drop-right
- text-shadow-drop-tl
- text-shadow-drop-top
- text-shadow-drop-tr
- text-shadow-pop-bl
- text-shadow-pop-bottom
- text-shadow-pop-br
- text-shadow-pop-left
- text-shadow-pop-right
- text-shadow-pop-tl
- text-shadow-pop-top
- text-shadow-pop-tr
- tracking-in-contract
- tracking-in-contract-bck
- tracking-in-contract-bck-bottom
- tracking-in-contract-bck-top
- tracking-in-expand
- tracking-in-expand-fwd
- tracking-in-expand-fwd-bottom
- tracking-in-expand-fwd-top
- tracking-out-contract
- tracking-out-contract-bck
- tracking-out-contract-bck-bottom
- tracking-out-contract-bck-top
- tracking-out-expand
- tracking-out-expand-fwd
- tracking-out-expand-fwd-bottom
- tracking-out-expand-fwd-top
- vibrate-1
- vibrate-2
- vibrate-3
- wobble
- wobble-hor-bottom
- wobble-hor-top
- wobble-ver-left
- wobble-ver-right
- zoom-in
- zoom-in-down
- zoom-in-left
- zoom-in-right
- zoom-in-up
- zoom-out
- zoom-out-down
- zoom-out-left
- zoom-out-right
- zoom-out-up
Create Your Own Animations
Even though Grimoire CSS comes packed with animations, it also gives you the power to add your own, seamlessly integrating them into your projects. It’s as simple as creating a new subfolder called animation inside the grimoire folder, then adding your custom CSS file using the format <name-of-animation>.css.
Within that file, you define your animation using @keyframes, along with any custom styles. You can also use the class placeholder GRIMOIRE_CSS_ANIMATION to add specific styles tied to the animation itself. Let’s take a look at an example with a custom pulse animation:
{
from }
50% }
to }
}
}
In this example, you’ve defined the pulse animation and set it up with ease using the GRIMOIRE_CSS_ANIMATION placeholder. Once this file is in your project, you can invoke the pulse animation as easily as any built-in animation, giving you complete control over custom animations.
External Scrolls & Variables
In addition to defining scrolls and variables within grimoire.config.json, Grimoire CSS allows you to extend your configuration with external JSON files for scrolls and variables. These external JSON files follow the same structure as their corresponding properties in the config file. These files should be stored alongside your main configuration file.
Before generating CSS, Grimoire CSS checks for any external scrolls or variables and merges them into the main config (with the main config taking priority, so external scrolls/variables won't override your primary configuration settings). This adds flexibility, scalability, and convenience to your workflow.
This feature enables sharing your scrolls/spells independently from your main configuration, as well as using those created by others. For example, you can use the Tailwind CSS implementation via external scrolls. More information about where to share and find scrolls, variables, or complete configurations will be detailed below.
Language-Agnostic Parser: Extracting Spells from Any File, Any Format
Grimoire CSS isn’t just tied to traditional CSS, JavaScript, or HTML files. The beauty of its language-agnostic parser is that it can parse spells from any file or extension. Whether you’re working with .html, .tsx, .mdx, or something else entirely, it can handle it.
This means you’re not limited by file types or formats - you define the inputPaths, and Grimoire takes care of the rest. Whether your project is built with React, Vue, or something entirely different, it seamlessly integrates and extracts the styles you need.
Spells in Plain Text with Template Syntax
If you want to use spells outside the traditional class or className attributes, Grimoire CSS provides a clever solution with its template syntax: g!<spell>;. This syntax lets you wrap your spell in a template, enabling the parser to collect spells from any text-based content.
Template syntax works for scrolls too, by the same rules as spells (including prefixes and modifiers). For example: g!complex-card=120px_red_100px;.
Let’s say you have both a classic spell and a templated spell that are essentially the same. Don’t worry - Grimoire CSS is smart enough to combine them into one, as long as it doesn’t affect the CSS cascade. The result? Clean, efficient CSS output like this:
}
Template syntax also supports multiple spells in a single template using the & symbol as a spells separator: g!color=violet&display=flex;. This enables CSS-in-JS–like scenarios in absolutely any files.
This flexibility means you can integrate Grimoire CSS in non-traditional environments, using it across various file types and even in plain text. It's not just tied to the web - it’s ready for any project, anywhere.
CSS Optimization: Minification, Vendor Prefixes, and Deduplication - All with CSS Cascade in Mind
Grimoire CSS doesn’t just help you manage your styles - it ensures that only the CSS you actually need is generated. No duplicates, no wasted space. Whether it’s shared across multiple projects or inlined for critical loading, Grimoire makes sure your CSS is lean, efficient, and optimized for performance.
Grimoire CSS takes optimization seriously. It generates only the CSS that's actually used, and it monitors for duplicates right from the start, ensuring no unnecessary styles sneak through. This happens at the very early stages of generation, so by the time the process finishes, you've got a lean, clean stylesheet.
But it doesn't stop there. Just take a look:
- Minification: It shrinks your CSS without sacrificing readability or maintainability.
- Vendor Prefixes: Automatically adds necessary prefixes for cross-browser compatibility based on your browserslist configuration:
- Uses
.browserslistrcif it exists in your project - Falls back to 'defaults' if no configuration is found
- Supports custom browserslist configuration in in-memory mode
- Uses
- Deduplication: Duplicate CSS? Not here. Grimoire keeps a close watch and ensures that only the needed CSS is generated.
- Modern CSS Features: Automatically transforms modern CSS features for better browser compatibility
All of this happens while preserving the CSS cascade - no unintentional overwrites, no broken styles. Just clean, optimized CSS that's ready for any environment.
Professional-Grade Color Toolkit
Grimoire CSS introduces a comprehensive suite of built-in color manipulation functions, compliant with the CSS Color Module Level 4 specification. These functions enable precise and dynamic color transformations:
g-grayscale(color): Converts a color to grayscale by setting its saturation to 0%.g-complement(color): Generates the complementary color by adding 180° to the hue.g-invert(color_weight?): Inverts a color. Optionally, theweightparameter controls the intensity of the inversion (default: 100%).g-mix(color1_color2_weight): Blends two colors based on a specified weight (0% - 100%).g-adjust-hue(color_degrees): Rotates the hue of a color by a specified number of degrees (positive or negative).g-adjust-color(color_red?_green?_blue?_hue-val?_sat-val?_light-val?_alpha-val?): Adjusts individual components of a color using delta values for RGB or HSL channels.g-change-color(color_red?_green?_blue?_hue-val?_sat-val?_light-val?_alpha-val?): Sets absolute values for RGB or HSL components.g-scale-color(color_red?_green?_blue?_sat-val?_light-val?_alpha-val?): Scales RGB or HSL components by percentage values (positive to increase, negative to decrease).g-rgba(color_alpha): Updates the alpha (opacity) of a color.g-lighten(color_amount): Increases the lightness of a color by a specified percentage.g-darken(color_amount): Decreases the lightness of a color by a specified percentage.g-saturate(color_amount): Increases the saturation of a color by a specified percentage.g-desaturate(color_amount): Decreases the saturation of a color by a specified percentage.g-opacify(color_amount)(Alias:g-fade-in): Increases the opacity of a color by a specified amount.g-transparentize(color_amount)(Alias:g-fade-out): Decreases the opacity of a color by a specified amount.
Example Usage
Usage Rules:
- All arguments are positional, and any optional arguments can be omitted if they are not being changed.
- Do not include
%,deg, or other units in the values - Grimoire handles these internally.
Grayscale Red Background
Complementary Green Background
Fully Inverted Background
Partially Inverted Background
Purple Background
Hue Adjusted Background
Adjust Blue Component
Adjust Blue and Saturation
Set Red and Green Components
Set Hue Only
Scale Red Up, Green Down
Scale Saturation Up
Half Transparent Background
Lightened Background
Darkened Background
More Saturated Background
Less Saturated Background
More Opaque Background
More Transparent Background
These functions provide developers with an extensive toolkit for creating vibrant, dynamic, and flexible styles with ease.
Projects
In Grimoire CSS, managing your projects is as flexible as the spells themselves. You define exactly which files need to be parsed (inputPaths, supporting glob patterns) and specify where the built CSS should go (outputDirPath).
You also have two powerful options for compiling your CSS:
- Single Output File: Where all parsed spells from various files are compiled into a single CSS file.
- Individual Output Files: Where each input file has its own corresponding CSS file.
For single output mode, you’ll just need to define the name of the final CSS file with singleOutputFileName. The flexibility here allows you to control the output method depending on your project’s needs. Every project configuration contains a name property and can include as many projects as you want. Whether you’re building a single-page application (SPA) or managing multiple projects, Grimoire CSS has you covered.
In essence, the projects section of your config is a list of projects, each with its own unique input and output settings. Here’s how that might look:
"projects":
- In the first and third projects, we use the single output mode, where all the spells are compiled into one file. This is ideal for SPAs or projects that need consolidated CSS for optimization.
- In the second project, a static site, each page will have its own CSS file. This approach is perfect for projects where you want isolated styles for different parts of the website, ensuring that each page only loads what it needs.
Projects on Your Terms
Grimoire CSS gives you full control over how you manage and compile your styles. You can configure projects for different output strategies depending on whether you're building large, single-page applications or static sites with multiple pages. The flexibility to switch between single or multiple output files means you’re never locked into one approach. Grimoire adapts to your needs, not the other way around.
Locking
Grimoire CSS supports a locking mechanism for efficient builds. By enabling the lock option in grimoire.config.json, you can automatically track and clean up outdated built files
Shared and Critical CSS: Optimizing Your Styles for Maximum Efficiency
Grimoire CSS makes it easy to define shared and critical CSS alongside your project-specific styles, allowing you to optimize how styles are applied across your entire application.
Shared CSS: One File, Multiple Uses
Shared CSS is exactly what it sounds like - a set of styles that you can build into a separate file and reuse across multiple projects or pages in your application. By defining shared styles, you ensure consistency and reduce repetition, improving performance and maintainability.
Critical CSS: Inline for Faster Rendering
Critical CSS goes a step further. It automatically inlines essential styles directly into your HTML files, ensuring that key styles are loaded instantly. And here’s the clever part: if some spells are already used in your components or files, Grimoire won’t regenerate them - because they’re now part of your critical CSS. No duplicates, no unnecessary bloat - just efficient, fast-loading styles.
How It Works
Both the shared and critical sections of the config are similar in structure. Each has:
styles: An optional list of styles that are used in the shared or critical configuration. You can include any spells, scrolls, or even paths to existing CSS files. Grimoire will extract and optimize the content during compilation.cssCustomProperties: An optional list of custom CSS properties, which gives you the flexibility to define your own properties and pair them with specific elements or themes.
For shared CSS, you’ll define an outputPath - the file where your shared styles will be stored. For critical CSS, you’ll define fileToInlinePaths - a list of HTML files (or glob patterns) where these essential styles should be inlined.
Let’s take a look at some examples:
Defining Custom Properties
In the cssCustomProperties section, you can define custom properties and their key-value pairs for any DOM elements in your app. Here are the key parts of this configuration:
element: The optional DOM element associated with the CSS variable (e.g.,tag,class,id, or even:root).dataParam: The parameter name used in your CSS configuration.dataValue: The corresponding value for that parameter.cssVariables: A set of CSS variables and their values that will be applied to the element.
Here’s how this might look in JSON:
"cssCustomProperties":
This structure allows you to define theme-specific variables, making it easier to maintain consistency across your application.
Real-World Example
Here’s a complete example of how you might configure shared and critical CSS in Grimoire:
"shared": ,
"critical":
In this example:
- Shared CSS includes a simple style (
font-size=20px) and outputs toshared.css. - Critical CSS will be inlined into all HTML files under the
aboutandblogdirectories, ensuring essential styles likereset.css, padding, colors, and animations load immediately.
Performance By Design: Built for Speed and Efficiency
Grimoire CSS achieves exceptional performance through architectural decisions, algorithmic optimizations, and efficient implementation in Rust. The system is built from the ground up with performance as a core principle:
- Single-Pass Processing: Processing styles in a single efficient pass
- Smart Memory Management: Careful memory handling and efficient data structures minimize resource usage
- Optimized File I/O: Reduced system calls and efficient file handling
- Rust Implementation: Taking advantage of zero-cost abstractions and predictable performance
Grimoire CSS isn't just fast—it's blazingly efficient:
- Class Processing Speed: Processes an incredible ~200,000 classes per second
- Memory Efficiency: Handles ~4,000 classes per MB of memory
- Output Optimization: Generates optimized CSS with minimum overhead
Remember that Grimoire CSS is a complete CSS engine that goes far beyond simple class collection and CSS generation. It handles parsing, optimization, vendor prefixing, project management, and provides powerful features like variables, functions, animations, and component composition—all while maintaining this exceptional performance profile.
Benchmark
Grimoire CSS is lightning-fast and highly efficient. While its absolute performance is unquestionable, side-by-side comparisons often offer better perspective. This benchmark is designed to compare Grimoire CSS and Tailwind CSS by accurately measuring build time, memory usage, CPU load, and output file size.
Overview
The benchmark creates a series of standardized test projects, each containing a large number of HTML files with utility classes for both Grimoire CSS and Tailwind CSS. Then each framework is run to process these projects, and various performance metrics are recorded and analyzed.
Measured Metrics
- Build Time — total time required to process all projects
- Class Processing Speed — number of processed classes per second
- Memory Usage — peak and average memory consumption
- Memory Efficiency — number of processed classes per MB of used memory
- I/O Operations — volume of data read and written
- Output File Size — total size of generated CSS files
Results
When compared to the latest version of Tailwind CSS (v4.x) processing the same workload of 400,000+ classes across 100,000 files, Grimoire CSS demonstrates significant advantages:
| Metric | Grimoire CSS | Tailwind CSS | Difference |
|---|---|---|---|
| Build Time | 2.10s | 10.58s | 5.0x faster |
| Peak Memory Usage | 111.2 MB | 344.97 MB | 3.1x less memory |
| Average Memory Usage | 45.76 MB | 182.31 MB | 4.0x less memory |
| CPU User Time | 755.11ms | 7.77s | 10.3x less |
| CPU System Time | 1.33s | 60.89s | 45.7x less |
| Class Processing Speed | 190,684 cls/s | 37,824 cls/s | 5.0x faster |
| Memory Efficiency | 3,597 cls/MB | 1,160 cls/MB | 3.1x more efficient |
| Output Size | 5.05 MB | 5.66 MB | 1.1x smaller |
These performance advantages translate into:
- Dramatically improved development experience, even on resource-limited machines.
- Faster CI/CD pipelines and reduced cloud infrastructure costs.
- Efficient scaling for projects of any size.
- Reduced energy consumption for more sustainable development.
A Streamlined CLI with a Strict and Straightforward API
Grimoire CSS comes with a minimal but powerful CLI (Command Line Interface) that’s designed for simplicity and efficiency. Whether you’re integrating it into your build process or running it manually, the CLI gets the job done without unnecessary complexity.
There are only 5 commands you need to know:
init: Initializes your Grimoire CSS configuration, either by loading an existing config or generating a new one if none is found. This is your starting point.build: Kicks off the build process, parsing all your input files and generating the compiled CSS. If you haven’t already runinit, thebuildcommand will handle that for you automatically.shorten: Automatically converts all full-length component names in your spells (as defined in your config) to their corresponding shorthand forms. This helps keep your code concise and consistent. Run this command to refactor your files, making your spell syntax as brief as possible without losing clarity or functionality.transmute: Converts existing CSS content or root-relative files into deterministic external Scroll JSON using the same canonical API available to Rust and MCP clients.fi: Provides machine-readable project inspection and analysis, including spell explanations, config summaries, indexes, lint and dry reports, references, statistics, variables, and Scrolls.
Optional parallel project builds
If your config defines multiple independent projects (multiple output files), Grimoire CSS can build them in parallel.
- Enable by setting the
GRIMOIRE_CSS_JOBSenvironment variable to a positive integer (e.g.4). - Default is
1(fully sequential; same behavior as before). - Values are capped to the machine’s available parallelism.
- Higher values can reduce wall-clock build time, but may increase peak memory usage due to multiple optimizations running simultaneously.
Example:
GRIMOIRE_CSS_JOBS=4
Grimoire CSS’s CLI is built for developers who want power without bloat. It’s direct, no-nonsense, and integrates smoothly into any project or bundler.
Here’s a refined version of the remaining parts, keeping the technical depth and making them more engaging and polished:
Easy Migration with Transmutator
The canonical Transmutator is built into Grimoire CSS. It is available through the Rust API, the main CLI and the MCP server without installing another binary.
- Convert inline CSS:
grimoire_css transmute --content '.button { color: red; }'. - Convert files or globs:
grimoire_css transmute --paths 'src/**/*.css'. - Add
--with-onelinerwhen the JSON preview should include oneliners. - Add
--output <path>to write JSON; otherwise machine-readable JSON is printed to stdout.
The typed Rust entrypoints are transmutator::transmute_css and
transmutator::transmute_paths. Both return JSON-compatible data conforming to
the external Scrolls convention.
Migration supports selectors beginning with a class, including compound classes,
descendants, child selectors and pseudo selectors, plus media queries and nested
media queries. Other at-rules (such as @layer, @supports, @keyframes and
@import) and selectors without a leading class are rejected with an error;
the tool does not silently produce a partial migration. Split unsupported rules
out of framework-generated CSS before converting the supported rules.
The leading class must be usable as a plain Scroll name. Rename incompatible
classes such as a:b, a__b or 123 before migration. Literal underscores in
selector suffixes and values are preserved; duplicate declarations retain their
last cascade position within each Scroll.
If different Scrolls may depend on their relative CSS order, migration rejects
the complete input and identifies the conflicting selectors and declarations.
The check is conservative about shorthand/logical properties and selector/media
overlap. Keep order-dependent CSS in an original file connected through
shared.styles, and link the shared output stylesheet at the intended position.
Ordinary Scroll ordering is unchanged. The check covers the submitted CSS,
not its order relative to other stylesheets or existing project Scrolls.
File migration rejects relative asset URLs because Scrolls do not retain the
source stylesheet directory. Use absolute or root-relative URLs before migration;
local url(#fragment) references remain supported. Inline input has no source
base, so its relative URLs are interpreted at the eventual output location.
Unicode whitespace and escaped whitespace inside CSS identifiers are preserved.
Literal $ characters and empty custom properties are preserved. CSS text such
as mfs(...), mrs(...) and g-invert(...) is not evaluated as Grimoire
functions during migration. Animation references retain their names without
importing Grimoire keyframes; keep the original keyframe stylesheet connected.
Standard property names are normalized to lowercase; custom-property names
retain their case. Names that cannot be represented as Spell components, such
as --foo\=bar, --foo__bar or --цвет, are rejected before writing.
A CSS property that would invoke a Grimoire abbreviation, g-anim, or a Scroll
with the same name is rejected rather than compiled with a different meaning.
Rename conflicting Scrolls or keep unsupported CSS in shared.styles.
Authored Grimoire variables, functions, abbreviations and breakpoints keep their
normal behavior.
For example, .button { color: red; } produces:
The separately hosted Web UI is not part of this crate or the MCP server.
Usage and Distribution
Grimoire CSS is built to integrate seamlessly into a wide range of ecosystems. It supports both filesystem-based and in-memory operations, making it perfect for traditional web development and dynamic runtime environments. It's distributed in three ways to give you maximum flexibility:
- Single Executable Application: A standalone binary for those who prefer a direct, no-nonsense approach.
- NPM Library: A Node.js-compatible interface, perfect for JavaScript and web developers.
- Rust Crate: For developers building in Rust or those who want to integrate Grimoire CSS at the system level.
Working Modes
Grimoire CSS offers two primary modes of operation:
-
Filesystem Mode (Traditional):
- Works with files on disk
- Reads input files and writes CSS output to specified locations
- Perfect for build-time CSS generation
- Uses the standard configuration file approach
-
In-Memory Mode:
- Processes CSS entirely in memory
- No filesystem operations required
- Ideal for runtime CSS generation or serverless environments
- Accepts configuration and content directly through API
- Returns compiled CSS without writing to disk
Example of using In-Memory mode in Rust:
use ;
let config = ConfigInMemory ;
let result = start_in_memory?;
// result contains Vec<CompiledCssInMemory> with your generated CSS
The core of Grimoire CSS is architected entirely in Rust, ensuring top-notch performance and scalability. The main repository compiles both into a standalone executable (SEA) and a Rust crate, meaning you can use it in different environments with ease.
The grimoire-css-js takes the core crate and wraps it into a Node.js-compatible interface, which is then compiled into an npm package. Whether you’re working with Rust, Node.js, or need a direct CLI, Grimoire CSS is ready to integrate into your workflow and bring powerful CSS management wherever you need it.
For the best experience and access to online playground and transmutator (aka Desk), please visit the Grimoire CSS site. The documentation is the same in both places.
Installation
Rust crate:
If you’re using Rust, simply add Grimoire CSS to your Cargo.toml, and follow the link for documentation about crate: docs.rs.
or
Single Executable Application (SEA):
- Download the binary for your operating system from the releases page.
- Add the binary to your system’s $PATH (optional for easier usage).
NPM Library:
Once installed, you can run the following commands:
Initialize a Grimoire CSS config in your project:
or if you are using NPM library:
Build your CSS using the Grimoire CSS config:
or if you are using NPM library:
MCP Server
The optional grimoire_css_mcp executable exposes 19 project tools and four
resources over local stdio, using MCP revision
2025-11-25.
Installation and connection
You need an MCP client that supports local stdio servers and the
grimoire_css_mcp executable. The executable includes the CSS engine; it does
not require a separate grimoire_css CLI, Node.js, an NPM package, or a hosted
service. Ordinary CSS builds can continue without MCP.
Choose one installation method:
- Release download, after publication: select the asset for your operating
system and CPU from the v1.9.0 release.
On macOS/Linux, grant the downloaded file execute permission with
chmod +x /absolute/path/to/downloaded-binary. Use that file's actual name in the client configuration, or rename it togrimoire_css_mcp. - Cargo, after publication: requires Rust 1.93.0 or newer. Run
cargo install grimoire_css --version 1.9.0 --locked --features mcp --bin grimoire_css_mcp. The executable is placed in Cargo's installationbindirectory, normally~/.cargo/bin(%USERPROFILE%\.cargo\binon Windows). - This checkout, including before publication: requires Rust 1.93.0 or newer. Build from the repository root:
The local build produces target/release/grimoire_css_mcp (.exe on Windows).
Alternatively, install this checkout into Cargo's bin directory with
cargo install --path . --locked --features mcp --bin grimoire_css_mcp.
Release asset names are:
| Platform | Asset |
|---|---|
| Linux x64 | grimoire_css_mcp-linux-x64 |
| macOS Intel | grimoire_css_mcp-darwin-x64 |
| macOS Apple Silicon | grimoire_css_mcp-darwin-arm64 |
| Windows x64 | grimoire_css_mcp-win32-x64.exe |
Configure your client to launch the executable with an absolute project root.
Clients that accept an mcpServers JSON configuration can use the following;
other clients expose equivalent command and argument fields in their settings:
On Windows, include .exe and escape backslashes in JSON, for example
"command": "C:\\Tools\\grimoire_css_mcp.exe". The root must be the project
directory, not the executable's directory or the grimoire/config subdirectory.
Restart or reload the MCP connection after changing its configuration. The
client starts the process automatically; no separate terminal process, network
port, or Grimoire API key is needed.
The command uses newline-delimited JSON-RPC over stdio. It writes only MCP messages to stdout. The tool schemas contain no root override, so the agent cannot switch projects after launch.
Relative configuration paths are resolved against the selected project root, independently of the launcher's working directory. This includes project input globs, shared CSS output and source files, and critical CSS source and target files. Absolute paths retain their usual meaning. The same path resolution is used by the CLI and public Rust APIs; the server does not change process cwd.
For a new project, the agent can read grimoire://documentation and
grimoire://config-schema, call grimoire_init, edit the generated standard
configuration with its normal workspace tools, validate it through the MCP
analysis tools, and call the existing grimoire_build operation.
If configuration loading rejects cyclic Scroll inheritance, grimoire_init,
grimoire_build, and grimoire_shorten return a tool error and preserve the
configuration file byte for byte, matching the CLI and public Rust commands.
The server remains available for subsequent requests.
First session
- Ask the agent to read the component catalog and project configuration with
grimoire_config_summary. On a new project, ask it to initialize Grimoire CSS withgrimoire_init, then edit the generated configuration for your inputs and outputs using its workspace tools. - Ask it to explain a proposed Spell with
grimoire_explain, or validate a list withgrimoire_validate_spells. For example, the latter accepts{"tokens":["display=flex","padding=16px"]}. - After config changes, run
grimoire_validate_config. When you want to verify and build the project, rungrimoire_check_project; it writes build outputs. - For migration, preview with
grimoire_transmute_css, then explicitly requestgrimoire_import_cssto install the generated Scrolls. The source classes must be present in configured input files to produce CSS in the build.
An import request for a supported rule can use:
This creates grimoire/config/grimoire.buttons.scrolls.json after validation,
then checks and builds the project. Existing imports require explicit
"replace": true. Inspect structuredContent.data.valid, not only the absence
of a protocol error. Domain errors use isError: true with
structuredContent.error; a completed validation can return valid: false.
You can ask in natural language: “Use Grimoire CSS MCP to inspect my config, validate the proposed Spells, and build the project.” The agent makes the tool calls; you do not need to send JSON-RPC messages manually.
Troubleshooting
- Executable not found: use an absolute
commandpath. A desktop client's PATH may differ from your terminal's PATH. Include.exeon Windows. - Permission denied or incompatible executable: check execute permission on macOS/Linux and choose the asset matching your OS and CPU.
- The process appears idle in a terminal: this is expected for stdio. It waits for MCP requests; let your client launch and communicate with it.
- Missing configuration: verify
--rootand initialize that project. The standard config lives at<root>/grimoire/config/grimoire.config.json. - Empty build output: check configured
inputPathsand that your HTML/source files contain the Spell or Scroll class. Installing a Scroll definition alone does not add its class to component markup. - Import rejected: read the conversion or validation diagnostic and the migration limits. Unsupported input is not partially imported.
Validation and output
The initialize instructions and grimoire://primer require agents to:
- validate every proposed spell with
grimoire_validate_spells; - validate every created or modified config with
grimoire_validate_config; - run
grimoire_check_projectafter project changes; - avoid claiming completion unless the relevant report has
valid: true.
grimoire_check_project performs schema and engine config validation, checks
all indexed project spells, requires a clean lint result, and invokes the real
filesystem build. It can therefore write the configured build outputs.
The resulting guarantees are deliberately precise:
grimoire_validate_spells.validmeans every supplied token was accepted and compiled by the real project-aware engine;grimoire_validate_config.validmeans the main config and every discovered external Scroll/variable file match the official JSON Schema and load through the real config API;grimoire_check_project.validmeans config and indexed spells are valid, lint has no errors or warnings, and the real build succeeded.grimoire_transmute_css.validmeans the canonical CSS conversion completed and every generated spell was accepted by the current project-aware engine.grimoire_import_css.validadditionally means the external scroll file was installed and the complete project check passed. Failed verification restores the import file; generated build outputs follow normal build semantics.
These checks verify engine acceptance and build success; they do not establish visual equivalence to the original stylesheet or a design.
Resources
| Resource | Content |
|---|---|
grimoire://primer |
Grimoire syntax and tool usage guide for agents |
grimoire://components |
CSS component names and abbreviations |
grimoire://config-schema |
Project configuration JSON Schema |
grimoire://documentation |
This README, bundled with the executable |
Tools
| Tool | Operation | Arguments |
|---|---|---|
grimoire_explain |
Expand a Spell or Scroll and compile its CSS | token |
grimoire_config_summary |
Read project configuration | none |
grimoire_index |
Index project Spells and Scrolls | optional positive top |
grimoire_lint |
Report project errors and warnings | none |
grimoire_dry |
Find repeated Spell groups | optional positive min_support and min_items |
grimoire_list_variables |
List Grimoire variables | none |
grimoire_list_scrolls |
List Scroll names | none |
grimoire_refs |
Find references of a specified kind | kind, query |
grimoire_stats_spells |
Count Spell usage | optional positive top |
grimoire_refs_auto |
Find references by variable, Scroll or Spell name | query |
grimoire_stats |
Report usage statistics | optional group, token, top |
grimoire_validate_config |
Validate schemas and load the configuration | none |
grimoire_validate_spells |
Parse and compile proposed tokens | tokens |
grimoire_check_project |
Validate, lint and build the project | none |
grimoire_transmute_css |
Preview CSS conversion and validate generated Spells | content, optional with_oneliner |
grimoire_import_css |
Import CSS as Scrolls, then check and build the project | exactly one of content/paths, import_name, optional replace/with_oneliner |
grimoire_init |
Initialize project configuration | none |
grimoire_build |
Build configured CSS outputs | optional force_version_update |
grimoire_shorten |
Rewrite source files with shortened Spells | none |
grimoire_init, grimoire_build, grimoire_shorten, grimoire_check_project
and grimoire_import_css can write files. Other tools provide read-only analysis.
Import rollback covers the imported Scroll file; generated build outputs are not
transactional. See CSS migration for supported
input, cascade checks and the shared.styles fallback.
The Arcane Circle
Grimoire CSS gives you the freedom to create styles that work exactly the way you want them to - no rigid rules or constraints. Whether you’re crafting dynamic interactions or fine-tuning layouts, Grimoire adapts to your needs, making each step straightforward and rewarding.
So, come join us. Share your work, exchange your thoughts, and help us keep pushing CSS to be more flexible and enjoyable.
The Arcane Circle, or simply the Circle, is a place where you can share your configs, scrolls, variables, components, or UI kits. It’s where you can catch the latest news, follow development, influence the project, and interact with other members of the Circle.
The Circle is currently under development.
The First Member
Hello! My name is Dmitrii Shatokhin, and I am the creator of Grimoire CSS. I invented the Spell concept and all the other ideas behind the project. Grimoire CSS is the result of countless hours of work and dedication, and I am proud to have made it open source.
But this is just the beginning. I am committed to the ongoing development of Grimoire CSS and its entire ecosystem - there are many plans and tasks ahead, which I strive to manage transparently on GitHub. My vision is to grow the Arcane Circle community and bring all these ideas to life.
I would be truly grateful for any support you can offer - whether it’s starring the project on GitHub, leaving feedback, recommending it to others, contributing to its development, helping to promote Grimoire CSS, or even sponsoring the project or my work.
Thank you!
Release Information
Release Notes
For detailed information about each release, including new features, improvements, and breaking changes, see our Release Notes.
Changelog
A concise list of version-specific changes can be found in our Changelog.
Craft Your Code, Cast Your Spells