Web · React 19 · Next 15 · Tailwind v4 · Radix
@avala/design
Carbon-shaped React kit, Tailwind v4 token bridge, Radix a11y backbone. Drop into any Next 14+/16+ App-Router project in five minutes.
Install
bash
npm i @avala/design @avala/design-tokens
# or
bun add @avala/design @avala/design-tokensCSS imports
Tailwind v4 first (consumer must own this), then the kit's style bridge, then your chosen brand × tone token file.
src/app/globals.csscss/* Tailwind v4 — owned by the consumer so postcss-import resolves
from /node_modules. design/web/node_modules is empty on Vercel. */
@import "tailwindcss";
/* Token bridge: maps every Carbon role to Tailwind utility classes. */
@import "@avala/design/styles";
/* Brand × tone: g10 (light) at :root, g100 (dark) under .dark. */
@import "@avala/design-tokens/css/avala.css";
/* — or any of the 8 brands —
@import "@avala/design-tokens/css/pay.css";
@import "@avala/design-tokens/css/learning.css";
@import "@avala/design-tokens/css/investor.css";
@import "@avala/design-tokens/css/tickets.css";
@import "@avala/design-tokens/css/operations.css";
@import "@avala/design-tokens/css/chat.css";
@import "@avala/design-tokens/css/neutral.css";
*/next.config.ts
One helper sets up transpilePackages + webpack.resolve.modules so the kit's symlinked dist finds its transitive deps.
next.config.tstsximport type { NextConfig } from "next";
import { withAvalaDesign } from "@avala/design/next-config";
const baseConfig: NextConfig = {
// your config…
};
export default withAvalaDesign(baseConfig);First component
src/app/page.tsxtsximport { Button, Tag } from "@avala/design";
export default function Page() {
return (
<div className="p-8">
<h1 className="text-heading-04 text-text-primary mb-4">Hello, Avala.</h1>
<Button kind="primary" size="md">Primary action</Button>
<Tag tone="green" className="ml-3">Stable</Tag>
</div>
);
}Theme provider
Wraps your app, persists brand × tone to localStorage, toggles the .dark class on <html> so the dual-tone CSS swaps tokens.
src/app/layout.tsxtsximport { ThemeProvider } from "@avala/design";
import "./globals.css";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider defaultBrand="avala" defaultTone="g100">
{children}
</ThemeProvider>
</body>
</html>
);
}What's next
- Browse the component catalog — 79 primitives, patterns, layout, and domain components.
- Open /themes to preview every brand × tone.
- Check migrating from Carbon if you're cutting over from
@carbon/react.