02 - Project Setup & Structure
Creating a Project
npx sv create my-app
cd my-app
npm install
npm run devnpm run dev starts a local server at http://localhost:5173. Changes auto-reload.
Project Structure
After creating a project, you'll see:
my-app/
├── src/
│ ├── routes/ ← Your pages live here
│ │ ├── +page.svelte ← Home page (/)
│ │ └── +layout.svelte ← Root layout (wraps all pages)
│ ├── lib/ ← Your reusable code
│ │ ├── components/ ← Shared components
│ │ └── server/ ← Server-only code (DB, secrets) — PROTECTED
│ ├── app.html ← HTML shell (you rarely edit this)
│ ├── hooks.server.ts ← Server hooks (auth, logging)
│ └── hooks.client.ts ← Client hooks (optional — only for global error handling)
├── static/ ← Static files (favicon, images)
├── svelte.config.js ← SvelteKit config
├── vite.config.ts ← Vite bundler config
├── tsconfig.json ← TypeScript config
└── package.jsonThe Two Most Important Folders
src/routes/ — Your Pages
This is where you spend most of your time. Each folder = a URL:
src/routes/
├── +page.svelte → / (home page)
├── +layout.svelte → wraps all pages (nav, footer)
├── +layout.server.ts → loads data for the layout (server-only, e.g. auth user)
├── about/
│ └── +page.svelte → /about
├── blog/
│ └── +page.svelte → /blog
└── contact/
└── +page.svelte → /contactsrc/lib/ — Your Reusable Code
Components, utilities, types, stores — anything shared across pages. Import using the $lib alias:
<!-- Instead of: import Card from '../../../lib/components/Card.svelte' -->
<script>
import Card from '$lib/components/Card.svelte';
</script>$lib always points to src/lib/ no matter where you import from.
src/lib/server/ — Protected Server Code
src/lib/server/ is a special folder — SvelteKit prevents it from being imported in client-side code. If you try, the build fails. This is where you put database connections, API keys, and any code that must never reach the browser.
Only server-only files can import from it:
+page.server.ts,+layout.server.ts,+server.ts,hooks.server.ts✅+page.svelte,+page.ts❌ (build error)
The rule: if it has server in the name, it stays on the server.
Special Files in a Route
Each route folder can have these files (all optional except +page.svelte):
| File | What it does | Runs on |
|---|---|---|
+page.svelte |
The page UI | Browser |
+page.ts |
Loads data for the page | Server + Browser |
+page.server.ts |
Loads data (server only) + form actions | Server only |
+layout.svelte |
Wraps child pages with shared UI | Browser |
+layout.ts |
Loads data for the layout | Server + Browser |
+layout.server.ts |
Loads data for layout (server only) | Server only |
+error.svelte |
Error page | Browser |
+server.ts |
API endpoint (no UI) | Server only |
Don't memorize this — you'll learn each one in upcoming lessons. For now, just know:
.sveltefiles = UI (what the user sees).tsfiles = logic (data loading, form handling, API endpoints)serverin the name = runs only on the server (safe for secrets/DB)
Your First Page
Create src/routes/+page.svelte:
<!-- src/routes/+page.svelte -->
<h1>Hello SvelteKit!</h1>
<p>This is the home page.</p>That's it. Visit http://localhost:5173 and you'll see it. No imports, no configuration.
Adding a Second Page
Create src/routes/about/+page.svelte:
<!-- src/routes/about/+page.svelte -->
<h1>About</h1>
<p>This is the about page.</p>
<a href="/">← Back home</a>Visit http://localhost:5173/about. Navigation between pages is instant — SvelteKit handles it client-side.
The app.html Shell
src/app.html is the HTML template that wraps everything:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body>
%sveltekit.body%
</body>
</html>%sveltekit.head%— SvelteKit injects CSS, meta tags, etc.%sveltekit.body%— SvelteKit injects your rendered page
You rarely need to edit this file.
Key Takeaways
src/routes/= pages. Folder structure = URL structuresrc/lib/= shared code. Import with$lib/+page.svelte= what the user sees+page.server.ts= server logic (data, forms)npm run dev= start developing
Next Lesson
Now that you have a project, let's learn how routing works in detail — dynamic routes, parameters, and navigation.