Skip to main content
Advertisement

17.2 Environment Setup

There are two main ways to set up a Svelte development environment: using SvelteKit (the full-stack framework) or a plain Svelte + Vite combination. For most real-world projects, SvelteKit is recommended.


Prerequisites

# Check Node.js version (18+ required)
node --version # v18.x.x or higher

# Check npm version
npm --version # 8+ recommended

# Install VS Code extension
# "Svelte for VS Code" (svelte.svelte-vscode)

SvelteKit is the official application framework for Svelte. It supports routing, SSR, SSG, API endpoints, and more.

# Create a SvelteKit project
npm create svelte@latest my-svelte-app

# Interactive prompts
# ┌ Welcome to SvelteKit!
# │
# ◆ Which Svelte app template?
# │ ○ SvelteKit demo app
# │ ● Skeleton project ← recommended
# │ ○ Library project
# │
# ◆ Add type checking with TypeScript?
# │ ○ Yes, using TypeScript syntax
# │ ● Yes, using JavaScript with JSDoc comments
# │ ○ No
# │
# ◆ Select additional options
# │ ☑ Add ESLint for code linting
# │ ☑ Add Prettier for code formatting
# │ ☑ Add Playwright for browser testing
# │ ☑ Add Vitest for unit testing

cd my-svelte-app
npm install
npm run dev

Starting the Development Server

npm run dev              # Dev server (localhost:5173)
npm run dev -- --open # Auto-open browser
npm run build # Production build
npm run preview # Preview the build

Option 2: Plain Svelte + Vite

Use this when you only need a simple SPA (Single Page Application) without SvelteKit.

# Create a Svelte project with Vite template
npm create vite@latest my-svelte-app -- --template svelte

# TypeScript version
npm create vite@latest my-svelte-app -- --template svelte-ts

cd my-svelte-app
npm install
npm run dev

Project Directory Structure (SvelteKit)

my-svelte-app/
├── src/
│ ├── app.html # HTML entry point (base HTML shell)
│ ├── app.css # Global CSS
│ ├── lib/ # Reusable code ($lib alias)
│ │ ├── components/ # Shared components
│ │ ├── stores/ # Svelte stores
│ │ └── utils/ # Utility functions
│ └── routes/ # File-based routing
│ ├── +layout.svelte # Root layout
│ ├── +page.svelte # / route
│ └── about/
│ └── +page.svelte # /about route
├── static/ # Static files (images, fonts, etc.)
├── tests/ # Test files
├── svelte.config.js # Svelte/SvelteKit config
├── vite.config.js # Vite config
└── package.json

src/app.html

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
  • %sveltekit.head%: Content injected by SvelteKit (title, meta, link tags)
  • %sveltekit.body%: The actual page content
  • %sveltekit.assets%: Path to static assets

Key svelte.config.js Settings

// svelte.config.js
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Preprocessor settings (TypeScript, SCSS, etc.)
preprocess: vitePreprocess(),

kit: {
// Adapter (change based on deployment target)
adapter: adapter(),

// Path aliases
alias: {
$lib: 'src/lib',
$components: 'src/lib/components',
$stores: 'src/lib/stores',
},

// CSRF protection
csrf: {
checkOrigin: true,
},

// Environment variable prefix
env: {
publicPrefix: 'PUBLIC_',
},
},

// Svelte compiler options
compilerOptions: {
// Enable Runes mode globally (Svelte 5)
// runes: true, // Uncomment to apply Runes to all files
},
};

export default config;

TypeScript Setup

When using TypeScript, tsconfig.json is automatically generated:

// tsconfig.json
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
}

TypeScript Svelte Component

<!-- Counter.svelte -->
<script lang="ts">
interface Props {
initialCount?: number;
label?: string;
}

let { initialCount = 0, label = 'Counter' }: Props = $props();
let count = $state(initialCount);

function increment(): void {
count++;
}

function reset(): void {
count = initialCount;
}
</script>

<div>
<h2>{label}: {count}</h2>
<button onclick={increment}>+1</button>
<button onclick={reset}>Reset</button>
</div>

Vite Configuration

// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
plugins: [sveltekit()],

// Dev server settings
server: {
port: 5173,
open: true,
},

