I Got Tired of Class-Heavy UI Code — So I Kept Going (Juice Part 3)
In Part 1, I talked about the frustration. In Part 2, I showed the direction. Now in Part 3, we’re going deeper into what Juice is actually becoming. Because at this point… This isn’t just about styling anymore. Classes were just the symptom. The real problem? We’ve been writing UI in a way that separates what something is from how it behaves. This doesn’t describe intent. It describes implementation. With Juice, I’m not trying to replace Tailwind. I’m trying to replace how we think about UI. Now we’re talking. layout → structure padding → spacing surface → semantic background text → semantic color radius → shape elevation → depth This is no longer a pile of utilities. This is a language. Here’s the shift that changed everything for me: Juice isn’t a CSS library. It’s a UI protocol. That means: Defined attributes Predictable behavior Shared contracts across components Extensible rules Sound familiar? That’s because it mirrors how we already think about: APIs Schemas Infrastructure So why doesn’t UI get the same treatment? We have: Frameworks (React, Vue, etc.) Styling systems (Tailwind, CSS Modules) Component libraries (MUI, Chakra) But we don’t have a standardized way to describe UI itself. Juice is aiming to sit right there: [ App Logic ] ↓ [ UI Description Layer (Juice) ] ↓ [ Render Layer (DOM / Canvas / WebGL) ] That middle layer? That’s the gap. Let’s be clear: This isn’t about: “attributes are better than classes” That’s shallow. The real win is: Attributes let you define rules and contracts more naturally. Example: Now imagine: variant ties into your design system size scales consistently everywhere state drives behavior + visuals This becomes a shared interface, not just styling. One of the biggest issues with utility-first systems: They scale visually but not conceptually. You end up with: Multiply that across an app… Now try to refactor it. Good luck. With Juice: Now: Behavior is abstracted Patterns are reusable Refactoring becomes changing rules, not hunting classes Once UI becomes declarative like this… You unlock things like: Everything adapts. No class overrides. Now your UI can be generated from: JSON YAML APIs AI (👀) Because it's structured. Same UI definition could target: DOM Canvas WebGL Native Because Juice isn’t tied to one renderer. This is where Juice connects to everything else I’m building. Sig → rendering & reactivity Nectarine → data & APIs Seltzer → HTTP layer GrapeVine → infrastructure Juice becomes: The way UI is defined across the entire system. Not just styled. Right now, Juice is still evolving. I’m documenting rules. But the direction is clear: UI should be declarative, structured, and system-driven. Not just styled with strings. I didn’t start building Juice because I hated CSS. I started building it because I realized: We’ve been missing a layer. And once you see it… You can’t unsee it. Part 4 is where things start getting real. We’ll talk about: Rules & constraints How Juice avoids becoming chaos And how this turns into an actual engine Stay tuned.
