Tuto: Setup a Svelte project using esbuild

Friday, September 29, 2023 · 3 minutes · 540 words

This article will show you how to set up a new Svelte project to develop a custom tag, using esbuild, with live reloading.

Reload Svelte app when code changes

First, why use esbuild ? Well, it’s a very fast bundler that’s easy to set up, and I did not find a lot of tutorials about Svelte and esbuild.

Next, what is a custom tag ? It’s an HTML tag, like <pre> or <input> but we are in charge to define its behavior and its look, thanks to some JavaScript code. In fact, thanks to Svelte, we can define both in a single component.

So, to do just that, in a new directory, we will create 4 files :

  • package.json : defines all JavaScript dependencies
  • esbuild.js : script to launch the local server, watch files and reload Svelte
  • index.html : our main web page
  • app.svelte : the Svelte custom tag component

package.json

This is where we declare our dependencies. We need esbuild and its svelte plugin. Obviously, we also need Svelte.

1{
2  "type": "module",
3  "dependencies": {
4    "esbuild": "^0.19.4",
5    "esbuild-svelte": "^0.8.0",
6    "svelte": "^4.2.1"
7  }
8}

To install all of them, execute the npm install command:

1npm i

If you don’t want to create the package.json by hand, you can use this npm command :

1npm i esbuild esbuild-svelte svelte

But do not forget to add the line "type": "module", or you’ll get an error at build time.

File esbuild.js

The esbuild script builds, watches and reloads the Svelte application.

 1import * as esbuild from 'esbuild';
 2import sveltePlugin from 'esbuild-svelte';
 3
 4let ctx = await esbuild.context({
 5	entryPoints: ['app.svelte'],
 6	bundle: true,
 7	format: 'esm',
 8	outdir: './build',
 9	plugins: [
10		sveltePlugin({
11			compilerOptions: { customElement: true}
12		})
13	],
14	banner: {
15		js: "new EventSource('http://127.0.0.1:8888/esbuild').addEventListener('change', () => location.reload())"
16	},
17	logLevel: 'info'
18});
19await ctx.watch();
20await ctx.serve({
21	servedir: './',
22	port: 8888,
23	host: '127.0.0.1'
24});

The entryPoints lists Svelte component main files : in this example, we only have app.svelte.

We want to create a custom tag (web component) so we need to force the format to esm and also activate the option customElement in the Svelte plugin.

This script will start a local server from the local directory (see servedir path) on port 8888 and watch for any changes and reload the page if any, by injecting a JavaScript code inside the rendered HTML, thanks to the banner esbuild directive.

File index.html

Create an index.html file :

 1<!DOCTYPE html>
 2<html lang="en">
 3	<head>
 4		<title></title>
 5		<meta charset="UTF-8">
 6		<meta name="viewport" content="width=device-width, initial-scale=1">
 7		<script defer src="build/app.js" type="module"></script>
 8	</head>
 9	<body>
10		<app-input/>
11	</body>
12</html>

You can see that we use our web component app-input as any HTML tag. It is that easy with Svelte. Just use a two words tag with a dash separation, so the browser knows it is a custom tag.

File app.svelte

And lastly, add a file ‘app.svelte’ that will define our web component :

1<svelte:options customElement="app-input" />
2
3Hello world

Now, launch your local server with :

1node esbuild.js

If all is ok, you can connect your browser to http://localhost:8888/ and get the greeting message.

You can update your code and see the live refresh. Happy coding !

Tuto Svelte