4 things I miss from Svelte after working in React

— 4 minute read

I got a new job in August, and I'm really enjoying the new problem space and all the great people I work with! However, like most companies, they write their frontend in React. This took some getting used to after writing Svelte for so long. Here are four things from Svelte that I deeply miss when writing React code.

(Psst - this is not a React hate post. Different frameworks solve different problems! At the end of the day users don't care about the syntax of the frameworks we use; they care about the end experience.)

Scoped styles permalink

Svelte just makes component styling so easy. You don't have to make a decision about what method to use (styled components? CSS modules? emotion? all global CSS?) and can just write them directly in the component file. Those styles are also scoped to the component so you know what might break when you change it.

<button>You can style me directly</button>

<style>
/* I only apply to buttons in this component */
button {
color: red;
}
</style>

Sure, there can be some friction (usually when you want to style something not in the component), but for the vast majority of use cases it's all you need.

Since React doesn't have a blessed styling solution, you need to choose one, and that leads to inconsistency in the codebase as different developers bring their own approach to styles.

Component prop shorthand permalink

This is a small one, but I really miss being able to write this...

<Button {disabled}>

...instead of this...

<Button disabled={disabled}>

It's the little things.

Actions permalink

I love Svelte actions, since they make it easy to tie some behavior to an individual HTML element's lifecycle. I ran into a problem at work that would've been a perfect fit for one (we were adding and removing an iframe and needed to add/remove event listeners and do some setup), but since this wasn't Svelte, it required extra effort.

There's likely a more idiomatic React way of accomplishing this (maybe a custom hook), and I ended up going with a combination of useEffect and useRef. But a Svelte action would have been so convenient.

Automatic reactive dependencies permalink

useEffect is a powerful tool, but one annoying thing is that you have to manually list each variable you depend on after the effect.

useEffect(() => {
doAThingWith(var1, var2, var3);
}, [var1, var2, var3]); // why do I have to write this?

Not adding all the dependencies (or adding too many) can lead to subtle bugs where the component doesn't behave as expected. The React docs say that the dependency list may be generated by a compiler in the future, but for now you need to play spot-the-difference and keep it up-to-date manually.

In Svelte, you don't have to do this. Reactive statements will automatically detect which variables they depend on and re-run when they change. And because Svelte components don't "re-render" like React components do (the component script tag only runs once), stale closures aren't a concern.

// I will automatically re-run when any of these variables change
$: doAThingWith(var1, var2, var3);

Wrapping up permalink

There are some things I appreciate about React - the ecosystem is very mature, and it's nice how composable hooks are. But I won't be switching from Svelte on anything where I have a choice.

Want to find out when I post a new article? Follow me on Mastodon or Twitter or subscribe to my RSS feed. I also have an email newsletter that I'll send out when I post something new, along with anything else I find interesting.

Previous Blog Post: Teaching Kelvin Svelte on TKYT

Next Blog Post: Partial hydration in SvelteKit with @11ty/is-land