// Build optimization
build: {
target: 'es2020',
sourcemap: true,
},

// Test settings (Vitest)
test: {
include: ['src/**/*.{test,spec}.{js,ts}'],
environment: 'jsdom',
globals: true,
setupFiles: ['./src/setupTests.ts'],
},
});

VS Code Extensions and Settings

Essential Extensions

  1. Svelte for VS Code (svelte.svelte-vscode): Syntax highlighting, autocomplete, type checking
  2. ESLint (dbaeumer.vscode-eslint): Code quality
  3. Prettier (esbenp.prettier-vscode): Code formatting

.vscode/settings.json

{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
},
"svelte.enable-ts-plugin": true,
"typescript.preferences.importModuleSpecifier": "shortest"
}

.prettierrc

{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"plugins": ["prettier-plugin-svelte"],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}

Adapters Overview

SvelteKit uses Adapters to deploy to different platforms. An adapter converts the build output to fit a specific deployment environment.

AdapterPackageUse Case
adapter-auto@sveltejs/adapter-autoAuto-detect platform (default)
adapter-node@sveltejs/adapter-nodeNode.js server
adapter-static@sveltejs/adapter-staticStatic site (SSG)
adapter-cloudflare@sveltejs/adapter-cloudflareCloudflare Pages
adapter-vercel@sveltejs/adapter-vercelVercel
adapter-netlify@sveltejs/adapter-netlifyNetlify
// svelte.config.js - static adapter example
import adapter from '@sveltejs/adapter-static';

export default {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: '404.html',
precompress: false,
strict: true,
}),
prerender: {
handleHttpError: 'warn',
},
},
};

Building Your First Component

After creating the project, let's update the first page:

<!-- src/routes/+page.svelte -->
<script>
import Counter from '$lib/Counter.svelte';
</script>

<main>
<h1>My First Svelte App</h1>
<Counter initialCount={5} label="Visit Count" />
</main>

<style>
main {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
</style>
<!-- src/lib/Counter.svelte -->
<script>
let { initialCount = 0, label = 'Counter' } = $props();
let count = $state(initialCount);
</script>

<div class="counter">
<p>{label}: <strong>{count}</strong></p>
<button onclick={() => count--}>-</button>
<button onclick={() => count++}>+</button>
</div>

<style>
.counter {
display: inline-flex;
align-items: center;
gap: 1rem;
padding: 1rem 2rem;
border: 2px solid #ff3e00;
border-radius: 8px;
}

button {
width: 36px;
height: 36px;
background: #ff3e00;
color: white;
border: none;
border-radius: 50%;
font-size: 1.2rem;
cursor: pointer;
}
</style>

Development Commands Reference

npm run dev          # Start dev server
npm run build # Production build
npm run preview # Preview the build
npm run check # TypeScript + Svelte type check
npm run lint # Run ESLint
npm run format # Run Prettier
npm run test # Run Vitest unit tests
npm run test:e2e # Run Playwright E2E tests

Pro Tips

Tip 1: Environment Variable Management

# .env file
DATABASE_URL=postgresql://... # Server-only (never exposed)
PUBLIC_API_URL=https://api.example.com # Safe for client
<script>
import { PUBLIC_API_URL } from '$env/static/public';
import { DATABASE_URL } from '$env/static/private'; // Server components only
</script>

Tip 2: Use Path Aliases

<!-- Use aliases instead of relative paths -->
<script>
// Not recommended
import Button from '../../../lib/components/Button.svelte';

// Recommended
import Button from '$lib/components/Button.svelte';
</script>

Tip 3: SvelteKit Inspector

Click a component in dev mode to jump directly to its source file:

# Set environment variable
SVELTE_INSPECTOR=true npm run dev

Or configure in svelte.config.js:

import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

export default {
preprocess: vitePreprocess(),
vitePlugin: {
inspector: {
holdMode: true, // Only activate when holding a key
},
},
};

Summary

ToolRole
SvelteKitRouting, SSR, API, full-stack support
ViteBundler, dev server, HMR
svelte.config.jsSvelte compiler and SvelteKit settings
vite.config.jsVite build settings
AdapterDeployment platform targeting
$lib aliasShorthand for src/lib path

The next chapter dives into Svelte 5's reactivity system and the Runes API.

Advertisement