#Web Development

Getting Started with Svelte 5: Building Your First Counter App

October 24, 20245 min read

Getting Started with Svelte 5: Building Your First Counter App

Svelte 5 introduces a revolutionary way to build web applications with its new Runes system. In this guide, we'll explore how to set up your first Svelte 5 project and build a simple counter application to demonstrate its powerful features.

Setting Up Your Development Environment

1. Creating a New Svelte 5 Project

First, let's create a new Svelte project using the latest version:

# Create a new project using create-svelte
npm create svelte@latest my-first-svelte-app

# Navigate to the project directory
cd my-first-svelte-app

# Install dependencies
npm install

2. Configure Your Project

Update your svelte.config.js to enable Runes:

const config = {
  kit: {
    // ... other config options
  },
  compilerOptions: {
    runes: true,
    legacy: false,
  },
};

export default config;

Building Your First Counter

1. Basic Counter Component

Let's create a simple counter using Svelte 5's new Runes system. Create a new file called Counter.svelte:

// src/lib/Counter.svelte
function Counter() {
  const count = $state(0);

  return (
    <div class="counter">
      <h1>Count: {count}</h1>
      <button onClick={()=> count++}>Increment</button>
      <button onClick={()=> count--}>Decrement</button>
    </div>
  );
}

export default Counter;

2. Adding Styles

Let's make our counter look better with some CSS:

// src/lib/Counter.svelte
function Counter() {
  const count = $state(0);

  return (
    <div class="counter">
      <h1>Count: {count}</h1>
      <div class="buttons">
        <button onClick={()=> count++}>
          Increment
        </button>
        <button onClick={()=> count--}>
          Decrement
        </button>
      </div>

      <style>
        .counter {
          text-align: center;
          padding: 2rem;
          margin: 2rem;
          border-radius: 8px;
          box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .buttons {
          display: flex;
          gap: 1rem;
          justify-content: center;
          margin-top: 1rem;
        }

        button {
          padding: 0.5rem 1rem;
          border: none;
          border-radius: 4px;
          background: #4CAF50;
          color: white;
          cursor: pointer;
          transition: background 0.3s ease;
        }

        button:hover {
          background: #45a049;
        }
      </style>
    </div>
  );
}

export default Counter;

3. Enhanced Counter with Features

Let's add more features to showcase Svelte 5's reactivity:

// src/lib/EnhancedCounter.svelte
function EnhancedCounter() {
  const count = $state(0);
  const history = $state([]);

  // Derived state using Runes
  const average = $derived(
    history.length > 0
      ? history.reduce((a, b) => a + b, 0) / history.length
      : 0
  );

  function updateCount(increment) {
    const newCount = count + increment;
    count = newCount;
    history = [...history, newCount];
  }

  function reset() {
    count = 0;
    history = [];
  }

  return (
    <div class="enhanced-counter">
      <h1>Enhanced Counter</h1>

      <div class="count-display">
        <h2>Current Count: {count}</h2>
        <p>Average: {average.toFixed(2)}</p>
      </div>

      <div class="buttons">
        <button onClick={()=> updateCount(-1)}>-1</button>
        <button onClick={()=> updateCount(-5)}>-5</button>
        <button onClick={reset}>Reset</button>
        <button onClick={()=> updateCount(5)}>+5</button>
        <button onClick={()=> updateCount(1)}>+1</button>
      </div>

      <div class="history">
        <h3>History</h3>
        <ul>
          {history.map((value, index) => (
            <li>Step {index + 1}: {value}</li>
          ))}
        </ul>
      </div>

      <style>
        .enhanced-counter {
          max-width: 600px;
          margin: 2rem auto;
          padding: 2rem;
          border-radius: 8px;
          box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }

        .count-display {
          text-align: center;
          margin: 2rem 0;
        }

        .buttons {
          display: flex;
          gap: 0.5rem;
          justify-content: center;
          margin: 1rem 0;
        }

        .history {
          margin-top: 2rem;
          padding: 1rem;
          background: #f5f5f5;
          border-radius: 4px;
        }

        ul {
          list-style: none;
          padding: 0;
          max-height: 200px;
          overflow-y: auto;
        }

        li {
          padding: 0.5rem;
          border-bottom: 1px solid #ddd;
        }
      </style>
    </div>
  );
}

export default EnhancedCounter;

Using the Counter in Your App

Update your src/routes/+page.svelte to use the counter:

import Counter from '$lib/Counter.svelte';
import EnhancedCounter from '$lib/EnhancedCounter.svelte';

function HomePage() {
  return (
    <div class="container">
      <h1>Welcome to Svelte 5!</h1>
      <Counter />
      <EnhancedCounter />

      <style>
        .container {
          max-width: 1200px;
          margin: 0 auto;
          padding: 2rem;
        }

        h1 {
          text-align: center;
          color: #333;
          margin-bottom: 2rem;
        }
      </style>
    </div>
  );
}

export default HomePage;

Key Concepts Demonstrated

  1. State Management with Runes: Using $state for reactive variables
  2. Derived Values: Using $derived for computed values
  3. Event Handling: Implementing click handlers and state updates
  4. Component Composition: Building and combining components
  5. Styling: Scoped CSS in Svelte components

Running Your Application

Start the development server:

npm run dev

Visit http://localhost:5173 to see your counter in action!

Next Steps

Now that you've built your first Svelte 5 application, here are some ways to enhance it:

  1. Add persistence using localStorage
  2. Implement undo/redo functionality
  3. Add animations using Svelte's transition system
  4. Implement different themes
  5. Add keyboard shortcuts

Debugging Tips

When working with Svelte 5's Runes system, keep these debugging tips in mind:

  1. Use the Svelte DevTools extension
  2. Console log state changes in effect callbacks
  3. Check the Network tab for any issues
  4. Use the built-in error boundary component

Conclusion

Building a counter application with Svelte 5 demonstrates the power and simplicity of the new Runes system. The reactive state management is intuitive, and the component model makes it easy to build complex applications from simple building blocks.

Resources

Happy coding with Svelte 5! 🚀

Kiran Kumar headshot

Kiran Kumar is a full-stack developer with 2 years of experience and over 20 freelance projects deployed, specializing in creating seamless applications and enhancing user experiences across the web.