polaris-shadcn
v0.4.0
Published
Shopify Polaris design language for shadcn — a shadcn-compatible component registry for embedded Shopify admin apps.
Maintainers
Readme
polaris-shadcn
shadcn/ui components styled with Shopify Polaris design tokens, distributed as a standard shadcn registry — install the theme and components with the regular shadcn CLI.
Getting started
polaris-shadcn requires Tailwind CSS v4 and a path alias (@/*).
1. Install Tailwind CSS v4
Skip this step if you already have Tailwind v4 set up.
npm install tailwindcss @tailwindcss/viteAdd the plugin to vite.config.ts:
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [tailwindcss()],
});If you don't already have a CSS entrypoint, create app/app.css (or src/app.css) with the Tailwind v4 entrypoint import (@import "tailwindcss";), then import it in your root component (app/root.tsx for React Router apps):
// app/root.tsx
import "./app.css";/* app/app.css */
@import "tailwindcss";See the Tailwind CSS Vite guide for full details.
2. Configure path alias
The CLI requires an @/* import alias. Add to tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./app/*"]
}
}
}And to vite.config.ts:
import path from "path";
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "./app"),
},
},
});Adjust ./app to ./src if your project uses a src/ directory.
3. Initialize the Polaris theme
npx shadcn@latest init https://unpkg.com/polaris-shadcn@latest/r/theme.jsonThis runs non-interactively (no base-library or preset prompts), needs no registry configuration (the theme item is self-contained), and:
- writes
components.json - places the theme at
<project root>/polaris-shadcn.cssand injects@import "../polaris-shadcn.css";into your CSS entry point — no manual import step - installs
lib/utilsplusclsxandtailwind-merge - skips all upstream shadcn defaults (
extends: "none"): no default:roottokens, fonts, or extra dependencies
The injected import assumes your CSS entry point lives one directory below the project root (
src/index.cssorapp/app.css). Adjust the@importpath by hand if yours doesn’t.Tip:
curl -sf https://unpkg.com/polaris-shadcn@latest/r/registry.json > /dev/nullfirst to confirm the registry is reachable — a failed init can leave a half-writtencomponents.jsonbehind (delete it or re-run with-f).
4. Register the namespace (after init)
npx shadcn@latest registry add @polaris-shadcn=https://unpkg.com/polaris-shadcn@latest/r/{name}.jsonComponent items declare their registry dependencies as @polaris-shadcn/..., so this step is required before adding components. Pinning the namespace URL to an exact version ([email protected]) pins all transitive registry dependencies too.
4b. TypeScript projects
Components are authored in .tsx (JS projects receive auto-stripped .jsx). The <s-*> element types come from @shopify/polaris-types — installed automatically as a dev dependency, but it must be listed in your tsconfig types to apply:
{
"compilerOptions": {
"types": ["@shopify/polaris-types"]
}
}Shopify’s React Router app template already ships this entry — no action needed there.
5. Add components
npx shadcn@latest add @polaris-shadcn/button @polaris-shadcn/card @polaris-shadcn/tabs
# or, without the namespace configured:
npx shadcn@latest add https://unpkg.com/polaris-shadcn@latest/r/button.jsonComponents are added to app/components/ui (or src/components/ui), per the aliases in your components.json. Registry dependencies (shared utils, the theme, data-table → table) and npm dependencies are resolved automatically.
Bare names install upstream shadcn/ui.
npx shadcn@latest add buttonfetches the upstream shadcn button — always use the@polaris-shadcn/prefix (or a full URL) for polaris-shadcn components.
Useful flags: -o to overwrite existing files, --dry-run to preview changes.
6. Load Polaris web components
Most components render Polaris web components (<s-button>, <s-modal>, …), defined by polaris.js. Shopify’s React Router app template already loads it via AppProvider — skip this step there. Everywhere else, add to your HTML before the app entry module:
<script src="https://cdn.shopify.com/shopifycloud/polaris.js"></script>GitHub registry
The repo itself is also a GitHub registry, so items can be installed straight from source without npm:
npx shadcn@latest add storeatlas/polaris-shadcn/button(Component items declare registry dependencies as @polaris-shadcn/..., so register the namespace — step 4 — first. The committed r/ output also makes https://raw.githubusercontent.com/storeatlas/polaris-shadcn/main/r/{name}.json usable as an alternative namespace URL.)
Demo app (this repo)
npm install
npm run devVite will start the dev server (defaults to http://localhost:5173).
Screenshots
npm run screenshotsRuns the Playwright screenshot pipeline and writes images to ./screenshots/.
How it works
src/components/ui/*contains the shadcn-style wrapper components used by the demo app. These are plain-JS copies; the distributable source of truth is the typed.tsxinregistry/templates/(checked bynpm run registry:check).- Polaris web components are loaded via the script tag in
index.html. - The demo theme layer lives in
src/index.css. registry.jsondefines the shadcn registry; the component sources it points at live inregistry/templatesand are copied into consuming apps by the shadcn CLI.npm run registry:buildbuilds the distributable registry JSON intor/(committed — run it after editingregistry.jsonor any template;prepackalso rebuilds it on publish). It's served from the published npm package via unpkg, withraw.githubusercontent.comas a host-agnostic fallback.- Demo routes are registered in
src/demos/registry.jsxand rendered bysrc/pages/DemoPage.jsx.
Adding a new demo
- Create or update a wrapper in
src/components/ui/. - Add a new entry to
demoRegistryinsrc/demos/registry.jsxwith both the wrapper and Polaris-only demos.
