Skip to main content
Components are the building blocks of Svelte applications. They’re written in .svelte files using a superset of HTML that combines JavaScript logic, HTML markup, and CSS styles in a single file.

Component structure

A Svelte component consists of up to three sections — all of which are optional:
MyComponent.svelte
You can have a component with just markup, just a script, or any combination. Svelte is flexible.

The <script> block

The <script> block contains JavaScript (or TypeScript with lang="ts") that runs when a component instance is created. Variables declared or imported at the top level are automatically available in the component’s markup.

Basic example

Button.svelte
In this example:
  • count is reactive state created with the $state rune
  • increment is a function that modifies the state
  • Both are accessible in the markup below

TypeScript support

Add the lang="ts" attribute to use TypeScript:
Todo.svelte

Reactivity with runes

Svelte’s reactivity system is powered by runes — special function-like constructs that the compiler understands:

$state

Creates reactive state that triggers UI updates when changed

$derived

Computes values that automatically update when dependencies change

$effect

Runs side effects when reactive dependencies change

$props

Declares component properties passed from parent components
Example using multiple runes:
Calculator.svelte

The <script module> block

A <script> tag with a module attribute runs once when the module first evaluates, rather than for each component instance. This is useful for:
  • Shared constants
  • Utility functions
  • Module-level state shared across all instances
Component.svelte
Each time this component is created, total increments and is shared across all instances.

Exporting from module blocks

You can export bindings from <script module> blocks, and they become exports of the compiled module:
utils.svelte
Other files can import these:
You cannot export default from a module block — the default export is always the component itself.
Legacy note: In Svelte 4, module scripts used <script context="module">. Svelte 5 uses the simpler <script module> syntax.

Markup

Markup in Svelte components is HTML enhanced with special syntax for:
  • Template expressions: {value}
  • Control flow: {#if}, {#each}, {#await}
  • Event handlers: onclick={handler}
  • Bindings: bind:value={variable}
  • Directives: use:action, transition:fade

Example with template features

UserList.svelte
This demonstrates:
  • Two-way binding with bind:checked
  • Conditional rendering with {#if}
  • List rendering with {#each}
  • Class toggling with class:inactive

The <style> block

CSS inside a <style> block is automatically scoped to the component. Svelte adds unique identifiers to elements and styles, ensuring they don’t leak to other components.

Scoped styles example

Card.svelte
The selectors .card, h2, and p only apply to elements within this component instance. Other components can use the same class names and element selectors without conflicts.

Global styles

If you need to apply styles globally, use the :global() modifier:

Complete example

Here’s a complete component that demonstrates all three sections working together:
TodoItem.svelte

Key takeaways

  • All sections are optional — use only what you need
  • Script runs per instance — fresh state for each component
  • Script module runs once — shared across all instances
  • Styles are scoped — no CSS conflicts between components
  • Markup is enhanced HTML — with powerful template features

Next steps

Runes

Learn about Svelte’s reactivity system in depth

Template syntax

Explore control flow, bindings, and directives

Component communication

Pass data between parent and child components

Styling

Advanced styling techniques and patterns