Shared Nextide shadcn/ui components with a Vite playground.
Run npm run dev, then open http://127.0.0.1:5174 to view the component catalogue.
Install Node 26.9.0 (matching .node-version and CI), npm 12.0.2, and just. On Windows, install PowerShell 7.5+
with pwsh available on PATH.
just setupinstalls the frozen workspace lockfile and activates the tracked commit hook. For an already prepared checkout, runjust hooks-install.just pre-commitchecks the whole working tree: LOC limits, Prettier, full lint, the supply-chain watchlist, and TypeScript for the package, playground, and E2E. It uses installed tools without downloading, formatting, staging, or stashing. Type checks read source directly; they do not rebuild package declarations. Packed-package and browser qualification remain separate required CI checks.- Hook setup preserves custom
core.hooksPathand existing Git hooks. Integratejust pre-commitinto those hooks explicitly. The relative.githookspath applies to linked worktrees too; each worktree needs its own prepared tools. Whole-tree checks include unstaged edits; usegit -c core.hooksPath=/dev/null commitfor a deliberate one-off bypass, with CI still required before merge. just checkruns Prettier, Vite+ Oxlint, the supply-chain watchlist, LOC budgets, strict TypeScript checks, and packed-consumer qualification.just fmt,just fmt-check,just lint, andjust typecheckrun separately.just qualityruns full formatting, lint, and LOC checks.just correctnessruns correctness lint, the supply-chain watchlist, TypeScript, packed-consumer checks, the playground build, and native TesterArmy browser checks.just qualify-deployruns the same checks without publishing.just qualifyruns both groups.just checkkeeps its existing scope.just testruns native package acceptance: a packed tarball installed into an isolated npm consumer, public TypeScript/runtime exports, stylesheet/font assets, and known chart, scroll-state, and typography regressions. It needs npm registry access. Native tooling acceptance also invokes the real lint processes against disposable unsafe-operation, React Hooks, accessibility and workspace export probes.just test-integrationbuilds both workspaces and runs native TesterArmy E2E. First runnpm exec -- e2e-web install chromium(Linux CI adds--with-deps). The runner owns an isolated preview port and stops the server on exit. Focus withnpm exec -- e2e run tests/schedule.e2e.ts --target mobile.- Normal runs use committed recordings, strict read-only cache, zero retries, and unavailable model credentials. Tests use the built library through playground public exports at desktop (1440px) and mobile (390px) widths. The packed consumer separately proves installation without workspace links. No visible browser is opened.
- To author a changed recorded goal, set
UI_E2E_RECORD=1with saved ChatGPT OAuth, then run the affected case and one target with--grepand--max-failures 1. Usegpt-6-lunawith low reasoning. Inspect the generated.e2e/cacheJSON for sensitive data and literal origins before committing it unchanged. Clear the recording variable and replay without credentials; never edit cache outcomes.
The shared baseline sets complexity 12, function length 100, and source/test LOC limits. All source files meet the 600-line limit and browser suites meet the 900-line test limit; Oxlint counts nonblank lines, including comments, with no size exceptions. Accessibility exceptions explain specific SVG, forwarded-prop, or scroll-region semantics. Vite+ 1.1.0 owns lint and builds; TypeScript 7.0.2 owns compiler checks and declarations. The official React Hooks plugin retains three rules where native parity is incomplete. See migration evidence for scopes, diagnostic comparisons, retained checks and the approved release-age waiver. Prettier remains the formatter.
Correctness lint retains the configured React Hooks, accessibility, unsafe-operation, and accumulating-spread checks. Only explicit cosmetic rules (size/complexity, unused declarations, redundant syntax/types, and syntax preferences) are omitted; the complete rule sets still run in Quality. Type safety restrictions and the supply-chain watchlist remain required in both profiles.
Pull requests, main pushes, and the weekly Qualification workflow run full qualification. Manual runs select
full or deploy; deploy deliberately skips Quality. Both profiles share one
Node installation in Correctness / Package and browser. Full runs execute
Quality first; its full lint also covers correctness lint and the watchlist.
Qualification result requires the selected checks to succeed and reports the validated commit. The
package has no service deployment or database integration lane; its integration
surface is the packed consumer and playground browser suite.
The implementation guide from nextide-saas-meta is copied into docs/brand_assets/NEXTIDE_BRAND_AGENT_GUIDE.md. The large PDF and font zip stay in the meta repo for now.
packages/ui/src/components: primitive shadcn-compatible components.packages/ui/src/blocks: composed, prop-driven Nextide app patterns such asAppShell,NavigationPanel, andWorkflowStepper.packages/ui/src/hooks: shared interaction hooks such asuseStagedDrawerfor collapse/expand drawer motion.apps/playground: Vite consumer app for visual checks.docs/component-map.md: quick lookup map for shared primitives, blocks, hooks, and the upstream workflow.docs/responsive-support.md: required responsive acceptance widths and shared component behavior.
Start with docs/component-map.md when deciding whether a UI element should be imported from @nextide/ui, polished upstream, or created as a new shared component.
Use docs/responsive-support.md when changing layout,
navigation, overflow, or responsive component behavior.
To add components to the shared UI package, run:
npx shadcn@latest add button -c packages/uiThis will place the ui components in the packages/ui/src/components directory.
The package expects React 19 and Tailwind CSS 4. Install an exact release so a consumer upgrades deliberately:
npm install --save-exact @nextide/ui@2.6.2
npm install --save-dev --save-exact tailwindcss@4.3.1 @tailwindcss/vite@4.3.1Vite consumers need the Tailwind CSS Vite plugin. Import the shared stylesheet once in the application entry point, before app-specific styles:
// vite.config.ts
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"
export default defineConfig({ plugins: [react(), tailwindcss()] })// src/main.tsx
import "@nextide/ui/globals.css"
import "./app.css"Import only through the package's public subpaths:
import { AppShell } from "@nextide/ui/blocks/app-shell"
import { NavigationPanel } from "@nextide/ui/blocks/navigation-panel"
import { Button } from "@nextide/ui/components/button"
import { PopoverTrigger } from "@nextide/ui/components/popover"
import { useStagedDrawer } from "@nextide/ui/hooks/use-staged-drawer"The primitives use Base UI. When a Base UI trigger must adopt an existing
control, compose it with render; do not use Radix's asChild convention:
function DetailsTrigger() {
return (
<PopoverTrigger render={<Button variant="outline" />}>
Open details
</PopoverTrigger>
)
}Do not import from src or dist, and do not copy shared components into a
consumer. Fix reusable behavior here, publish a release, then update the
consumer's exact package version. See packages/ui/README.md
for the npm-facing quick start and docs/component-map.md
for the complete component map.
For local development against a sibling checkout, use a file dependency:
npm install "@nextide/ui@file:../nextide-ui/packages/ui"npm run check
npm exec -- e2e-web install chromium
npm run qualify
cd packages/ui
npm pack --dry-run --access publicnpm run check keeps its lint, typecheck, build, and targeted supply-chain scope.
Install Chromium once, then run the explicit, headless npm run qualify gate for packed-package consumer resolution and
representative Chromium interaction, accessibility, and responsive checks.
Use just qualify for all checks or just qualify-deploy for release validation.
Direct dependencies are pinned exactly. The workspace also enforces a seven-day release age (except native E2E packages),
strict peer dependencies, and explicitly approved dependency install scripts.
The library uses vp pack in unbundled mode, preserving public .js/.d.ts
subpaths, client directives, stylesheets and fonts. Native E2E remains the test runner;
there is no starter Vitest suite.
- Update
packages/ui/package.jsonand the install examples in both READMEs. - Run
just qualify-deployand the package dry run above (just qualifyincludes Quality too). - Merge the release commit and create a matching
v<version>tag on that merge. - Run Publish @nextide/ui manually with the exact tag.
Publication requires successful deploy qualification. Running either qualification profile alone never publishes a package.
Run just deadcode-setup once, then just deadcode. Reports are written to
.artifacts/deadcode/ and uploaded by the monthly/manual Dead-code report workflow.
Findings are advisory candidates for review; the command never deletes code.
Tool execution failures return a nonzero exit status. Knip can report recoverable
plugin loading errors without failing, so read diagnostics before trusting a report.
@nextide/ui public export paths are Knip entrypoints, including exports unused by the playground.