Skip to content
Web + React Native

One catalogue.
Two platforms.
Zero forks.

Nebula is a UI library where the contract lives in the tokens and each platform only implements the visual layer. Two products that look nothing alike ship from the same components — you change the theme, never the code.

app/listing.tsx

Swiss Chalet

Cozy wooden chalet nestled in the Swiss Alps, with a warm fireplace and direct access to the ski slopes.

pnpm add @stellaria/nebula-web
614 a11y checks
One catalogue

Same markup. Different product.

Nothing below changes when you switch products: not a prop, not a class, not a component. Only the theme — and it repaints this page, not a preview box. Switch it right here, or from the panel at the bottom right.

Verify account

We sent a code to a****@email.com

Didn't get it?

Resend

Price

USD 250.00

62

Open the palette

K

Ana Ruiz

Reconciliation lead

matchedVerifiedAdmin
@stellaria/nebula-web

Notifications

Account

Profile

Beyond four colours

What the theme actually reaches

Every other library stops at an accent colour and a radius. Nebula's contract covers seven axes, and the panel at the bottom right drives all of them on this page: product, scheme, corners, density, typeface, motion and glass. Nothing here is re-implemented per product.

Colour, type, motion, radii, shadows, glass

The NebulaTheme contract covers the whole visual surface, including the variant recipes. A product retunes all of it from one object.

Accessibility is a gate, not a promise

Every story runs axe on every commit, alongside keyboard, reduced-motion, contrast and visual-regression gates. Eight of them, all blocking.

Every module has a budget

size-limit measures each entry point in brotli kB and fails the build when it drifts. Heavy dependencies live behind subpaths you opt into.

Measured, not claimed

Web components
158
in v1
Blocking CI gates
9
eight of them in CI
Style props
128
on every primitive
Themes on this page
7
each in light and dark
Motion is a token

One switch retunes every animation

Components read motion.tier from the theme instead of hardcoding durations. Set it to minimal and every loop, spring and reveal on this page stops — the same path prefers-reduced-motion takes.

Tokens in force

tier

standard

duration.base

180ms

spring.default

280

Everything on this page reads these, never a hardcoded duration.

Springs, staggered

gentle

default

snappy

Presets, on a loop

scale
pop
slide-up
slide-right

The beam

A lit border that sweeps the perimeter. It stops flat at minimal.

standard

Animated gradient

Brand in motion

The stops drift; the tier decides whether they move at all.

Indeterminate work

Counting down

Hover, with intent

Hover the button.

Gradient text

Same switch

One theme object retunes colour, type, motion and glass at once.

Build the whole product from one catalogue

The core is MIT and public. Install it, theme it, and ship both platforms from the same components.

Next.js

pnpm add @stellaria/nebula-web

Vite

pnpm add @stellaria/nebula-web

React Router

pnpm add @stellaria/nebula-web