DEV Community

Cover image for I Got Tired of Class-Heavy UI Code — So I Kept Going (Juice Part 4)
Drew Marshall
Drew Marshall

Posted on

I Got Tired of Class-Heavy UI Code — So I Kept Going (Juice Part 4)

In Part 1, I talked about the frustration.

In Part 2, I showed the direction.

In Part 3, I explained the shift toward a system.

Now in Part 4, I want to talk about the part that matters most:

rules.

Because a UI system is not just made useful by how expressive it is.

It is made useful by how well it avoids turning into chaos.


A System Cannot Be “Anything You Want”

This is the trap a lot of systems fall into.

They give you a lot of power, but not enough structure.

So over time, the same idea gets written five different ways.

<div padding="2rem" bgColor="blue-500" fontColor="white-100">
  Content
</div>
Enter fullscreen mode Exit fullscreen mode
<div padding="32px" bgColor="blue-500" fontColor="white-100">
  Content
</div>
Enter fullscreen mode Exit fullscreen mode
<div class="p-8 bg-blue-500 text-white">
  Content
</div>
Enter fullscreen mode Exit fullscreen mode

Different syntax. Same outcome.

That might seem harmless at first, but over time it creates drift.

And drift is what breaks systems.


Juice Needs More Than Attributes

This is one of the biggest things I have realized while building Juice:

Attributes alone do not make a system.
Rules make a system.

The attributes are just the interface.

The rules are what make the interface reliable.

Without rules, you get:

  • naming drift
  • inconsistent spacing
  • duplicated patterns
  • unpredictable components
  • weird one-off markup decisions

With rules, you get:

  • repeatability
  • consistency
  • cleaner templates
  • stronger defaults
  • better long-term scale

That is the real difference.


Rule 004: One Concern Per Attribute

One of the most important rules I have written for Juice is simple:

One concern per attribute.

That means an attribute should do one job.

Not three jobs.
Not five jobs.
One.

Bad:

<div box="primary">
  Content
</div>
Enter fullscreen mode Exit fullscreen mode

Why is that bad?

Because box="primary" is too vague.

Does it control:

  • background color?
  • padding?
  • border?
  • radius?
  • shadow?
  • text color?

Probably several of those.

That means one attribute is hiding multiple concerns.

And once that starts happening, the system gets harder to reason about.

Better:

<div padding="2rem" bgColor="blue-500" radius="md" shadow="gray-400" depth="sm">
  Content
</div>
Enter fullscreen mode Exit fullscreen mode

Now each attribute has a clear responsibility.

That makes the system easier to learn, easier to document, and easier to extend.


Explicit Beats Clever

A lot of frontend tooling tries to be clever.

I want Juice to be clear.

I would rather have markup that is:

  • readable
  • direct
  • predictable

than markup that is “smart” but unclear.

That is part of why I keep leaning into attributes.

They let the markup say what is happening in a way that feels close to the element itself.

But that only works if the attribute language stays disciplined.

If the language gets sloppy, then all I have done is reinvent confusion with different syntax.


Rules Protect the System From Drift

This is especially important in a growing project.

Once you have:

  • cards
  • forms
  • nav
  • themes
  • layout primitives
  • responsive behavior
  • surface ideas
  • templates

you are no longer just experimenting.

You are defining a language.

And languages break down fast when the same thing can be expressed too many different ways.

That is why rules matter.

They protect the system from becoming a pile of “kind of similar” patterns.


Constraints Are Not the Enemy

This is something I think more developers should hear:

constraints are not what kill creativity.
bad constraints kill creativity.
good constraints make creativity faster.

If spacing is already consistent, I do not have to think about spacing every five seconds.

If responsiveness is already baked into the system, I do not have to keep writing breakpoint logic into the markup.

If a card has a known structure, I can focus on the actual content and presentation.

That is freedom.

Not the freedom to do anything.

The freedom to move faster without lowering quality.


Juice Is Trying To Be a Language

That is the deeper idea behind all of this.

I am not trying to build a bag of styling tricks.

I am trying to build a language for UI.

A language needs:

  • vocabulary
  • syntax
  • constraints
  • consistency
  • meaning

In Juice:

  • attributes are the vocabulary
  • markup patterns are the syntax
  • rules are the constraints
  • docs are the grammar
  • templates are the stress test

That is how it starts becoming more than a styling library.

That is how it starts becoming a system.


Why This Matters for the Future

The more I work on Juice, the more I believe this:

frontend development has too much repeated decision-making in it.

Too much repetition.
Too much breakpoint choreography.
Too much restating intent.
Too much low-level noise in markup.

I think future-thinking UI systems should take more responsibility.

They should:

  • understand layout better
  • handle responsiveness better
  • provide stronger structure
  • reduce repeated authoring work
  • let developers think more about pages and products

That is the direction I want Juice to move in.

Not less control.

Better defaults.
Better structure.
Better language.


The Goal

The goal is not to remove thought from UI development.

The goal is to remove unnecessary thought.

I should be thinking about:

  • the page
  • the product
  • the experience
  • the content
  • the flow

I should not have to keep fighting the markup just to maintain consistency.

That is what the rules are for.

They make the language trustworthy.


Final Thought

Juice does not get stronger by adding endless attributes.

It gets stronger by making the attribute language more disciplined.

Because the real power of a UI system is not how much it can do.

It is how consistently it helps people do the same things well.

That is where I am pushing Juice next.

Not just toward more features.

Toward stronger rules.


Part 5 will go deeper into themes, surfaces, and how Juice starts moving from a styling system into something that feels more like an engine.

Top comments (0)