BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Svelte 3 Front-End Framework Moves Reactivity into the JavaScript Language, Q&A with Rich Harris

Svelte 3 Front-End Framework Moves Reactivity into the JavaScript Language, Q&A with Rich Harris

This item in japanese

The Svelte front-end framework recently released Svelte 3. Svelte 3 introduces a novel way to declaratively express invariants linking entities involved in the implementation of a user interface. Developers thus may no longer need to manually handle re-rendering for performance purposes, or manually synchronize dependent pieces of state. Svelte 3 comes with a new logo, tagline and website. Sapper (a Svelte-powered Next.js-style application framework), and Svelte Native (targeting mobile application development) are being upgraded to Svelte 3. InfoQ interviewed Rich Harris, Svelte creator, and discussed what Svelte 3 means and its implications for developers.

Svelte 3 is the latest major iteration of the Svelte front-end framework. Rich Harris, explains the goal behind Svelte 3:

Version 3 is a significant overhaul. Our focus for the last five or six months has been on delivering an outstanding developer experience. It’s now possible to write components with significantly less boilerplate than you’ll find elsewhere.

At the core of the release is a new syntax for declaratively expressing permanent relationships between variables that are involved in the rendering process. Three cases are distinguished in Svelte 3’s documentation: reactive assignments, reactive declarations, and reactive statements.

To exemplify reactive assignments, Harris gives a simple example of an incrementing counter with Svelte and other front-end frameworks:

// With Svelte
const { count } = this.get();
this.set({
  count: count + 1
});

// With React
const { count } = this.state;
this.setState({
  count: count + 1
});

// With Vue
(...)
data: () => ({count: 0}),
(...)
this.count += 1;

In these examples, developers need to trap or signal state changes to the embedded framework in order to trigger dependent computations and effects. With Svelte 3, developers can just assign the variable:

count += 1;

and Svelte will generate the corresponding synchronizing code at build time:

count += 1; $$invalidate('count', count);

Reactive declarations deal with relationships between miscellaneous variables. With Svelte 3, developers may now write a relationship between variables as an equation, with the Svelte compiler ensuring that changes in the variables on the right side of the equation are reflected in the variable on the left side, like in a spreadsheet. In the following example:

<script>
	let count = 1;

	// the `$:` means 're-run whenever these values change'
	$: doubled = count * 2;
	$: quadrupled = doubled * 2;

	function handleClick() {
		count += 1;
	}
</script>

<button on:click={handleClick}>
	Count: {count}
</button>

<p>{count} * 2 = {doubled}</p>
<p>{doubled} * 2 = {quadrupled}</p>

the syntax $: doubled = count * 2; introduces an equation linking the doubled variable to the count variable. The Svelte compiler will here again generate code that updates doubled whenever count is updated:

	let doubled, quadrupled;
	$$self.$$.update = ($$dirty = { count: 1, doubled: 1 }) => {
		if ($$dirty.count) { $$invalidate('doubled', doubled = count * 2); }
		if ($$dirty.doubled) { $$invalidate('quadrupled', quadrupled = doubled * 2); }
	};

Reactive statements are statements that will be evaluated every time a dependent variable changes. They also use the $ syntax:

<script>
	let count = 0;

	$: if (count >= 10) {
		alert(`count is dangerously high!`);
		count = 9;
	}

	function handleClick() {
		count += 1;
	}
</script>

<button on:click={handleClick}>
	Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

and will be compiled by the framework as:

	$$self.$$.update = ($$dirty = { count: 1 }) => {
		if ($$dirty.count) { if (count >= 10) {
				alert(`count is dangerously high!`);
				$$invalidate('count', count = 9);
			} }
	};

InfoQ interviewed Rich Harris, Svelte creator, and discussed the motivations behind Svelte 3 and its implications for developers.

InfoQ: Tell us about the history of Svelte. You are behind Ractive, another template-based front-end framework that was used at the Guardian newspaper. What drove you to write Svelte?

Rich Harris: Ractive was part of the 2012-13 crop of UI frameworks, and was a product of its age. It was powerful and intuitive, but like all its peers it worked by interpreting your declarative component code at runtime, which incurs a penalty. You pay for the framework in the form of a larger JS bundle and slower performance than if you’d hand-written code to manipulate the DOM directly.

