Getting started
Installation
Set up Expressive in a React project that uses Tailwind CSS v4. It takes one command, plus one more per component.
Requirements
- React 19 and TypeScript.
- Tailwind CSS v4, with a CSS file that contains
@import "tailwindcss". - Next.js, Vite, React Router / Remix, TanStack Start or Astro (with React islands).
1. Initialize
Run this in your project root:
npx @grenishrai/expressive initIt asks for six things, all changeable later:
- Seed color: the hex color your whole scheme is generated from.
- Color scheme: how the seed is interpreted, from
expressive(the default) totonal-spotormonochrome. - Font: any font family. Variable fonts work best.
- Motion scheme:
expressive,standardorfluid(soft and gooey; needs Motion or GSAP). - Motion engine: CSS (no dependency), Motion or GSAP.
- Corner scale: Material's default, softer, or sharper.
Then it:
- writes
expressive.jsonwith your choices and where files go; - copies the tokens and helpers into
lib/expressive/; - adds
expressive.cssnext to your global CSS and imports it after Tailwind; - generates your theme's CSS variables into the global CSS file;
- installs the npm packages those files use.
2. Add components
npx @grenishrai/expressive add button dialog switchComponents land in components/expressive/, with imports rewritten to your path aliases (or to relative paths if you don't use aliases). Anything a component depends on is added too.
import { Button } from "@/components/expressive/button";
export default function Page() {
return <Button>Get started</Button>;
}3. Load your font
The theme refers to your font by name; loading it is up to you. In Next.js, use next/font and pass its CSS variable as the font:
import { Geist } from "next/font/google";
const geist = Geist({ subsets: ["latin"], variable: "--font-geist" });
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={geist.variable}>
<body>{children}</body>
</html>
);
}npx @grenishrai/expressive theme --font "var(--font-geist)"Dark mode
The dark scheme applies under a .dark class on any ancestor, usually <html>. Toggle it however you like, for example with next-themes set to attribute="class".
Run from source
Until the CLI is on npm:
git clone https://github.com/Grenish/expressive.git
cd expressive
pnpm install
pnpm --filter @expressive/registry build # builds the registry JSON
pnpm --filter @grenishrai/expressive build # builds the CLI
# in your project (uses the hosted registry):
node /path/to/expressive/packages/cli/dist/index.js initTo work against your local checkout instead, add --registry /path/to/expressive/apps/www/public/r. The registry location is saved in expressive.json, so later add commands find it on their own.
Troubleshooting
- “Could not find a CSS file with @import "tailwindcss"”: set up Tailwind v4 first, or point at your CSS file with
--css src/styles.css. - Styles look unthemed: make sure
expressive.cssis imported after Tailwind, and that starter styles (like abodybackground from a project template) aren't overriding the theme.