Files
upstream-twenty/packages/twenty-ui
upstream-mirror e7da97194a
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
2026-09-17 23:28:13 +05:00
..

twenty-ui logo

twenty-ui

Twenty's open-source React UI component library: components, icons, and design tokens built on a zero-runtime, CSS-variable styling layer.

Read the twenty-ui documentation for setup, theming, and component guides.

Alpha: twenty-ui is still in alpha. Its version number follows the Twenty SDK release cycle. APIs and component behavior may change between releases.

Installation

For a standalone React application, install the library and its peer dependencies. React 19 is required.

npm install twenty-ui monaco-editor react@^19 react-dom@^19

Install monaco-editor even if you never render a code editor: the twenty-ui/primitives/input, twenty-ui/primitives/feedback, and twenty-ui/primitives/navigation entry points reference it, and bundlers fail to resolve it otherwise.

For Twenty apps, follow Using Twenty UI components. The front component renderer supplies the workspace theme. Keep twenty-ui, twenty-sdk, and twenty-client-sdk on the same version.

Usage

For a standalone React application, import the base styles once, pick a theme stylesheet, and wrap your app in ThemeProvider:

import { ThemeProvider } from 'twenty-ui/theme-constants';
import { Button } from 'twenty-ui/primitives/input';

import 'twenty-ui/style.css';
import 'twenty-ui/theme-light.css';

export const App = () => (
  <ThemeProvider colorScheme="light">
    <Button>Click me</Button>
  </ThemeProvider>
);

Prefer the matching subpath for better tree-shaking. Imports from the twenty-ui root entry point are also supported.

import { Button } from 'twenty-ui/primitives/input';

Entry points

Subpath Contents
twenty-ui All components, icons, theme tokens, and utilities
twenty-ui/assets Logos and static assets
twenty-ui/components Shared design presets and reusable app building blocks
twenty-ui/icon Icon components and the icon provider
twenty-ui/primitives Foundational UI controls and compound controls
twenty-ui/primitives/accessibility Hidden elements and keyboard interaction helpers
twenty-ui/primitives/data-display Avatars, chips, tags, status indicators, and display helpers
twenty-ui/primitives/feedback Toasts, banners, progress bars, and loaders
twenty-ui/primitives/input Buttons, form controls, pickers, and code editors
twenty-ui/primitives/json-visualizer JSON tree viewer
twenty-ui/primitives/layout Layout, animation, resizing, and section components
twenty-ui/primitives/navigation Links, list items, menus, and tabs
twenty-ui/primitives/surfaces Cards, dialogs, menus, popovers, and tooltips
twenty-ui/primitives/typography Text, headings, labels, and typography helpers
twenty-ui/testing Storybook and test decorators
twenty-ui/theme Theme types and helpers
twenty-ui/theme-constants Design tokens, ThemeProvider, and useTheme
twenty-ui/utilities Hooks and shared utilities

Theming

  • twenty-ui/style.css ships the base reset and component styles. Import it once.
  • twenty-ui/theme-light.css and twenty-ui/theme-dark.css define the design-token CSS variables for each color scheme.
  • ThemeProvider exposes the active theme through useTheme() and applies the light / dark class. Pass applyToRoot={false} with overrides to scope a theme to a subtree instead of the document root.

Development

Primitive guides belong in packages/twenty-docs/ui/primitives. Shared component guides belong in packages/twenty-docs/ui/components. For each stateful API that supports both modes, include separate Uncontrolled state and Controlled state examples with the same scenario, labels, and initial state. Keep each example complete, with public imports and one exported example component.

Explain state ownership before advanced behavior such as indeterminate selection or manual tab activation. Document independent states, such as selection and popup visibility, separately. For components that delegate state to a parent or group, explain that ownership and link to the relevant examples.

For compound components, include an anatomy tree and identify required parts, optional parts, and elements supplied internally. Show supported composition with complete examples, use Twenty UI components for supporting controls, and explain how custom wrappers preserve props and refs. Use text fences for structural diagrams and tsx fences for runnable examples so the documentation checker validates the examples.

Internal state

twenty-ui uses Base UI's store for notification state. Each ToastProvider creates its own store, and the toaster subscribes to the toast list. Queue rules and rendering remain owned by twenty-ui. Consumers use useToast() without configuring a state library.

The store factory and subscription hook are internal to the toast module. @base-ui/utils is a direct dependency pinned to the version used by @base-ui/react, and the library build keeps it external. Review its store API changes when upgrading the dependency.

Testing

Component interaction and behavior tests belong in Storybook stories (*.stories.tsx) using play functions. Component unit tests are reserved for conformance (native props, refs, class names, rendering, and prop types). Keep non-interactive utility, hook, and token tests in the Vitest unit project; avoid duplicating story coverage there.

npx nx build twenty-ui                 # Build the library (dual ESM/CJS + types)
npx nx storybook:serve:dev twenty-ui   # Run Storybook
npx nx test twenty-ui                  # Run unit tests
npx vitest run --root packages/twenty-ui --project unit <file>   # Run a single test file

License

twenty-ui is released under the MIT license.