Vite
Plain Svelte + Vite, no router. Same primitives, same tokens — fewer moving parts for a prototype scene.
1. Scaffold
Terminal
pnpm create vite@latest my-prototype -- --template svelte-ts
cd my-prototype
pnpm install2. Install dependencies
Terminal
pnpm add bits-ui remixicon tailwind-variants tailwind-merge clsx
pnpm add -D @fontsource-variable/geist @fontsource-variable/geist-mono tailwindcss @tailwindcss/vite tw-animate-css3. Wire Tailwind v4
Vite needs the @tailwindcss/vite plugin; there’s no PostCSS step.
vite.config.ts
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [tailwindcss(), svelte()]
});4. Tokens and fonts
Copy theme.css and motion.css from Bloom’s src/lib/tokens/ into your project’s src/ tree and import them from your global stylesheet.
src/app.css
@import 'tailwindcss';
@import 'tw-animate-css';
@import 'remixicon/fonts/remixicon.css';
@import '@fontsource-variable/geist';
@import '@fontsource-variable/geist-mono';
@import './tokens/theme.css';
@import './tokens/motion.css';
@custom-variant dark ([data-theme='dark'] &);5. Path aliases (optional)
SvelteKit ships $lib for free; Vite doesn’t. If you want to mirror Bloom’s imports verbatim, add an alias to vite.config.ts pointing $lib at src/lib. Otherwise use relative imports — the components don’t care.
Caveats
- No file-based router means you roll your own navigation. Good for a single-screen prototype; friction for anything multi-route.
@sveltejs/kit-specific features ($app/navigation,$app/stores, server loaders) aren’t available. Bloom’s docs primitives useafterNavigate— if you lift them out, replace that with a plain store subscription or alocationwatcher.