The intention of this repo is to be a simple place to start any new SvelteKit project without having to go through all the initial boilerplate steps. We use it internally for our projects and also push updates to an open source Github repo. If you'd like to use it either clone or fork this repo and do as you'd like!
This repo contains a modern SvelteKit application built with the latest tools and best practices. We have made the following choices with this StarterKit:
@tailwindcss/viteThe intention is that this repo provides a production-ready StarterKit that you can deploy immediately and start building features - no "beginning of the project" boilerplate needed!
git clone <your-repo-url>
cd sveltekit-starterkit
npm install
# or
pnpm install
# or
yarn install
cp .env.example .env
# Edit .env with your configuration
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
SvelteKit uses a file-based router similar to Next.js but with its own conventions. Here's how this project is organized:
src/
├── lib/
│ ├── components/
│ │ ├── ui/ # shadcn-svelte components
│ │ └── ThemeToggle.svelte
│ ├── styles/
│ │ ├── tailwind.css # Main Tailwind styles
│ │ ├── typography.css # Typography utilities
│ │ └── fonts.css # Font definitions
│ ├── utils/ # Utility functions
│ └── types/ # TypeScript types
├── routes/
│ ├── +layout.svelte # Root layout
│ ├── +page.svelte # Home page
│ └── +page.server.ts # Server-side data loading
├── app.html # HTML shell
└── hooks.server.ts # Server hooks
To create a production version of your app:
npm run build
You can preview the production build with:
npm run preview
npm run dev - Start development server with hot reloadingnpm run build - Build for productionnpm run preview - Preview production build locallynpm run check - Run SvelteKit and TypeScript checksnpm run lint - Run ESLint and Prettier checksnpm run format - Format code with Prettiernpm run test - Run all tests (unit + integration)npm run test:unit - Run unit tests with Vitestnpm run test:integration - Run browser tests with PlaywrightThis repo includes a production-ready Docker setup with multi-stage builds for optimal image size and security.
The included Dockerfile uses Node.js 22 Alpine and follows best practices:
Before building, set up your environment variables:
# Copy example environment file
cp .env.example .env
# Edit .env with your production values
Build and run:
# Build the image
docker build -t your-app:latest .
# Run with docker-compose
version: "3.8"
services:
app:
image: your-app:latest
container_name: your-app
env_file: .env
ports:
- "3000:3000"
environment:
- NODE_ENV=production
restart: unless-stopped
Required environment variables for production:
ORIGIN - The domain your site will be accessed from (e.g., https://yoursite.com)SENTRY_ORG - Your Sentry organization (optional, for error tracking)SENTRY_PROJECT - Your Sentry project (optional, for error tracking)PUBLIC_API_URL - Public API URL for client-side requestsThe project includes Helm charts in web_chart/ for Kubernetes deployment using our Polar Labs helm StarterKit from helm.polarlabs.ca. The setup assumes:
The project includes Bitbucket Pipelines configuration that can be adapted for other CI/CD systems. Our deployment strategy focuses on simplicity and speed:
Branch Model:
Pipeline Steps:
Quality Gates:
svelte-checkDeployment Variables: Set these in your CI/CD system:
DOCKER_REGISTRY - Your container registryKUBE_CONFIG - Kubernetes configurationSENTRY_AUTH_TOKEN - For source map uploadsThis StarterKit uses the latest Tailwind CSS 4 with native CSS support and shadcn-svelte for components. This combination provides both utility-first styling and high-quality, accessible components out of the box.
Native CSS Support: Tailwind 4 uses native CSS features, eliminating the need for PostCSS plugins:
@import 'tailwindcss' imports the framework directly@theme blocks for custom design tokens@utility for custom utilities@layer for organizing stylesCustom Design System: Our configuration includes:
We use shadcn-svelte for accessible, customizable UI components:
import Button from '$lib/components/ui/button/button.svelte'; import * as Card from
'$lib/components/ui/card'; import Badge from '$lib/components/ui/badge/badge.svelte';
<Button variant="outline" size="lg">Click me</Button>
<Card.Root>
<Card.Header>
<Card.Title>Card Title</Card.Title>
<Card.Description>Card description</Card.Description>
</Card.Header>
<Card.Content>
<p>Card content goes here</p>
</Card.Content>
</Card.Root>
The StarterKit includes these shadcn-svelte components:
Semantic HTML with utility classes for enhanced typography:
<h1 class="display-1">Large Display Heading</h1>
<h2>Semantic Heading 2</h2>
<p class="text-lead">Lead paragraph for introductions</p>
<p>Regular paragraph text</p>
<p class="text-small text-muted-foreground">Small muted text</p>
Colors are defined using CSS custom properties with automatic dark mode:
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
/* ... more colors */
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
/* ... dark variants */
}
Use mode-watcher for theme switching:
import {(setMode, mode)} from 'mode-watcher';
<button onclick={() => setMode($mode === 'dark' ? 'light' : 'dark')}> Toggle Theme </button>
Add custom utilities in tailwind.css:
@utility container {
margin-inline: auto;
padding-inline: var(--container-padding);
max-width: var(--breakpoint-xl);
}
@utility text-balance {
text-wrap: balance;
}
tailwind.cssThe project configuration is streamlined with modern tooling:
vite.config.ts - Build tool configuration with Tailwind, Sentry, and sitemap pluginssvelte.config.js - Svelte preprocessing and adapter configurationtailwind.css - Tailwind 4 configuration with design tokens and utilitiescomponents.json - shadcn-svelte component configurationeslint.config.js - Flat ESLint configuration with TypeScript and Svelte rulesplaywright.config.ts - End-to-end testing configurationVite Plugins:
@tailwindcss/vite - Native Tailwind CSS 4 support@sentry/sveltekit - Error tracking and performance monitoringsitemapPlugin - Automatic sitemap generationPostCSS: Minimal configuration (Tailwind 4 handles most preprocessing natively)
TypeScript: Strict configuration with SvelteKit path aliases
The project includes comprehensive testing setup with modern tools:
# Run unit tests
npm run test:unit
# Run with watch mode during development
npx vitest
Features:
# Run integration tests
npm run test:integration
# Run specific browsers
npx playwright test --project=chromium
npx playwright test --project=firefox
Features:
Playwright Test Generation: Use the Playwright VS Code extension to generate tests:
npm run dev)Component Testing:
// Example unit test
import { render } from '@testing-library/svelte';
import Button from '$lib/components/ui/button/button.svelte';
test('renders button with correct variant', () => {
const { getByRole } = render(Button, {
props: { variant: 'outline' }
});
expect(getByRole('button')).toHaveClass('border');
});
Before deploying, update these items:
static/ directorysite.webmanifest with your app detailsapp.html title and meta tagsvite.config.tsDockerfile