Product screens,already designed
ferry-ui is a React design system for dashboards, admin consoles and developer tools. You get the tokens, the controls, the page patterns and the application shell, so you start from a finished screen.
Screens built with ferry-ui
This is not a picture. Click in the screen. The application frame with info tiles, metric cards, a grid of projects and a command menu.
See how it is builtBuilt on the stack you already use
- React 19
- TypeScript
- Tailwind CSS v4
- Radix UI
- shadcn/ui
- Lucide
- Vite
- Next.js
- React Router
- TanStack Router
- Storybook
- Vitest
Every layer of the screenTry each one here
28 accessible primitives
Buttons, fields, menus, dialogs and tables on Radix UI. The sizes have the same names in every control, so a row of controls lines up.
One set of tokens
Each color, radius and font is a CSS variable with a Tailwind class. The dark theme is one class on the page.
- surface-75
- surface-200
- border-strong
- foreground
- primary-solid
- success
- warning
- destructive
22 patterns
Page headers, form cards, table states, empty states and confirm dialogs: the parts you build again in each product.
The application shell
A top bar, an icon rail, a phone drawer and a command menu, all from one list of pages.
Keyboard and screen readers
Focus, ARIA names and keys come with the components. Put the mouse away and try this menu.
- Move the focus to the button
- Tab
- Open the menu
- Enter
- Move in the menu
- ↑↓
- Close the menu
- Esc
Written for your AI agent too
The repository has an AGENTS.md guide with rules and type-checked snippets. Each page of these docs has a Markdown version, and llms.txt lists them.
# ferry-ui
> ferry-ui is a React 19 design system for product interfaces.
## Primitives
- [Button](/docs/components/button.md): A control that starts an action.
- [Dialog](/docs/components/dialog.md): A window on top of the page.Your router, your state
A link is an href string that goes through one adapter. A component holds no global state: you control it with props.
import { Link } from 'react-router'
import { LinkProvider, type LinkComponent } from 'ferry-ui'
const RouterLink: LinkComponent = ({ href, ...props }) => (
<Link to={href} {...props} />
)
<LinkProvider component={RouterLink}>{app}</LinkProvider>One package, one import. The page you read now uses the same components: its navigation, its search, its code blocks and its tables are ferry-ui.
Add it to your appin four steps
You need React 19. Tailwind CSS v4 is optional: without it, you import one compiled stylesheet.
Install the package
One package, with the components, the tokens and the stylesheets.
$ npm install ferry-uiImport the styles
After Tailwind CSS v4, import the theme. It brings the tokens and the classes of the components.
app.css @import "tailwindcss"; @import "ferry-ui/fonts.css"; /* optional: Inter and Source Code Pro */ @import "ferry-ui/theme.css";Mount the providers
One time, at the root of the app: the theme, the tooltips and the toasts.
providers.tsx import type { ReactNode } from 'react' import { ThemeProvider, Toaster, TooltipProvider } from 'ferry-ui' export function Providers({ children }: { children: ReactNode }) { return ( <ThemeProvider defaultTheme="system"> <TooltipProvider> {children} <Toaster /> </TooltipProvider> </ThemeProvider> ) }Use a component
Import each component from the package root.
no-projects.tsx import { Button, EmptyState } from 'ferry-ui' import { FolderKanban, Plus } from 'lucide-react' export function NoProjects({ onCreate }: { onCreate: () => void }) { return ( <EmptyState icon={<FolderKanban />} title="No projects yet" description="Projects group your invoices, members and API keys." actions={ <Button variant="primary" icon={<Plus />} onClick={onCreate}> New project </Button> } /> ) }
No Tailwind in your app?
Import ferry-ui/styles.css at the root of the app. Style your own markup with plain CSS and the variables of the tokens.
Your colors, your fonts
Override a few CSS variables after the import to give ferry-ui the look of your product, in light and in dark.
Read about themingOpen source, MIT licensedRead it, run it, change it
ferry-ui is built in the open. Each component has a JSDoc that says when to use it and when not to, a story in Storybook and a page in these docs.
- TokensColors, radii, shadows and fonts, light and dark
- Primitives28 building blocks on Radix UI
- Patterns22 compositions for recurring product needs
- Layout8 pieces of the application shell
- Hooks and helperscn, useCopy, useTheme, the link contract
- DocumentationThese docs, a Storybook and a guide for agents
Product screens, already designed
Read the quick start, copy a page from the examples and put your data in it.