What Is Svelte?

Chapter 1
What Svelte Is, the .svelte File, and Vite Setup
A framework that's actually a compiler — it disappears at build time, leaving tiny vanilla JS behind

Having worked through React, Angular, and Vue, Svelte is the genuine outlier — and the reason it's the perfect contrast piece. React, Angular, and Vue all ship a runtime to the browser: a framework library that runs alongside your code, doing reconciliation (a virtual DOM, or change detection) to figure out what to update. Svelte takes a fundamentally different path: it's a compiler. Your components are compiled at build time into small, surgical vanilla JavaScript that updates the DOM directly — and the framework itself mostly disappears, never shipped to the browser at all.

No Virtual DOM, No Runtime

When data changes in React or Vue, the framework re-runs render logic and diffs the result against the previous one to find what changed. Svelte's compiler instead analyzes your component ahead of time and generates precise code that updates exactly the right DOM node when exactly the right value changes — no diffing, no virtual DOM, no reconciliation library along for the ride. The practical results: very small bundles (no framework runtime weight) and excellent performance, with code that often looks like less than the equivalent in the other three.

"Svelte" the language vs "SvelteKit" the meta-framework
Svelte is the component language/compiler — Chapters 1–10 of this course. SvelteKit (Chapters 11–12) is its official meta-framework, adding file-based routing, server-side rendering, and data loading on top — the rough equivalent of Next.js for React or Nuxt for Vue. They're often used together, but Svelte the component framework is the foundation, so we start there.

The .svelte File

<!-- Greeting.svelte --> <script> let name = 'Philip'; </script> <h1>Hello, {name}!</h1> <style> h1 { color: #ff3e00; } </style>

A Svelte component is a .svelte file with three optional parts: a <script> block for logic, the markup (written directly, not wrapped in a <template> tag), and a <style> block. This is close to Vue's Single-File Component, with one notable difference: the markup is just there at the top level of the file — no enclosing template element. {name} is interpolation, the same single-brace style as React's JSX rather than Vue/Angular's double braces.

Scoped Styles by Default

The <style> block's rules are automatically scoped to this component only — no scoped attribute needed (Vue) and no setup at all (unlike React). Two components can both style h1 differently with zero collision. Svelte achieves this by adding a unique class to the component's elements at compile time, with no runtime cost.

Creating a Project with Vite

# scaffold a Svelte project (component-only, no SvelteKit) npm create vite@latest my-app -- --template svelte cd my-app npm install npm run dev

npm create vite@latest -- --template svelte scaffolds a plain Svelte + Vite project — ideal for learning the component framework on its own (we add SvelteKit later). npm run dev starts the dev server with live reload, exactly as it did for React and Vue. To start a full SvelteKit app instead, you'd run npx sv create my-app — but the bare Vite template keeps the early chapters focused.

  • src/main.js — the entry point; mounts the root App component.
  • src/App.svelte — the root component, the first one you'll edit.
  • index.html — the single real HTML page everything mounts into.

Mounting the Root Component

// src/main.js import { mount } from 'svelte'; import App from './App.svelte'; const app = mount(App, { target: document.getElementById('app') }); export default app;

mount(App, { target }) attaches the root component to an element in index.html — the Svelte 5 equivalent of React's createRoot(...).render(), Angular's bootstrapApplication(), and Vue's createApp(App).mount(). (Older Svelte code used new App({ target }) with the new keyword — replaced by the mount function in Svelte 5.)

This course teaches Svelte 5 with runes — older code looks different
Svelte 5 (late 2024) introduced runes ($state, $derived, $effect, etc.) — a new, more explicit reactivity model used throughout this course. Svelte 3/4 code looks meaningfully different: reactivity came from plain let declarations plus $: reactive statements, and props used export let. That older style still works in Svelte 5 for now but is being superseded — the same "modern vs legacy" split as Vue's Composition-vs-Options API or Angular's standalone-vs-NgModule. Recognize the old syntax in tutorials; this course uses runes.
ConceptReactVueSvelte
Runs in browser asLibrary + your codeLibrary + your codeCompiled vanilla JS (no runtime)
Update mechanismVirtual DOM diffVirtual DOM diffCompiled direct DOM updates
Component file.jsx.vue (with <template>).svelte (markup at top level)
Interpolation{value}{{ value }}{value}
Scoped stylesCSS Modules / lib<style scoped><style> (automatic)

Coding Challenges

Challenge 1

Create a new Svelte + Vite project, and edit App.svelte so it shows "Welcome, [your name]!" by interpolating a variable declared in the script block.

📄 View solution
Challenge 2

Build a Greeting.svelte component with all three blocks — a name variable in the script, an interpolated heading in the markup, and a scoped style coloring that heading.

📄 View solution
Challenge 3

Build a second component (e.g. Footer.svelte) and use it inside App.svelte by importing it in the script block and placing its tag in the markup — confirming a child component renders inside a parent.

📄 View solution

Chapter 1 Quick Reference

  • Svelte is a compiler — components compile to vanilla JS; no virtual DOM, no runtime shipped
  • .svelte file<script>, markup (at the top level, no <template>), and <style>
  • {value} — interpolation, single braces like React's JSX
  • <style> — automatically scoped to the component, no extra syntax
  • npm create vite -- --template svelte / npm run dev — scaffold and run
  • mount(App, { target }) — bootstraps the root component (Svelte 5)
  • This course uses Svelte 5 runes; older Svelte 3/4 used $: and export let
  • Next chapter: reactivity with the $state rune