LV1 · 0 XPLog in
Learning path

Lesson 1 of 5 · Full-Stack & Middleware Engineering

SvelteKit & TypeScript

SvelteKit builds full apps from reusable components; TypeScript helps catch type mistakes when you run the project's checks; runtime validation is still required.

This lesson is locked. You can read ahead, but finish earlier stops to earn progress.

Listen

Watch

Video coming soon

Read

Why leave handwritten pages?

Your Level 3 calculator manages selectors and DOM updates manually. A component framework connects data and interface more directly. A component bundles a reusable piece of interface and its behaviour. Svelte compiles components; SvelteKit adds routing, server endpoints, development tooling and deployment support. TypeScript checks the shapes of values before you run them.

You are learning this stack in a separate project, not replacing your working studio website. Keep the earlier product and its Git history intact. The final level combines a reactive page, hosted data and a validated server endpoint into one real product.

Scaffold in a deliberate location

Confirm Node LTS and npm work using node -v and npm -v. In VS Code's terminal, navigate to the parent workspace folder, not inside your existing website or node_modules. Use pwd on Mac or Get-Location in PowerShell to confirm.

sh
npx sv create svelte-studio

sv is Svelte's scaffolder. It downloads/runs a tool and asks about the starter project. Read the prompts; wording can change with versions. Choose the minimal SvelteKit template and TypeScript. Optional extras are not needed for the first rehearsal. If it offers to install dependencies, note whether it actually did.

sh
cd svelte-studio
npm install
npm run dev -- --open

npm install resolves the project's dependencies. If the wizard already installed them, rerunning it is normally unnecessary but does not create a second project. -- --open passes the open-browser option to the development command. Use the exact URL printed by the terminal; a busy port can produce a different one. Keep the terminal running. Stop with Ctrl+C when finished.

Find the files before editing

File or folderPurpose
package.jsonDependencies and named scripts
package-lock.jsonExact resolved dependency versions; keep it in Git
src/routes/+page.sveltePage for the root URL
src/routes/about/+page.sveltePage for /about, if you create it
src/routes/api/products/+server.tsServer endpoint for /api/products, created later
src/libShared components/helpers
node_modulesDownloaded packages, not your source; do not commit

The plus sign is meaningful. A file called page.svelte instead of +page.svelte will not become a SvelteKit route. A server endpoint is not a visible page component. You will add it in the middleware lesson.

Build one reactive rehearsal

In the generated src/routes/+page.svelte, study this small practice component. Use your own labels and explain each line before adapting it:

svelte
<script lang="ts">
  let count = $state(0);
  function addOne() {
    count = count + 1;
  }
</script>

<h1>Practice counter</h1>
<p>Count: {count}</p>
<button onclick={addOne}>Add one</button>

lang="ts" enables TypeScript inside the script. $state(0) creates reactive state with a starting numeric value of zero. Braces in markup display an expression. onclick={addOne} passes the function to run on click; onclick={addOne()} would call it immediately during setup instead.

First render: count is 0. First click: the function assigns 1 and Svelte updates the paragraph. Second click: count becomes 2. You do not manually select that paragraph or set textContent. Save the file; the development server refreshes the page as you edit. A browser reload normally resets this in-memory state to 0—it is not database persistence.

Extract a component when there is something to reuse

Create src/lib/PracticeCounter.svelte and move the rehearsal markup and script into it. In the root page:

svelte
<script lang="ts">
  import PracticeCounter from '$lib/PracticeCounter.svelte';
</script>

<h1>My practice studio</h1>
<PracticeCounter />

$lib points to src/lib. Render a second <PracticeCounter /> temporarily. Click only the first: each instance should keep its own state. This shows what “reusable component” means without a complicated application architecture. Remove the duplicate after the experiment if your product needs only one.

Read a type error instead of suppressing it

TypeScript infers a number from the initial 0. Temporarily try assigning "many" to count in your disposable rehearsal. The editor should report that a string is not assignable to a number. Read the reported file, line and types, then restore a numeric assignment. Do not use any or a type assertion to hide the disagreement.

A type declaration can describe a product:

ts
type Product = { name: string; price: number };
const sample: Product = { name: 'Notebook', price: 12 };

price: "12" would fail the type check. But data arriving from an HTTP request is not automatically trustworthy because your code has a Product type. Zod's runtime validation is a separate check taught later.

Run npm run check from the project root to check Svelte/TypeScript diagnostics, and npm run build to compile the production application. Do not assume a visible page or a running dev server means every type is correct. Some tools transpile code while type errors still exist; the explicit check matters.

Guided changes

  1. Predict the value after three clicks, then test it.
  2. Add a second small function that resets the counter to zero; connect your own reset control. Explain why assigning a number is valid.
  3. Change the increment from one to two. Confirm the displayed sequence, then reset and retest.
  4. Extract the component and confirm it still renders from the page.
  5. Reload and explain why the count resets. Your next database lesson will add durable storage; state alone does not do that.

Troubleshoot by evidence

SymptomCheck
Scaffold says folder existsChoose a new folder; do not overwrite a product you need
Missing package.jsonTerminal is in the wrong folder; cd into the generated app
Page doesn't change on clickCheck $state, event spelling and function reference
Component import failsExact path, filename case and .svelte extension
Browser cannot connectKeep dev server running and use its printed URL
Type error after changing a valueCompare the assigned value's type with the declared/inferred type

Ready for activity 4.1

Show the generated SvelteKit dependencies/scripts in package.json, a working reactive control and the terminal check result. Keep the component and lockfile in the synced project and commit the change using your earlier Git workflow. Do not submit node_modules or rely on copying the example without understanding the state trace. You should now be able to build a small reactive component and locate the page where it belongs.

Key terms

Component
A reusable piece of UI with its own markup and logic.
$state
A reactive value — change it and the UI updates.
TypeScript
JavaScript plus type annotations that catch errors early.
Scaffolding
Generating a starter project with one command.

Summary — copy into your notes

  • Apps are built from reusable components.
  • npx sv create scaffolds a SvelteKit app.
  • $state makes UI reactive.
  • TypeScript catches mistakes before they run.