Why I Built My Website with Svelte
This article mentions several Svelte concepts. See the reference section for official documentation links.
The frontend world is a mess. Everyone knows it. Sometimes you spend hours just deciding on a framework to use. If you pick React, you’re going to spend another hour setting up your dependencies.
React did good work historically. It helped us move from technologies like
jQuery to composable UI. However, I didn’t use React for this website for a
variety of reasons. The primary reason was that simple state changes can balloon
into hooks, context, and useEffect logic that’s easy to break and hard to
reason about.
Managing state in React often feels needlessly verbose. For simplicity purists like myself, the indirection React forces at every step feels like a burden. Sometimes it even feels like managing state in the raw DOM would be more straightforward. In fact, for simple tasks like parsing markdown for a blog, I’d rather work with raw DOM manipulation than wrestle with React’s abstraction. At least with raw DOM, the behavior is predictable and direct. This is exactly why Svelte resonates with me. It gives you that ‘close-to-the-metal’ feeling while still providing a modern developer experience.
I’m not a junior developer reacting against React’s learning curve. I’m an engineer who values simplicity and believes our tools should empower us, not get in our way.
The aim of this post isn’t to bore you with endless tutorials. This isn’t a hackathon. It is to explain why, if you have a deep love for web fundamentals, you should use a framework like Svelte.
The Turning Point
I first got curious about Svelte after a chat with a fellow developer who followed me on X. He posted about rewriting his website in Svelte and why he loved it. I replied, skeptically, “You can’t love Svelte so much, man. It’s the same with all frameworks.”
He challenged me: “Try it out, and I promise you’ll never use React again.”
At first, I wasn’t convinced. I expected Svelte to be just another flavor of the
same mess (more hooks, more context wrappers, and the usual boilerplate ritual).
But when I finally got my hands dirty, it felt different. The reactivity model
was almost invisible. Suddenly, state management no longer required a dozen
lines of code for something trivial. I found myself actually enjoying the craft
again instead of wrestling with useEffect or passing state through components
like an overcomplicated maze.
Today, I can confirm that his prophecy has come to pass. I now use Svelte to build almost everything, no matter how easy or complex. I recently used it to build a Two-way rental marketplace for a client and Svelte handled it without breaking a sweat. Talk about complex state management.
The Svelte Philosophy
When I started web development, I loved HTML. I’m sure we all did. Then came JS, a little more complex, but we were still going with the flow. Then finally came React. This is when it started to feel like the HTML and CSS you learned were more of a ritual than knowledge you would apply in real life.
Enter Svelte. It strips away the complexities React introduced in favor of the
familiar trio: HTML, CSS, and JS. Did I hear someone whisper JSX? Forget about
it.

