The Anatomy of a Component

Every Svelte component lives in a .svelte file. These files have a simple structure that keeps your logic, markup, and styles together in one place. Understanding this structure is fundamental to everything we’ll build in BookIt.


What You’ll Learn

  • The three sections of a .svelte file
  • How script, markup, and style work together
  • Why colocating everything in one file is powerful

Open Your First Component

Let’s look at the homepage SvelteKit generated. Open src/routes/+page.svelte:

<!-- filename: src/routes/+page.svelte -->
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>

This is the simplest possible Svelte component — just HTML markup. But most components have three sections.


The Three Sections

A complete Svelte component can have up to three sections:

<script>
  // JavaScript logic goes here
</script>

<!-- HTML markup goes here -->

<style>
  /* CSS styles go here */
</style>

Let’s look at each one.

The Script Section

The <script> tag contains your component’s JavaScript. This is where you define variables, import other components, and write logic.

<script>
  import ServiceCard from '$lib/components/ServiceCard.svelte'
  
  let name = 'BookIt'
  let serviceCount = 5
</script>

Variables defined here are available in your markup. We’ll add reactivity to these variables in Module 4, but for now, think of them as regular JavaScript variables.

The Markup Section

The markup section is HTML with superpowers. It sits between the <script> and <style> tags (or can be the entire file if you don’t need the others).

You can use curly braces {} to insert JavaScript values:

<script>
  let name = 'BookIt'
</script>

<h1>Welcome to {name}</h1>
<p>We have {5 * 2} services available</p>

This renders:

  • Welcome to BookIt
  • We have 10 services available

Anything inside {} is JavaScript — variables, expressions, function calls. The compiler handles updating the DOM when values change.

The Style Section

The <style> tag contains CSS that’s automatically scoped to this component. Styles here won’t leak out and affect other parts of your app.

<script>
  let name = 'BookIt'
</script>

<h1>Welcome to {name}</h1>

<style>
  h1 {
    color: #2563eb;
    font-size: 2rem;
  }
</style>

That h1 style only applies to the <h1> in this component. If another component has an <h1>, it won’t be affected. This scoping is automatic — you don’t need to invent unique class names or use CSS modules.


A Real Example

Let’s see how these sections work together in a component we’ll build for BookIt. Here’s a preview of a service card:

<!-- filename: src/lib/components/ServiceCard.svelte -->
<script>
  let { name, price, duration } = $props()
</script>

<article class="card">
  <h3>{name}</h3>
  <p class="price">${price}</p>
  <p class="duration">{duration} minutes</p>
</article>

<style>
  .card {
    padding: 1.5rem;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: white;
  }
  
  h3 {
    margin: 0 0 0.5rem;
    font-size: 1.25rem;
  }
  
  .price {
    font-weight: 600;
    color: #059669;
  }
  
  .duration {
    color: #6b7280;
    font-size: 0.875rem;
  }
</style>

Notice how everything related to this component lives in one file:

  • Script: Receives name, price, and duration as props (we’ll cover $props() in Module 7)
  • Markup: Uses those values in the HTML structure
  • Style: Defines how the card looks, scoped to this component only

Section Order Doesn’t Matter

You can arrange the sections in any order. These are all valid:

<!-- Script first (most common) -->
<script>...</script>
<div>...</div>
<style>...</style>

<!-- Style first -->
<style>...</style>
<script>...</script>
<div>...</div>

<!-- Markup first -->
<div>...</div>
<script>...</script>
<style>...</style>

Most developers put <script> first because you typically want to see the data and logic before the markup that uses it. But it’s a matter of preference.


Sections Are Optional

You only need to include the sections you use:

<!-- Just markup — valid -->
<h1>Hello</h1>

<!-- Markup and style, no script — valid -->
<h1>Hello</h1>
<style>
  h1 { color: blue; }
</style>

<!-- Script and markup, no style — valid -->
<script>
  let name = 'World'
</script>
<h1>Hello {name}</h1>

Start with what you need. Add sections as your component grows.


Why Colocation Works

Keeping script, markup, and styles in one file might feel unusual if you’re used to separating HTML, CSS, and JavaScript. But there’s a good reason Svelte (and modern React, Vue) do it this way.

A component is a unit of UI. Everything about that unit — its logic, structure, and appearance — belongs together. When you need to change how a service card looks, you open one file, not three.

This is especially powerful as your app grows. BookIt will have dozens of components. Finding and updating them is straightforward when each component is self-contained.


Common Mistakes

Forgetting Curly Braces

<script>
  let name = 'BookIt'
</script>

<!-- ❌ Wrong — displays literal text "name" -->
<h1>Welcome to name</h1>

<!-- ✅ Correct — displays "BookIt" -->
<h1>Welcome to {name}</h1>

If you see variable names appearing literally in your page, you forgot the curly braces.

Using JavaScript Keywords as Variable Names

<script>
  // ❌ Wrong — "class" is a reserved word
  let class = 'premium'
  
  // ✅ Correct — use a different name
  let tier = 'premium'
</script>

Summary

Svelte components live in .svelte files with three optional sections: <script> for JavaScript logic, markup for HTML structure, and <style> for scoped CSS. Curly braces {} let you insert JavaScript values into your markup.

Key takeaways:

  • Script holds logic, markup holds structure, style holds appearance
  • Use {variable} to insert JavaScript values into HTML
  • Styles are automatically scoped to the component
  • All three sections are optional — use what you need

Next Steps

You understand the structure of a Svelte component. In the next lesson, Run Your First Dev Server, we’ll make sure your development environment is set up for a smooth workflow as we build BookIt.


See Also