In my last post, I talked about why I started building Juice—mainly out of frustration with class-heavy UI code and how messy things can get as projects scale.
If you haven’t read that yet, here it is:
👉 https://dev.to/stinklewinks/i-got-tired-of-class-heavy-ui-code-so-i-started-building-juice-4ocg
This post is about what came next.
Not just what Juice is, but what I’m actually trying to build with it.
⚠️ The Problem Isn’t Just Classes
After stepping back, I realized something:
The issue wasn’t just Tailwind-style class overload.
It was bigger than that.
Most UI systems today:
- Push styling into long class strings
- Mix structure, intent, and design into one place
- Become harder to read as complexity increases
- Don’t feel like they scale conceptually
You can make them work—but you’re constantly managing them.
And that’s where things started to feel off to me.
💡 What If UI Was More Declarative?
Instead of this:
<div class="flex items-center justify-between p-4 bg-white rounded-lg shadow-md">
What if you could express intent more directly?
<div row centered gap="1" padding="4rem" card>
Not just shorter—but more meaningful.
That’s the direction Juice is going.
🧃 The Core Idea Behind Juice
Juice is built around one simple idea:
UI should describe intent, not implementation.
Instead of:
- Writing long class lists
- Remembering utility combinations
- Repeating patterns across files
You define:
- Layout
- Spacing
- Surfaces
- Behavior
Using attributes that map to a design system.
🧱 Attributes Over Classes
Classes are flexible, but they come with trade-offs:
- No structure
- Easy to overuse
- Hard to standardize across teams
Attributes, on the other hand:
- Encourage consistency
- Create a natural design language
- Are easier to read at a glance
Example:
<div grid="2" gap="4">
<div card>A</div>
<div card>B</div>
</div>
You immediately understand:
- Layout: grid with 2 columns
- Spacing: gap of 4
- Surface: reusable card style
No mental decoding required.
🎯 Not Just Styling — A System
Juice isn’t just about styling elements.
It’s about creating a cohesive UI system that includes:
- 🎨 Design tokens (colors, spacing, typography)
- 🧩 Components (cards, nav, sections)
- ⚡ Interactions (animations, states)
- 📱 Responsiveness (built-in, not bolted on)
The goal is to make UI:
- Faster to build
- Easier to read
- More consistent
⚡ Where This Is Going
Right now, Juice is still early.
But the direction is clear:
- A fully expressive attribute-based UI system
- Designed to work standalone or alongside other frameworks
- Built to integrate directly into WebEngine
And eventually:
A system where developers and non-developers can both build interfaces without fighting the code.
🧠 What I’m Exploring Next
Some of the things I’m actively thinking through:
- How far can attributes go before they become noisy?
- How should responsiveness be handled without clutter?
- What’s the right balance between flexibility and structure?
- How can this integrate with things like WebGL and dynamic UI?
🚀 Why This Matters (To Me)
At the end of the day, this isn’t just about CSS.
It’s about reducing friction when building ideas.
Because when UI becomes easier to reason about:
- You build faster
- You experiment more
- You ship more
And that’s the real goal.
🤝 Let’s Build This Together
This is still evolving, and I’m learning as I go.
If you’ve run into similar frustrations—or have thoughts on this approach—I’d love to hear them.
Repo here:
👉 https://github.com/citrusworx/webengine/tree/master/libraries/juice
Next up, I’ll probably dive deeper into:
- How Juice handles responsiveness
- Or how it compares directly to existing frameworks in real-world use
Appreciate you reading 🙏
Top comments (0)