Installation
One package and two CSS imports. The stylesheet tells Tailwind where the components' classes are, so there is nothing else to configure.
Before you start#
cennge-ui needs an app with React 17, 18 or 19 and Tailwind CSS 4. If Tailwind is not set up yet, add it with the plugin for your build tool. In Next.js, that is the PostCSS plugin:
npm install tailwindcss @tailwindcss/postcss// postcss.config.mjs
export default {
plugins: { "@tailwindcss/postcss": {} },
};In Vite, it is the Vite plugin: npm install tailwindcss @tailwindcss/vite, then add tailwindcss() to the plugins of vite.config.ts.
Install the package#
npm install cennge-uiOr pnpm add cennge-ui, or yarn add cennge-ui. react, react-dom and tailwindcss are peer dependencies: the package uses the ones your app already has. The package itself brings radix-ui, tailwind-variants, tailwind-merge and clsx.
Add the styles#
Import Tailwind, then the package's stylesheet, in your app's main CSS file:
/* app/globals.css in Next.js, src/index.css in Vite */
@import "tailwindcss";
@import "cennge-ui/styles.css";
body {
@apply bg-background font-cennge text-foreground antialiased;
}The two imports are the whole setup. cennge-ui/styles.css:
- registers the package's own files with Tailwind (an
@sourceline inside it), so the classes the components use end up in your CSS; - declares the theme as
--cennge-*variables, for the light theme on:rootand the dark theme on.dark; - maps them to Tailwind utilities such as
bg-primary,text-primary-text,bg-surface-2androunded-large, which you can use in your own markup; - makes the
dark:variant follow adarkclass instead of the system setting.
The body rule is optional, and yours to change: it gives the page the theme's background and text colours, so it switches with the theme. font-cennge is the theme's font stack, Inter first, then the system font. The components use your app's fonts, and the package does not ship Inter: load it yourself, for example with @fontsource/inter, or the system font takes its place. To use another font, set --cennge-font-sans to it.
Use a component#
Import components by name from cennge-ui. Paste this one into a page: if the setup works, the buttons look the same in your app as here, the first filled with the accent and glowing in it, the second a soft tint, both sinking a little when pressed.
import { Button } from "cennge-ui";
export default function FirstComponent() {
return (
<div className="flex flex-wrap gap-3">
<Button asChild color="primary" variant="shadow" size="lg">
<a href="https://www.npmjs.com/package/cennge-ui">cennge-ui on npm</a>
</Button>
<Button asChild variant="flat" size="lg">
<a href="https://github.com/Cennge/cennge-ui">Source on GitHub</a>
</Button>
</div>
);
}Server Components#
The components' files start with "use client", so you import them straight into a Server Component page or layout, with no wrapper of your own. What has to run on the server, such as cn (class names joined, Tailwind conflicts resolved) and tv (variants), comes from cennge-ui/utils, which has no "use client":
import { cn, tv } from "cennge-ui/utils";Next.js and SSR covers hydration and what renders on the server.
Entry points#
| Import | What it has |
|---|---|
cennge-ui | Every component, the theme helpers, CenngeProvider and toast. ESM and CommonJS, with types. |
cennge-ui/styles.css | The tokens, their Tailwind utilities, the dark: variant and the Prose styles. |
cennge-ui/utils | cn and tv, safe on the server. |
cennge-ui/charts | BarChart, LineChart, AreaChart, DonutChart and Sparkline. ESM only. |
cennge-ui/map | The map and its layers. ESM only, and needs maplibre-gl 6. |
In the ESM build every component is a chunk of its own, and the package has no side effects but its CSS, so your bundler keeps only what a page imports. Each component page gives the gzip size of its import in its field marks.
Maps need one more package, only in apps that show a map:
npm install maplibre-glIt is loaded when the first map mounts. The Map page shows how to point MapLibre at its worker in Vite and in Next.js.
Optional pieces#
<Toaster />, mounted once near the root, shows whattoast()sends from anywhere: event handlers, data hooks, plain modules. See Toast.<CenngeProvider>sets defaults for every component below it (size, radius, colour), the locale for numbers and dates, and reduced motion. Components work without it. See Provider.<ThemeScript>in the<head>keeps the stored light or dark theme on the page before the first paint. See Dark mode.
If the components have no styles#
Buttons that render as plain text mean Tailwind did not generate the package's classes. Check that cennge-ui/styles.css is imported after tailwindcss, in the CSS file your app loads. If the classes are still missing, name the package's folder for Tailwind yourself, relative to that CSS file:
@source "../node_modules/cennge-ui/dist";