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
- State Management with Runes: Using
$state
for reactive variables - Derived Values: Using
$derived
for computed values - Event Handling: Implementing click handlers and state updates
- Component Composition: Building and combining components
- 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:
- Add persistence using localStorage
- Implement undo/redo functionality
- Add animations using Svelte's transition system
- Implement different themes
- Add keyboard shortcuts
Debugging Tips
When working with Svelte 5's Runes system, keep these debugging tips in mind:
- Use the Svelte DevTools extension
- Console log state changes in effect callbacks
- Check the Network tab for any issues
- 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! 🚀