DEV Community

Cover image for I got tired of class-heavy UI code, so I started building Juice
Drew Marshall
Drew Marshall

Posted on

I got tired of class-heavy UI code, so I started building Juice

At some point, my markup started feeling… heavy.

Not slow. Not broken. Just hard to look at.

At some point, it stopped feeling like I was writing UI…
and started feeling like I was managing class strings.


The Problem

Modern CSS tooling solves a lot of problems.

But it also introduces some friction—especially at scale.

Verbosity

You end up stacking utilities:

<div class="flex flex-col items-center justify-center h-screen bg-gradient-to-r from-purple-400 to-pink-500">
Enter fullscreen mode Exit fullscreen mode

It works. It’s powerful. But it’s a lot to parse.


Readability

When everything is a class:

  • layout
  • spacing
  • color
  • behavior

…it all blends together.

You stop seeing intent and start reading implementation.


Scaling UI Systems

As projects grow, this turns into:

  • long, unreadable markup
  • repeated patterns everywhere
  • small changes requiring multiple class edits

It works—but it starts to feel messy.


The Idea

What if UI wasn’t driven by long class strings?

What if it looked more like this:

<div flex="col" height="full" grad="candy-grape" centered>
Enter fullscreen mode Exit fullscreen mode

Instead of stacking utilities, each attribute describes intent directly:

  • flex="col" centered → layout
  • height="full" → sizing
  • grad="candy-grape" → styling

Example

Here’s a simple comparison.

Tailwind-style

<div class="flex flex-col items-center justify-center h-screen bg-gradient-to-r from-purple-400 to-pink-500">
  <h1 class="text-2xl font-bold text-white">Hello</h1>
  <button class="mt-4 px-4 py-2 bg-black text-white rounded-md">Click me</button>
</div>
Enter fullscreen mode Exit fullscreen mode

Juice

<div flex="col" height="full" grad="candy-grape" centered>
  <h1 fontSize="xl" fontColor="white">Hello</h1>
  <button margin-top="4rem" padding="x-4 y-2" bgColor="black" fontColor="white" rounded="md">
    Click me
  </button>
</div>
Enter fullscreen mode Exit fullscreen mode

The difference isn’t just shorter code.

Each attribute expresses intent directly, instead of stacking utilities together.


Interactions & Animations

This pattern extends beyond layout and styling.

<button hover="scale-up" motion="fade-in">
  Click me
</button>
Enter fullscreen mode Exit fullscreen mode

Interactions and animations follow the same idea:

  • attributes describe behavior
  • not just appearance

What Juice Is

Juice is an attribute-based UI system.

It’s designed to make UI code more:

  • expressive
  • readable
  • scalable

Core Ideas

  • Layout via attributes
  • Styling via attributes
  • Animations via attributes
  • Works standalone or with frameworks
  • Optional JS control when needed

Why I Built It

I wasn’t trying to replace existing tools.

I was trying to solve a personal problem:

I wanted my UI code to feel as clean as my logic.

I like systems.
I like consistency.

And I didn’t like how styling started to feel like a wall of strings.

So I started experimenting with attributes.

That turned into patterns.
Then conventions.
Then a system.


Who This Is For

Juice is probably a good fit if you:

  • build apps or dashboards
  • use Tailwind (or similar) but feel the verbosity
  • care about readability as your project grows

It’s probably not for you if you prefer:

  • strict class-based systems
  • or fully abstracted component libraries

Current State

Juice is currently in alpha.

That means:

  • things will change
  • APIs may evolve
  • ideas are still being refined

But the core concept is solid enough to start sharing.


Try It / Feedback

This is still early, and I’m actively shaping it.

If you’ve ever felt the pain of class-heavy UI code, I’d love your feedback:

  • Does this feel clearer or just different?
  • Would you actually use this in a project?

Repo:
👉 Juice


This isn’t meant to replace everything.

It’s just another way to think about UI—and I’m curious if it clicks for anyone else the way it did for me.

Top comments (0)