Skip to content

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 CSS

How 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.

pnpm test:consumer
button-only10.9 KB raw · 3.6 KB gzip
date-picker28.8 KB raw · 8.4 KB gzip
app-shell30.8 KB raw · 9.1 KB gzip
charts59.6 KB raw · 18.2 KB gzip

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.

Exported symbols
ExportKindSignature
LucProvider4 documented props({ children, defaultTheme, storageKey, tooltipDelayDuration, }: LucProviderProps) => import("@types/react").JSX.Element

LucProvider props

Type: LucProviderProps

Values the compiler reads from the declaration.

LucProvider props
PropTypeDefaultNotes
childrenReactNode—
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.
Luc UI v1.0Overviewdark theme