Svelte’s core philosophy is Developer Experience and building on Web Standards. You cannot go wrong building with Svelte because it uses a majority of what the web consortium recommends as a standard. (NB: The reason for majority is that no framework can do 100%. That would mean writing raw JS, CSS, and HTML.)
To prove how intuitive this philosophy is, I recently introduced SvelteKit to a former colleague. He picked it up in a single week. We immediately competed in a hackathon where he built the entire frontend while I handled the backend.
Svelte introduces very little custom syntax. Mostly just
Runes and specific tags like
<svelte:head> or
{ @html }. This makes it incredibly
easy to pick up because you are mostly writing standard JavaScript and
TypeScript.
Reactivity: Runes vs. Hooks
Reactivity in Svelte 5 often collapses into two lines of code. Things that would
need useEffect or a mix of memoization and callbacks in React are usually
handled cleanly with
onMount and the
$derived rune.
Effects on the frontend are inherently messy. Even in Svelte, $effect isn’t
something you reach for by default. Most of the time, onMount, $derived, and
a few other runes cover what you’d use useEffect for, and they do it with far
less ceremony.
Using Svelte results in writing less code because the model for applying logic
is straightforward. Writing a simple hello world in both frameworks is
identical, but try to build something as trivial as a calculator and watch your
React code rise like bread in an oven.
React: To update just the name property, you have to recreate the entire state object. You also need to write a handler to extract the value from the event.
import { useState } from "react";
export default function UserProfile() {
const [user, setUser] = useState({ name: "Guest", active: false });
// You have to manually merge state
const updateName = (e) => {
setUser({ ...user, name: e.target.value });
};
return (
<div>
<input value={user.name} onChange={updateName} />
<button onClick={() => setUser({ ...user, active: !user.active })}>
Toggle Status
</button>
<p>
{user.name} is {user.active ? "Active" : "Inactive"}
</p>
</div>
);
}
Svelte 5: No spread operators. No manual event handlers just to extract a value. You simply bind the input and mutate the object property directly.
<script>
let user = $state({ name: 'Guest', active: false });
</script>
<div>
<input bind:value={user.name} />
<button onclick={() => user.active = !user.active}>
Toggle Status
</button>
<p>{user.name} is {user.active ? 'Active' : 'Inactive'}</p>
</div>
This article by Dan Abramov goes into detail on UI component principles using React as an example, but many of the problems he identifies are solved more elegantly by Svelte’s design.
The Ecosystem and The “Wrapper” Tax
The common argument against Svelte is the ecosystem. Here are my two cents: The React ecosystem is the largest in the world, second only to npm itself. BUT, a lot of things you need external packages for in React are built directly into Svelte. You don’t need a Jupiter-sized ecosystem when the framework actually does its job.
Furthermore, if you are one of those who need special packages, the vast ecosystem of vanilla JavaScript libraries works with Svelte out-of-the-box.
“But what about React-specific packages?” This is a fair point. To use them, you often need a compatibility layer, which adds a small bundle-size penalty. However, I’ve found this cost is often offset by Svelte’s lean core and the fact that you need far fewer external state-management libraries to begin with. For the best performance, I recommend seeking out native Svelte alternatives, which are growing rapidly.
The Kit Superpowers
I’ll admit that vanilla Svelte has a lot of features better than vanilla React, but let’s talk about the meta-framework: SvelteKit.
SvelteKit is built to get out of the way. Some settings are done with just a
single line of code, e.g., export const prerender = true, as opposed to
Next.js where you have to juggle getStatic, getDynamic, and whatever flavor
of the month they are using. “You can take your Next.js configuration
questions to Vercel’s documentation, thanks”
I’m not going to bore you by preaching about modular architecture which is a
universal truth in software engineering. But I will say this: Svelte
encourages it by default. The $lib alias and the folder structure mean your
architecture is clean from day one, not something you have to configure five
plugins to achieve.
Question: What do Svelte and Vite have in common?
They provide sensible defaults that let you build immediately, not spend days configuring build tools.
Forms and Headers
Building multi-step forms is something you look forward to in Svelte. With
SvelteKit’s progressive enhancement, you have no business manually preventing
default; you simply submit clean formData to the backend.
Additionally, writing with Svelte lets you adopt the best security practices because you control more parts of your code. An example is the Cache-Control header. If you write React/Next.js for 5 years, you might forget how these headers are handled. In Svelte, you write code for these explicitly, making them easier to debug.
Performance and Deployment
Now, let’s talk about the Next.js dev server. The Next.js dev server’s performance has been a common pain point in the community, particularly with larger applications. While recent versions have improved, the sluggish HMR (Hot Module Replacement) during development became a real productivity drain for many developers, myself included.
Anyway, back to reality; the slowdown wasn’t just an inconvenience. It’s one of the reasons developers started looking for alternatives. The growing complexity surrounding React became too much, and people sought after simpler, more productive frameworks.
I know what you’re thinking: “Nothing is perfect, right?” When a tool actually solves your specific problems well, you don’t need a thousand alternatives.
Svelte’s build size is a no-brainer. Who wouldn’t like a system where they write code and don’t worry about the overhead, knowing the compiler will do its job?
Speaking of the compiler, Svelte provides some of the clearest error messages in frontend development. Often, a quick glance at your terminal tells you everything you need to know. No browser DevTools required.
SvelteKit can deploy to basically any modern hosting platform thanks to its adapter system. The officially supported adapters are rock-solid, but third-party or niche adapters vary in maturity, so compatibility isn’t truly universal.
The Elephant in the Room: Astro
Let’s talk about Astro. Astro was created because the mainstream ecosystem (React, Vue, Angular) was shipping too much JavaScript to the browser. Svelte’s compiler-first model already side-stepped that problem, so the core motivation behind Astro wouldn’t have existed if Svelte were the dominant paradigm.
React and Vue developers reach for Astro because it gives them tight control over how much JavaScript gets hydrated. Svelte developers already get those benefits from SvelteKit, so the need for Astro is much lower. When performance is already baked in, Astro becomes a stylistic choice rather than a necessity.
You can build content-heavy apps with SvelteKit without the performance penalty. If I hadn’t used Svelte to build this website, I would have used Astro.
Conclusion
Coming from React, learning Svelte was a bit difficult at first because I was trying to learn it the “React way,” paying attention to every minuscule item. After a while, I decided to stop comparing and just build.
I built a simple login form, and it was fascinating. The reason it was initially difficult was a lack of direction on my end. If you want to learn it now, stop overthinking it.
In my experience, onboarding juniors into Svelte projects has been noticeably easier than with other frameworks I’ve used.
Fun Fact:
- The majority of what developers need to build complex apps is already in Svelte by default.
You should try out Svelte this weekend. While my friend’s prediction “you’ll never use React again” felt profoundly true for me, the reality is more nuanced. The right tool always depends on the job and the team. But if you, like me, yearn for a simpler, more direct path from idea to implementation, I promise Svelte is a journey worth taking.
Want to Learn Svelte?
If this post convinced you to try Svelte, here are the best resources to get started:
Quick Overview (5-10 minutes)
- Fireship: Svelte in 100 Seconds - Perfect high-level introduction to Svelte’s philosophy
- Fireship: Svelte 5 Runes Explained - Deep dive into the new reactivity system I mentioned
Comprehensive Course (Free)
- Syntax and Scott Tolinski: Svelte 5 Course - Complete playlist that takes you from beginner to confident
Official Documentation
- Svelte Tutorial - The official interactive tutorial (highly recommended)
- SvelteKit Docs - For full-stack applications
References
Runes- Keywords understood by Svelte’s compiler$derived- Svelte’s derived state rune$effect- Side effects and reactionsonMount- a function that schedules a callback to run as soon as the component has been mounted to the DOM{ @html }- inject raw HTML into your component<svelte:head>- reference todocument.head