Build interfaces
with attributes

Every spacing, color and layout decision lives on the element it styles. Your markup keeps reading like the thing it renders, not like an index of class names.

Get started Browse AtomAttr UI

Customers

18,246

+6.5% since last week

Asset generatedMonthly

128.7K

Selected customers201
Selected MRR$30,000
Annual discount rate7.9%

24

Clients

Samantha Bloom

Calling...

Markup that actually reads like the interface.

Styling is a property of an element, so it belongs on the element. No sprawling class strings, and no stylesheet to cross-reference.

button.html
<button bg="primary"
  hover-bg="primary/80"
  text="white"
  px="6" py="3"
  rounded="full">
  Get started
</button>

Attribute-first

One attribute for every decision.

There is exactly one place a style decision lives: the attribute. Not a class, not a modifier, not a wrapper component. Just bg=, px= and rounded=, spelled the way you would say them out loud.

Read the docs

ATOMATTR VS TAILWIND

Same decisions. A different shape.

Tailwind is a great utility system, and Atomattr borrows its vocabulary. The difference is where the decisions live: one long class string, or one attribute per decision.

Tailwind class="…"
<button
  class="inline-flex items-center gap-2
    rounded-full bg-indigo-600 px-6 py-3
    text-sm font-semibold text-white
    shadow-lg hover:bg-indigo-500
    focus-visible:outline-2
    md:px-8 md:text-base
    dark:bg-white dark:text-gray-950
    dark:hover:bg-gray-200">
  Get started
</button>
Atomattr attr="…"
<button
  display="inline-flex" items="center" gap="2"
  rounded="full"
  bg="primary" hover-bg="primary/80"
  dark-bg="#fff" dark-text="gray-950"
  text="white"
  px="6" md-px="8" py="3"
  font-size="sm" md-font-size="md"
  font-weight="600" shadow="lg">
  Get started
</button>

Scannable

Each decision is its own name and value, so you can read down a column instead of parsing a string.

Variants stay beside values

px and md-px sit next to each other, rather than px-6 and md:px-8 scattered through the string.

Semantic tokens

Say primary, muted or border and let the theme decide the actual color.

React Native, same words

The vocabulary carries over to <View>, so web and mobile share one way of styling.

Tailwind Atomattr
Where styling lives A single class string One attribute per decision
Responsive md:px-8 md-px="8"
Dark mode dark:bg-white dark-bg="#fff"
Hover and state hover:bg-indigo-500 hover-bg="primary/80"
Opacity modifier bg-indigo-600/80 bg="primary/80"
Platforms Web HTML, React and React Native

Different tools, different trade-offs. Pick the one whose markup you would rather read six months from now.

RESPONSIVE

Breakpoints, right where you read.

A breakpoint is just a prefix. md-grid-cols="2" sits beside grid-cols="1", so the whole layout story is in one spot. Resize your window and watch these tiles reflow.

See the patterns
button.html
display="grid" gap="3"
grid-cols="1"
md-grid-cols="2"
One
Two
Three
Four

Family Therapy

Tomorrow

Johnson Family

4:30pm tp 6:00pm 1hr 30mins
Group Therapy

Family Therapy

Tomorrow

Johnson Family

4:30pm tp 6:00pm 1hr 30mins
Group Therapy

DARK MODE

Dark mode without a rewrite.

Add dark-bg or dark-text to the element and light and dark intent live together. Flip the theme in the header and this whole page follows.

Explore the color system

CROSS-PLATFORM

Same language, platform-aware output.

HTML and React Native render differently. Atomattr gives you one styling vocabulary without pretending the two platforms are the same thing.

Read the docs
HTML
<div display="grid" grid-cols="3" gap="4">
  ...
</div>
React Native
<View display="grid" grid-cols="3" gap="4" />

COMPONENTS, READY TO COPY

Real interfaces, built the same way.

PRO

$19/month

Unlimited projects
Free UI Templates
Unlimited projects
Dark mode built in
Priority support

Welcome back

Active users

12.4k

+8.2%

Revenue

$48.9k

+3.1%

Churn

1.2%

-0.4%

COLOR SYSTEM

Design systems that stay yours.

The primary color on this page is not a screenshot. It is read straight from --aa-color-primary at render time, in whichever mode you are viewing.

Primary

Success

Warning

Danger

Semantic tokens

Tokens stay stable. Palettes can change.

PRIMARY SHADES

10 30 50 70 90

LIVE GRADIENT

Gradient
--aa-color-primary

COMMUNITY

Build with people nearby.

Follow progress, ask questions, share experiments, and help shape the attribute API as it grows.

Community chat Get help, trade ideas, and talk through real interface patterns. Source and issues Read the code, open issues, and propose changes in public. Follow on X Updates as they ship, and focused questions when a thread needs detail.

Try one component, then decide.

Open the docs, copy a pattern, and see how the markup feels before changing anything big in your project.

Read the docs Browse AtomAttr UI