Application
Packaging
A real package, not a folder of TypeScript. Compiled ESM, generated declarations, curated subpath exports, one public stylesheet, and a consumer smoke test that proves a Button import stays a Button import.
Public entry points
The export map is curated by hand so internal adapter files are never reachable, and a verification script fails the build if a declared path does not exist in dist.
@luc/uiThe whole surface, for convenience@luc/ui/components/buttonOne component, one import@luc/ui/app-shellShell, sidebar, breadcrumbs, page header@luc/ui/workspacePanes, handles, inspector@luc/ui/url-stateCodecs and parameter sets (no React)@luc/ui/data-tableDataTable, columns, toolbar@luc/ui/chartsChart chrome and families@luc/ui/financial-chartLightweight Charts adapter@luc/ui/formsForm primitives and inputs@luc/ui/forms/react-hook-formOptional adapter (never auto-loaded)@luc/ui/datetimeCalendar, pickers, formatters@luc/ui/styles.cssTokens, base, utilities, chart and toast CSSHow a product consumes it
Two imports and one stylesheet. Tailwind is a consumer requirement, and it is stated rather than hidden: the package ships CSS-first tokens that your Tailwind build compiles.
app/globals.css
@import "tailwindcss";
@import "@luc/ui/styles.css";
/* The package styles itself: Tailwind scans its compiled modules. */The stylesheet carries tokens, base layer, utilities, chart styles and the toast skin. There is no second CSS file to remember and no source-scanning requirement pointing into another package's TypeScript.
a page component
import { Button } from "@luc/ui/components/button";
import { AppShell } from "@luc/ui/app-shell";
import { Workspace } from "@luc/ui/workspace";
import { useI18n } from "@/lib/i18n/provider";
// Compiles to the buttons, the shell and the panes: no ECharts,
// no Lightweight Charts, no date system.Declarations ship beside the code, client directives are preserved for React Server Components, and React stays a peer dependency.
Measured
From the consumer smoke test: each scenario is bundled with every third-party module external, so the numbers describe Luc UI's own graph rather than React's. The figures are a snapshot taken on 2026-10-09; re-run the command to reproduce them on your machine.
The assertions are the contract: a button-only bundle that contains an engine or the date library fails the test. Chart engines stay dynamically imported, so they never sit on a page that does not draw one.
Validation
The gates run in pnpm verify, and none of them trust the repository manifest — they check the artifact that would be published.
build:package
ESM plus declarations, one module per source module, then the CSS is copied and the source-scan path is re-pointed at the compiled output.
verify:package
Every declared path exists in source and in dist, the two maps declare the same subpaths, publint lints the packed tarball, and the tarball contains dist and no source.
test:consumer
Five entries — button, date picker, app shell, charts, barrel — bundled against the built package through the public subpaths only.
pnpm verify
Typecheck, lint, unit tests, the Showcase production build, and then the package gates above. Nothing is published by any of it.
API
Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.
| Export | Kind | Signature |
|---|---|---|
LucProvider | 4 documented props | ({ children, defaultTheme, storageKey, tooltipDelayDuration, }: LucProviderProps) => import("@types/react").JSX.Element |
LucProvider props
Type: LucProviderProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
children | ReactNode | — | |
defaultTheme? | ThemeMode | undefined | — | |
storageKey? | string | undefined | — | |
tooltipDelayDuration? | number | undefined | — | Delay before a hovered tooltip appears, shared by every tooltip in the tree so the app has one tooltip rhythm instead of one per component. |