The canonical Ponti Studios UI package. It is published from this repository to npm.
The design system is documented in docs/:
- Foundations — color, spacing, radius, typography, elevation, iconography, motion tokens
- Primitives — component contracts (variants, sizes, states)
- Patterns — screen composition rules
- Review gates — pass/fail review criteria
Import native components and the shared token theme from @ponti-studios/ui/native.
This entry point requires react-native as a peer and uses the same light/dark
color, spacing, radius, type-size, and font-weight tokens as the web components.
The base package remains usable by web consumers that do not install React Native.
import { NativeButton, NativeThemeProvider } from "@ponti-studios/ui/native";Built-in accessibility labels can be localized once with UiTextProvider.
Component props such as loadingLabel, emptyLabel, and visible labels remain
available and take precedence over provider defaults. Feature-specific copy stays
owned by the consuming application.
import { UiTextProvider } from "@ponti-studios/ui";
<UiTextProvider messages={{
"button.loading": "Chargement",
"pagination.previous": "Page précédente",
"pagination.next": "Page suivante",
}}>
<App />
</UiTextProvider>The shadcn-compatible registry is a curated set of independently installable
components plus the compiled Ponti theme. It is generated from source and
validated during pnpm run check; use the npm package for the complete,
maintained component library.
Common development workflows are available through the Makefile:
make build # regenerate token artifacts and typecheck
make check # build, then verify tokens/source contracts/lint
make test # run light and dark Storybook/vitest tests (implies build)
make storybook # build tokens and start StorybookThe pnpm run scripts (check, build, test, storybook, format) delegate to these targets for compatibility.
The package also ships a React + Vite starter wired to the current Ponti UI release. It includes the shared theme and component styles, strict TypeScript settings, and a first screen using the shared Button. The starter does not need Tailwind installed.
Create a project and install its dependencies:
pnpm dlx --package @ponti-studios/ui create-ponti-project my-new-project
cd my-new-project
pnpm devThe command refuses to write into a non-empty directory. Pass --no-install
to create the files without running pnpm install. From a local checkout, use
pnpm run create:project <directory>.
This starter is intentionally focused on web apps. Native apps use the same
token sources through the package's /native entry point and should keep their
platform-specific app setup in their own starter.
Releases are owned by release-please, not by hand-edited version numbers or manually pushed tags. The .github/workflows/publish.yml workflow runs after a successful validate push to main:
release-please— maintains a root-package release PR, updatingpackage.json,.release-please-manifest.json, andCHANGELOG.mdfrom Conventional Commit history.publish— when that release PR is merged, checks out the exact release tag and publishes it to npm.workflow_dispatchis the break-glass recovery path for a previously created release tag.
So the actual release flow is:
- Land commits using Conventional Commits —
fix:→ patch,feat:→ minor, andfeat!:or aBREAKING CHANGE:footer → major. Usefix:when the intended release is a patch. - Once on
main, find or wait for thechore(main): release ui X.Y.ZPR that Release Please opens or updates. - Review and merge it. That merge creates the
ui-v<version>tag; after validation succeeds, the release workflow publishes that exact tag automatically.
prepack (pnpm run check) runs before packing or publishing and is the last gate before anything reaches npm — see "Generated files" below for the failure mode that most commonly trips it.
src/styles/tokens/generated/** and .storybook/generated/** are produced only by make build (style-dictionary) from the DTCG source in src/styles/tokens/source/*.tokens.json. make check enforces this with git diff --exit-code -- src/styles/tokens/generated .storybook/generated after a fresh rebuild — if the committed file doesn't byte-for-byte match what the tool just produced, the check (and therefore prepack and the publish) fails. This has happened in practice when a repo-wide formatter (oxfmt) reformatted a generated CSS file directly; .oxfmtrc.json's ignorePatterns now excludes both generated directories specifically to prevent that recurring. If make check fails on a file you didn't intend to touch, run make build and commit the regenerated output — don't hand-format it back into place.
The package is public on npm, so consumers can install it without an organization token:
pnpm add @ponti-studios/uiImport the package once from your web app entry point to load the precompiled theme and component styles:
import "@ponti-studios/ui";Components remain available through their named entry points, such as
@ponti-studios/ui/primitives. Consumers do not need Tailwind to use the
components' built-in styles. Tailwind is only needed if the app itself wants to
write Tailwind utility classes. The /native entry remains platform-specific
and does not load the web stylesheet.
The package publishes compiled ESM and TypeScript declarations, so consumer
bundlers do not need to transpile the library source. The root import loads the
precompiled stylesheet; explicit CSS consumers can use
@ponti-studios/ui/styles.css.