@tsuki/svelte (0.3.0)
Installation
@tsuki:registry=https://git.d-v.cc/api/packages/tsuki/npm/npm install @tsuki/svelte@0.3.0"@tsuki/svelte": "0.3.0"About this package
@tsuki/svelte
Svelte 5 component library for the tsuki design system. Built on shadcn-svelte — same component API, same accessibility characteristics — with the visual surface re-themed against tsuki tokens and patched to match the brief (4 px buttons, 6 px cards, hairline borders, no resting shadows, shu vermillion accent).
What's included
| Component | Subpath |
|---|---|
| Accordion | @tsuki/svelte/accordion |
| Alert | @tsuki/svelte/alert |
| Avatar | @tsuki/svelte/avatar |
| Badge | @tsuki/svelte/badge |
| Button | @tsuki/svelte/button |
| Calendar | @tsuki/svelte/calendar |
| Card | @tsuki/svelte/card |
| Checkbox | @tsuki/svelte/checkbox |
| Command | @tsuki/svelte/command |
| Context Menu | @tsuki/svelte/context-menu |
| Dialog | @tsuki/svelte/dialog |
| Dropdown Menu | @tsuki/svelte/dropdown-menu |
| Form | @tsuki/svelte/form |
| Input | @tsuki/svelte/input |
| Kbd | @tsuki/svelte/kbd |
| Label | @tsuki/svelte/label |
| Popover | @tsuki/svelte/popover |
| Radio Group | @tsuki/svelte/radio-group |
| Select | @tsuki/svelte/select |
| Separator | @tsuki/svelte/separator |
| Sheet | @tsuki/svelte/sheet |
| Sidebar | @tsuki/svelte/sidebar |
| Skeleton | @tsuki/svelte/skeleton |
| Slider | @tsuki/svelte/slider |
| Sonner | @tsuki/svelte/sonner |
| Switch | @tsuki/svelte/switch |
| Table | @tsuki/svelte/table |
| Tabs | @tsuki/svelte/tabs |
| Tooltip | @tsuki/svelte/tooltip |
All also available from the barrel:
import { Button, Card, Dialog } from '@tsuki/svelte';
Install
# .npmrc
@tsuki:registry=https://git.d-v.cc/api/packages/tsuki/npm/
//git.d-v.cc/api/packages/tsuki/npm/:_authToken=${GITEA_NPM_READ_TOKEN}
pnpm add @tsuki/svelte @tsuki/tokens @tsuki/fonts @tsuki/icons-svelte
pnpm add -D tailwindcss@^4
bits-ui@2.18.1 is a peer dependency. pnpm will prompt for it on install — accept the suggestion, or add it explicitly with pnpm add bits-ui@2.18.1.
The Form component also follows shadcn-svelte and peers on Formsnap/Superforms:
pnpm add formsnap@^2.0.1 sveltekit-superforms@^2.30.1
Use
Step 1 — wire the CSS (order matters):
/* app.css */
@import '@tsuki/fonts/css'; /* MUST come first: declares @font-face */
@import '@tsuki/svelte/styles'; /* tailwind + tokens + shadcn alias layer */
Step 2 — render components:
<script lang="ts">
import * as Button from '@tsuki/svelte/button';
import * as Card from '@tsuki/svelte/card';
import { Icon, ChevronDown } from '@tsuki/icons-svelte';
</script>
<Card.Root>
<Card.Header>
<Card.Title>Welcome</Card.Title>
</Card.Header>
<Card.Content>
<Button.Root>
Continue
<Icon icon={ChevronDown} />
</Button.Root>
</Card.Content>
</Card.Root>
Step 3 — theme switching. Set data-theme="dark" (or data-theme="light") on <html>. Tsuki tokens swap automatically. shadcn-svelte's own .dark-class convention also works — both selectors are supported.
document.documentElement.dataset.theme = 'dark';
What's different from upstream shadcn-svelte
The components are vendored from shadcn-svelte@1.2.7 and edited in-place per the tsuki brief:
- Radius tiers — buttons / inputs / checkboxes / badges / kbd / tabs triggers use
var(--radius-sm)(4 px); cards / dialog content / tabs list / tooltips usevar(--radius-md)(6 px). Replaces the single--radiuswithcalc()offsets pattern. - Focus rings are 2 px (was 3 px) per the brief's "2 px outline, 2 px offset".
- No resting shadows. Card, Dialog content, and Button outline have
shadow-xsremoved. Cards use a 1 px border instead ofring-1. - Dialog backdrop is
rgba(27, 22, 17, 0.32)(light) /rgba(0, 0, 0, 0.55)(dark) with nobackdrop-filterblur. The brief forbids glassmorphism. - Tabs underline (line variant) uses
--primary(shu) instead of neutral foreground. - Table row states use the explicit
mutedsubtle-surface token instead of translucent fills. - Badge defaults to
radius-smrather thanrounded-4xl. Use a class override for pill shape:<Badge.Badge class="rounded-full">.
tailwind-variants configs are exported alongside the components (buttonVariants, badgeVariants, tabsListVariants) for consumer-side composition.
Develop
pnpm install
pnpm build # svelte-package -> dist/, then cp styles/
pnpm dev # examples/ Vite app on http://localhost:5235
pnpm test # button-variants assertions + tree-shake guard
pnpm check # svelte-check
The examples/ directory boots a Vite + Svelte 5 app that renders every component in both light and dark, serving as the manual QA surface.
Re-running shadcn-svelte init
If shadcn-svelte ships a major update and we want to re-vendor:
# 1. Compute the preset code from the new shadcn-svelte version
pnpm install
node scripts/encode-preset.mjs
# → outputs a base62 code
# 2. Scaffold a throwaway app
pnpm dlx sv@latest create _setup --template minimal --types ts \
--add tailwindcss=plugins:none --install pnpm --no-dir-check
# 3. Run shadcn-svelte init in it
cd _setup
pnpm dlx shadcn-svelte@latest init \
--preset <code-from-step-1> \
--css src/routes/layout.css \
--lib-alias '$lib' --components-alias '$lib/components' \
--utils-alias '$lib/utils' --hooks-alias '$lib/hooks' \
--ui-alias '$lib/components/ui' --overwrite
# 4. Add the components
pnpm dlx shadcn-svelte@latest add button input card checkbox switch badge tabs tooltip sonner dialog avatar label separator form --yes
# 5. Copy back to ../src/lib/, re-apply the tsuki patches (see git log for
# the B.2/B.3 commit), update pinned versions in package.json.
_setup/ is gitignored, so the throwaway app won't pollute the repo.
Releasing
export GITEA_NPM_TOKEN=<your-gitea-personal-access-token>
pnpm install
pnpm test
pnpm build
npm version <patch|minor|major>
npm publish # honors publishConfig.registry
git push --follow-tags
The repo's .npmrc reads GITEA_NPM_TOKEN from the environment — never commit the token. The publishConfig.registry in package.json pins the publish target. Bump @tsuki/tokens, @tsuki/fonts, and @tsuki/icons-svelte first if a release of this package needs newer versions of the peer-deps.
License
No license declared at v0.1 (closed source). Upstream shadcn-svelte is MIT.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @internationalized/date | 3.12.1 |
| clsx | 2.1.1 |
| mode-watcher | 1.1.0 |
| svelte-sonner | 1.1.1 |
| tailwind-merge | 3.6.0 |
| tailwind-variants | 3.2.2 |
Development Dependencies
| ID | Version |
|---|---|
| @lucide/svelte | 1.16.0 |
| @sveltejs/package | ^2.3.7 |
| @sveltejs/vite-plugin-svelte | ^7.0.0 |
| @tailwindcss/vite | ^4.0.0 |
| @testing-library/svelte | ^5.2.4 |
| @tsuki/fonts | ^0.1.0 |
| @tsuki/icons-svelte | ^0.1.0 |
| @tsuki/tokens | ^0.1.0 |
| @types/node | ^25.9.0 |
| bits-ui | 2.18.1 |
| esbuild | ^0.24.0 |
| formsnap | 2.0.1 |
| jsdom | ^25.0.0 |
| shadcn-svelte | 1.2.7 |
| svelte | ^5.55.0 |
| svelte-check | ^4.0.0 |
| sveltekit-superforms | 2.30.1 |
| tailwindcss | ^4.0.0 |
| tw-animate-css | 1.4.0 |
| typescript | ^5.6.0 |
| vaul-svelte | ^1.0.0-next.7 |
| vite | ^7.0.0 |
| vitest | ^4.0.0 |
Peer Dependencies
| ID | Version |
|---|---|
| @tsuki/fonts | ^0.1.0 |
| @tsuki/icons-svelte | ^0.1.0 |
| @tsuki/tokens | ^0.1.0 |
| bits-ui | 2.18.1 |
| formsnap | ^2.0.1 |
| shadcn-svelte | ^1.2.7 |
| svelte | ^5.0.0 |
| sveltekit-superforms | ^2.30.1 |
| tailwindcss | ^4.0.0 |
| tw-animate-css | ^1.4.0 |
| vaul-svelte | ^1.0.0-next.7 |