Installation
Install editable component source and the shared styles once.
Requirements
Use React 19, TypeScript, Tailwind CSS 4, and an @/* alias pointing to src/*. Follow the complete Next.js or Vite path for framework configuration. Your coding agent can do this setup and install the skill: send it the agent prompt from Getting started.
Create components.json
First complete the Prepare the application section for Next.js or Vite. Run commands from the application directory.
Write components.json yourself instead of running shadcn init. It writes a shadcn theme into your global CSS that replaces the kit’s colors, borders and radii, and it installs a second Button and packages the kit does not use. This is the complete file for Next.js:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks",
"utils": "@/siteplane/system/utils/cn"
},
"registries": {
"@siteplane": "https://ui.siteplane.io/registry/{name}.json"
}
}For Vite, rsc is false and tailwind.css is src/index.css; the Vite guide shows the complete file. Keep tailwind.config empty for Tailwind 4. The aliases must match the TypeScript and bundler configuration. Siteplane UI’s registry declares explicit targets under src/siteplane, so changing aliases.ui does not relocate its source; keep the documented src layout and @/* alias.
If your application already uses shadcn, keep its components.json and add the Siteplane UI registry to registries, next to any entries already there. Siteplane UI’s installed source does not depend on the style or aliases.utils values it holds.
{
"registries": {
"@siteplane": "https://ui.siteplane.io/registry/{name}.json"
}
}This address uses the documentation site you are reading. Components and their dependencies are available from its registry without an account.
Add components
pnpm dlx shadcn@4.18.0 add @siteplane/button @siteplane/input @siteplane/dialogWith npm, use npx shadcn@4.18.0 add @siteplane/button @siteplane/input @siteplane/dialog. Component pages also let you choose and copy either command.
The registry installs required source and package dependencies transitively under src/siteplane. Field is included with Input: install @siteplane/input, then import from @/siteplane/components/field. Shared base styles, action icons, and locale support are dependencies rather than extra catalog pages.
Load styles and typography
In a new application, replace the contents of the global CSS with these two lines. The starter styles of create-next-app and create-vite set their own colors and fonts, which would override the kit’s.
@import "../siteplane/system/styles/base.css";
@source "..";For Vite’s src/index.css, use @import "./siteplane/system/styles/base.css"; and @source ".";. Import the global CSS once from the application entry.
The kit stylesheet imports Tailwind itself, along with the shared tokens, recipes and motion styles, and its first line sets the order of the cascade layers. In an application with its own styles, make it the first import and remove the separate @import "tailwindcss". A Tailwind import above it sets that order without the kit’s siteplane layer, and the kit’s rules then override the utilities you pass in className. Keep your own rules below the import and make sure Tailwind scans your application code. A theme in the same file, such as the one shadcn init writes, also applies to Siteplane UI components and replaces the kit’s colors, borders and radii.
The kit is set in Inter. Install the font and import it once from the application entry (npm: npm install @fontsource-variable/inter):
pnpm add @fontsource-variable/interimport "@fontsource-variable/inter";To set the kit in another typeface, such as Geist or the system font, follow Typeface.
Siteplane UI Pro
Siteplane UI Pro adds ready-made patterns; sections and templates follow. Pro is free for now, and if you get it now, you get all updates. The patterns install with the shadcn CLI and your license key from a separate registry, on top of the setup above. Get a license on the Pro page. After checkout, the license page and your license email show the same steps with your key filled in.
Add the key to .env.local, which the Next.js and Vite templates keep out of version control:
SITEPLANE_LICENSE_KEY=your-license-keyAdd the @siteplane-pro registry to components.json, next to any entries already in registries:
{
"registries": {
"@siteplane-pro": {
"url": "https://ui.siteplane.io/api/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${SITEPLANE_LICENSE_KEY}"
}
}
}
}The shadcn CLI reads the key from .env.local, or from .env in a project set up that way, and sends it with each request to this registry. Install a pattern:
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-blockOther patterns install the same way under the name in their page address, for example @siteplane-pro/metric-card for Metric Card. Each example on a Pattern page installs as its own item, named like the free examples: @siteplane-pro/metric-card-demo for the example at the top of the page and @siteplane-pro/metric-card-<example-id>-example for the others. Every Pattern page shows these commands, and pnpm dlx shadcn@4.18.0 search @siteplane-pro lists every pattern and example in @siteplane-pro. The free components a pattern uses install along with it. The source of patterns, sections and templates is licensed under the Siteplane UI Pro License; the free components use the Siteplane UI License.
Install or copy an example
Install a default example and its component dependencies directly:
pnpm dlx shadcn@4.18.0 add @siteplane/button-demoDefault examples use <component>-demo; other examples use <component>-<example-id>-example. The three application examples are also installable; their pages show the command.
To copy manually, open a component page, expand the code below its preview, and copy the complete TSX file. Save it as src/components/example.tsx, then render its default export. The page’s Markdown version links the same file as raw TSX.
When copying manually, install the components named in the example’s imports. Registry installation resolves these dependencies for you.
Stability and deprecations
From 1.0, Siteplane UI versions follow semantic versioning. The stable API is what these docs describe. It covers the registry items, the components with their parts, props and types, the hooks and providers on their pages, the documented data-slot attributes and the CSS tokens on the customization pages. Documented aliases, such as the shadcn names DialogContent and AlertDialogContent, are part of it. Everything else that an installed file exports is internal, for example helpers and class names that other kit files import, and can change in any release.
Minor and patch releases keep the documented API working. When a prop or a part is renamed, the old name stays as a deprecated alias: it keeps working, and your editor marks it as deprecated and names the replacement. A renamed value, such as variant="brand" on Badge, which is now accent, keeps working too, but TypeScript can't mark a string value, so the component page names the deprecated values. The changelog lists every deprecation with its replacement. Deprecated aliases are removed in the next major version, 2.0. Fixes and refinements of the look ship in minor and patch releases. Installed source changes only when you install again, so you decide when a release reaches your application.
Pin a release
The @siteplane namespace always serves the current catalog. To install the fixed source of a release, including its Siteplane UI dependencies, use its versioned URL. The current release is 1.4.2:
pnpm dlx shadcn@4.18.0 add https://ui.siteplane.io/registry/v/1.4.2/button.jsonReplace button with any item name from the 1.4.2 catalog. The release manifest records the source commit and SHA-256 hashes for the registry items and public build. Earlier releases remain available under /registry/v/0.1.0/, /registry/v/0.1.1/, /registry/v/0.1.2/, /registry/v/0.1.3/, /registry/v/0.1.4/, /registry/v/0.1.5/, /registry/v/0.2.0/, /registry/v/0.2.1/, /registry/v/0.3.0/, /registry/v/0.3.1/, /registry/v/0.3.2/, /registry/v/0.3.3/, /registry/v/0.3.4/, /registry/v/0.3.5/, /registry/v/0.3.6/, /registry/v/0.3.7/, /registry/v/0.3.8/, /registry/v/0.3.9/, /registry/v/0.3.10/, /registry/v/0.3.11/, /registry/v/0.3.12/, /registry/v/0.3.13/, /registry/v/0.3.14/, /registry/v/0.4.0/, /registry/v/0.4.1/, /registry/v/0.4.2/, /registry/v/0.4.3/, /registry/v/0.4.4/, /registry/v/0.4.5/, /registry/v/0.4.6/, /registry/v/0.4.7/, /registry/v/0.4.8/, /registry/v/0.4.9/, /registry/v/0.4.10/, /registry/v/0.4.11/, /registry/v/0.4.12/, /registry/v/0.4.13/, /registry/v/0.4.14/, /registry/v/0.5.0/, /registry/v/0.6.0/, /registry/v/0.6.1/, /registry/v/0.6.2/, /registry/v/0.6.3/, /registry/v/1.0.0/, /registry/v/1.1.0/, /registry/v/1.2.0/, /registry/v/1.3.0/, /registry/v/1.3.1/, /registry/v/1.4.0/ and /registry/v/1.4.1/. Dependency versions are declared in each item; commit your application lockfile as well as installed source. Future updates use a new release version.
Siteplane UI installs @base-ui/react at an exact version. Keep that version, including in automated dependency updates, and upgrade Base UI only when a Siteplane UI release does: Field and the date, time and color controls build on internal Base UI modules, which Base UI may change in any release.
Content Security Policy
Siteplane UI renders no inline <script> or <style> element of its own, but React Aria and Motion add a <style> element while the page runs. Under a Content Security Policy that allows styles only with a nonce, pass that nonce to SiteplaneUIProvider. The provider hands it to React Aria through a <meta property="csp-nonce"> element in the head, to the kit's lists and swaps that use Motion's popLayout mode, and to Base UI's CSPProvider, which puts it on any inline element your own Base UI parts render. An application that uses Motion's popLayout mode itself passes the same nonce to Motion's MotionConfig. Without such a policy, leave the nonce out.
The policy must also allow style attributes, with style-src-attr 'unsafe-inline'. Base UI, React Aria and the kit set positions, sizes and visually hidden styles in style attributes, and a nonce covers only <script> and <style> elements, never an attribute. Without the directive, a Checkbox shows a second, native checkbox beside it and Slider thumbs sit at the start of the track. Scripts and <style> elements keep their nonce protection. The directive works from Chrome 75, Firefox 108 and Safari 15.4; older browsers apply style-src to style attributes, so the attributes stay blocked there.
In Next.js, the proxy creates a nonce for each request and sends the policy. This is the proxy from the Next.js Content Security Policy guide with the style-src-attr directive added:
import { NextRequest, NextResponse } from "next/server";
export function proxy(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
const isDev = process.env.NODE_ENV === "development";
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic'${isDev ? " 'unsafe-eval'" : ""};
style-src 'self' 'nonce-${nonce}';
style-src-attr 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`;
const contentSecurityPolicyHeaderValue = cspHeader
.replace(/\s{2,}/g, " ")
.trim();
const requestHeaders = new Headers(request.headers);
requestHeaders.set("x-nonce", nonce);
requestHeaders.set(
"Content-Security-Policy",
contentSecurityPolicyHeaderValue,
);
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});
response.headers.set(
"Content-Security-Policy",
contentSecurityPolicyHeaderValue,
);
return response;
}
export const config = {
matcher: [
{
source: "/((?!api|_next/static|_next/image|favicon.ico).*)",
missing: [
{ type: "header", key: "next-router-prefetch" },
{ type: "header", key: "purpose", value: "prefetch" },
],
},
],
};The root layout reads the nonce and passes it to the provider. This is the layout from the Next.js guide with the provider added:
import "@fontsource-variable/inter";
import "./globals.css";
import { headers } from "next/headers";
import { SiteplaneUIProvider } from "@/siteplane/system/provider/siteplane-ui-provider";
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const nonce = (await headers()).get("x-nonce") ?? undefined;
return (
<html lang="en" data-theme="light">
<body>
<SiteplaneUIProvider nonce={nonce}>{children}</SiteplaneUIProvider>
</body>
</html>
);
}Reading the request headers renders every page when it is requested, which a nonce needs: each response carries a new one.
Updating and manual installation
Installed files belong to your application. Commit or back up your changes, inspect the incoming source, and reconcile local edits before reinstalling with overwrite.
Inspect incoming files without changing your application:
pnpm dlx shadcn@4.18.0 view @siteplane/button
pnpm dlx shadcn@4.18.0 add @siteplane/button --dry-run
pnpm dlx shadcn@4.18.0 add @siteplane/button --diffAfter reviewing and saving your local work, apply an intentional replacement:
pnpm dlx shadcn@4.18.0 add @siteplane/button --overwriteReinstall every Siteplane UI item you use in the same update: name them all in one add command with --overwrite. The items of a release work together, and from 1.1 the base stylesheet styles each part through a class that components installed from an earlier release don't render.
Replace pnpm dlx with npx for npm. Dependencies may also be updated: inspect the entire resulting diff and run your application’s relevant checks. These commands use the current catalog; to stay on a fixed version, pin a release. Keep reviewed source in your own version control to reproduce or roll back your application.
shadcn add installs the package dependencies through your package manager. pnpm records the exact versions the kit names, while npm writes its ^ range, such as ^1.7.0. To keep the exact versions with npm, add save-exact=true to the project's .npmrc before you install, or set the versions in package.json back to the exact numbers after each update.
For a manual install, open the Registry JSON link below a component’s install command, such as Button JSON, and the base support JSON. Copy every file to its declared target and install its package dependencies. Repeat for registryDependencies, including base styles. The registry command is the shorter and less error-prone path; copying only the visible component implementation omits required CSS and helpers.
The JSON files array contains each file’s content and target; dependencies names npm packages, and registryDependencies names additional registry items. Follow those dependencies recursively and preserve the installed LICENSE and TRADEMARKS notices. The Read the installed source link on each component page concatenates all files for inspection; do not paste it into one TSX file.