793 words
4 minutes
From SvelteKit to Svelte Store: A Complete Guide for Beginners

In this comprehensive guide, we’ll explore SvelteKit and Svelte Store, two powerful tools that make building web applications a breeze. Whether you’re new to Svelte or coming from other frameworks, this guide will help you understand the fundamentals and best practices.

Understanding SvelteKit#

SvelteKit is more than just a framework - it’s a complete solution for building web applications. It provides:

  • File-based routing
  • Server-side rendering (SSR)
  • Static site generation (SSG)
  • API routes
  • Development environment with hot module replacement

Setting Up Your First SvelteKit Project#

Let’s start by creating a new SvelteKit project:

npx sv create my-svelte-app --template skeleton
cd my-svelte-app
npm install
npm run dev

The project structure will look like this:

my-svelte-app/
├── src/
│   ├── routes/
│   │   └── +page.svelte
│   ├── lib/
│   └── app.html
├── static/
└── svelte.config.js

Understanding the Svelte CLI#

The Svelte CLI (sv) is a powerful toolkit for creating and maintaining Svelte applications. Let’s explore its features in detail.

Basic Usage#

The basic syntax for creating a new project is:

npx sv create [options] [path]

Project Templates#

The --template option lets you choose from different project templates:

# Minimal setup
npx sv create my-app --template minimal

# Demo app with word guessing game
npx sv create my-app --template demo

# Library setup with svelte-package
npx sv create my-app --template library

TypeScript Support#

You can configure TypeScript support using the --types option:

# Use TypeScript (.ts files)
npx sv create my-app --types ts

# Use JSDoc for type annotations
npx sv create my-app --types jsdoc

# Skip TypeScript (not recommended)
npx sv create my-app --no-types

Additional Options#

Control the setup process with these flags:

# Skip the interactive add-ons prompt
npx sv create my-app --no-add-ons

# Skip dependency installation
npx sv create my-app --no-install

A typical workflow might look like this:

# Create a TypeScript project with the demo template
npx sv create my-project \
  --template demo \
  --types ts \
  --no-add-ons

Deep Dive into Svelte Store#

State management is crucial in modern web applications. Svelte Store provides three types of stores, each serving different purposes.

1. Writable Stores#

Writable stores are the most flexible type. Here’s a complete example:

// src/lib/stores/counter.ts
import { writable } from 'svelte/store';

export interface CounterStore {
  count: number;
  lastUpdated: Date;
}

function createCounterStore() {
  const { subscribe, set, update } = writable<CounterStore>({
    count: 0,
    lastUpdated: new Date()
  });

  return {
    subscribe,
    increment: () => update(store => ({
      count: store.count + 1,
      lastUpdated: new Date()
    })),
    reset: () => set({ count: 0, lastUpdated: new Date() })
  };
}

export const counterStore = createCounterStore();

2. Readable Stores#

Perfect for external data sources that can’t be modified by the application:

// src/lib/stores/time.ts
import { readable } from 'svelte/store';

export const time = readable(new Date(), function start(set) {
  const interval = setInterval(() => {
    set(new Date());
  }, 1000);

  return function stop() {
    clearInterval(interval);
  };
});

3. Derived Stores#

Derived stores depend on one or more other stores:

// src/lib/stores/derived-example.ts
import { derived } from 'svelte/store';
import { counterStore } from './counter';

export const doubledCount = derived(
  counterStore,
  $counter => $counter.count * 2
);

Building a Real-World Example#

Let’s create a todo list application that demonstrates these concepts:

// src/lib/stores/todos.ts
import { writable } from 'svelte/store';

export interface Todo {
  id: string;
  text: string;
  completed: boolean;
}

function createTodoStore() {
  const { subscribe, set, update } = writable<Todo[]>([]);

  return {
    subscribe,
    add: (text: string) => update(todos => [
      ...todos,
      { id: crypto.randomUUID(), text, completed: false }
    ]),
    toggle: (id: string) => update(todos =>
      todos.map(todo =>
        todo.id === id ? { ...todo, completed: !todo.completed } : todo
      )
    ),
    remove: (id: string) => update(todos =>
      todos.filter(todo => todo.id !== id)
    )
  };
}

export const todos = createTodoStore();

And here’s how to use it in a component:

<!-- src/routes/todos/+page.svelte -->
<script lang="ts">
  import { todos } from '$lib/stores/todos';
  import type { Todo } from '$lib/stores/todos';
  
  let newTodoText = '';

  function handleSubmit() {
    if (newTodoText.trim()) {
      todos.add(newTodoText);
      newTodoText = '';
    }
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <input
    bind:value={newTodoText}
    placeholder="What needs to be done?"
  />
  <button type="submit">Add Todo</button>
</form>

<ul>
  {#each $todos as todo (todo.id)}
    <li class:completed={todo.completed}>
      <input
        type="checkbox"
        checked={todo.completed}
        on:change={() => todos.toggle(todo.id)}
      />
      <span>{todo.text}</span>
      <button on:click={() => todos.remove(todo.id)}>Delete</button>
    </li>
  {/each}
</ul>

<style>
  .completed {
    text-decoration: line-through;
    opacity: 0.6;
  }
</style>

Best Practices and Tips#

  1. Store Organization

    • Keep stores in a dedicated directory (e.g., src/lib/stores)
    • Create separate files for different stores
    • Use TypeScript for better type safety
  2. Performance Optimization

    • Use derived stores instead of computing values in components
    • Unsubscribe from stores when components are destroyed
    • Use $: reactive statements wisely
  3. Error Handling

    • Implement error states in your stores
    • Use try-catch blocks for async operations
    • Provide meaningful error messages

Conclusion#

SvelteKit and Svelte Store provide a powerful and intuitive way to build modern web applications. By following these patterns and best practices, you can create maintainable and scalable applications. Remember to:

  • Start with simple stores and gradually add complexity
  • Use TypeScript for better type safety
  • Follow the Single Responsibility Principle
  • Test your stores thoroughly

The examples provided here are just the beginning. As you build more complex applications, you’ll discover more ways to leverage these tools effectively.

Additional Resources#

From SvelteKit to Svelte Store: A Complete Guide for Beginners
https://zxce3.net/posts/from-sveltekit-to-svelte-store-a-complete-guide-for-beginners/
Author
Memet Zx
Published at
2024-04-01