By 2016, everything had changed. Mobile, not desktop, suddenly accounted for the majority of traffic, making bundle size and performance even more important. Thanks to projects like Babel and TypeScript, the JS community was newly comfortable with compilers and build steps, so I started to wonder if a compiler that understood declarative components could transform them into highly-optimised imperative code. By this point I’d spent several years thinking about UI framework design, and I’d built a module bundler (Rollup) and a compiler (Bublé), so I felt like I was in a good position to take a stab at it.

InfoQ: Svelte 3 brings a new syntax to solve synchronization issues within a component, e.g. intra-component. What about inter-component synchronization/communication? Say two components read and write a shared piece of state, or two components must communicate. How do you handle the possible synchronization issues with Svelte?

Harris: Svelte has a primitive called a store, which works with the built-in reactivity system. It’s a very simple contract — it has a reference implementation in the package, but you can also wrap other libraries like Redux or xstate — that is infinitely composable. We also natively support TC39’s proposed Observable specification (which is implemented by libraries like RxJS) since they happen to adhere to the Svelte store contract.

InfoQ: Is it possible to package a Svelte component into a Web Component which can be used in another framework? Conversely, how easy is it to use Web Components in Svelte?

Harris: A nice thing about being a compiler is that you can generate different outputs from the same component code. Generating web components is a simple matter of setting a compiler option. Consuming web components is equally straightforward — Svelte scores 30/30 on the Custom Elements Everywhere test suite.

InfoQ: If Svelte can compile to web components, would that mean that developers can incrementally introduce Svelte in their code base? Would that be a practical thing to do (any possible clash with existing code, conflicting markups, bundling issues, etc., you know of)?

Harris: Yes, Svelte is designed with incremental adoption in mind. Custom elements are a convenient way to achieve that, as long as you bring the right polyfills. It depends on the ‘host’ framework though — for example React has poor support for custom elements, so you would be better off using a React wrapper around Svelte components (such as react-svelte) for the duration of the migration.

InfoQ: How can developers handle nested routing with Svelte?

Harris: The easiest way is to use Sapper, which is an app framework built on top of the Svelte component framework. Sapper gives you a completely declarative nested routing system based on your app’s folder structure, similar to Next.js but with a number of important enhancements.

For developers who prefer component- or configuration-based routing, there are several community-maintained projects.

InfoQ: How would you go about testing a Svelte application?

Harris: The default Sapper template has Cypress integration built-in. For individual component tests I often use Puppeteer. We’re still figuring out the most idiomatic testing story and should have something to share soon.

InfoQ: Three reasons to adopt Svelte?

Harris: Firstly, you’ll write less code, which is the most reliable way to create software quicker and with fewer bugs. Secondly, you get much better performance guarantees than more mainstream frameworks can possibly give you, which means you won’t have to stop for rewrites as your app grows, or as you expand into new markets where slower devices and connections are prevalent.

Thirdly, Svelte has many features that traditional frameworks consider out of scope. That’s because — as a compiler — Svelte only needs to include the features you’re actually using, saving bytes for everyone else. That means we’re free to include things that other framework teams would consider an extravagance, like declarative transitions and animations.

InfoQ: Three reasons not to adopt Svelte?

Harris: We don’t yet have the wealth of editor integrations and devtools that more mature frameworks do. We don’t yet have first-class TypeScript support. We don’t belong to a deep-pocketed company — we’re just a ragtag crew of true believers.

InfoQ: What is next for Svelte?

Harris: The most requested feature has been TypeScript support, so we’re anxious to make some progress on that soon. I’m personally excited about using Svelte to build WebGL apps, and am in the early stages of exploring that. Finally, there’s a community project called Svelte Native which allows you to build Android and iOS apps using Svelte (powered by NativeScript), and it’s making some incredible progress.

InfoQ: Can you give us some examples of companies using Svelte?

Harris: The New York Times, where I work, has used it for a number of projects, as have a few other news organisations. Our website has a number of other examples on the homepage — perhaps most interestingly, Stone in Brazil and Mustlab in Russia are using Svelte to power embedded devices like point-of-sale systems and Smart TV apps. More and more front end development is moving to the embedded web, and these companies are realising that traditional JavaScript-first frameworks can’t meet the demands of that environment.

Rate this Article

Adoption
Style

BT