@project-graphite/ui holds the Project Graphite design tokens, dark theme and React components,
so every Graphite web app shares one look and one set of building blocks.
It has no runtime dependencies. React 19 is a peer dependency, and the package never imports a
router: apps pass their own link component in through UiProvider.
Install a release by URL. No registry account or token is needed:
npm install --save-exact https://github.com/project-graphite/graphite-ui/releases/download/v0.3.0/project-graphite-ui-0.3.0.tgzLoad the theme after Tailwind. @source lets Tailwind see the classes the components use, and its
path is relative to the CSS file:
@import 'tailwindcss';
@import '@project-graphite/ui/theme.css';
@source '../node_modules/@project-graphite/ui/dist';Give the package the app's router link once:
import { Link } from 'react-router';
import { UiProvider, type UiLinkProps } from '@project-graphite/ui';
const RouterLink = ({ href, ...props }: UiLinkProps) => <Link to={href} {...props} />;
<UiProvider link={RouterLink}>
<App />
</UiProvider>;Then import components and use the colour tokens as Tailwind classes, such as bg-surface,
text-muted and border-line:
import { AppShell, Dialog, TextField, Toggle } from '@project-graphite/ui';theme.css:- colour, font, radius, shadow and easing tokens;
- base form styles, the focus ring and scrollbars;
- motion that only runs when reduced motion isn't requested;
- the
shell,page-title,mono-smandrule-linkutilities; - generic component classes such as
primary-button,tab-link,popover-panelandtab-bar.
- Components:
- layout:
AppShell(with an optionalSidebar),Tabs; - dialogs and popups:
Dialog,ConfirmDialog,CommandPalette,Popover,Menu; - forms:
TextField,TextAreaField,CodeInput,Toggle,GridListbox; - display:
TagChip,Avatar,EmptyState,Pagination,SmoothImage, the skeletons,Icon; - feedback:
SnackbarProvider,OutageGate.
- layout:
- Helpers:
errorMessage,isAbortError,timeAgo,useDismiss, anduseCommandShortcut(opens the command palette on Ctrl+K or Cmd+K).
The phone layouts are built in. Dialogs become bottom sheets, and the tab bar and popovers account for the header and the safe area.
npm ci
npm run lint && npm test && npm run build
npm run preview:devpreview:dev serves a local page showing every component in every state. It isn't published.
To try a change in an app before releasing it, run npm run build && npm pack. Then install the
tarball in the app with npm install --no-save <path to the .tgz>.
- Merge a PR that bumps
versioninpackage.jsonandpackage-lock.json, titledchore(release): <version>. - Tag the merge commit and push the tag, for example
git tag v0.2.0 && git push origin v0.2.0.
The Release workflow checks that the tag matches the version, runs lint, tests and build, attests
the tarball's provenance and publishes the GitHub release. Anyone can verify a downloaded tarball
with gh attestation verify <file> --repo project-graphite/graphite-ui.
Versions follow semver. While the package is at 0.x, a minor version may break things, and its release notes say so.