Tuto: Setup a Svelte project using esbuild
Tags: svelte, tutorial, javascript, esbuild
Published: 2023-09-29 20:11:59

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

![Reload Svelte app when code changes](https://barim.us/img/svelte-esbuild-reload.gif)

Fisrt, why use esbuild ? Well, it's a very fast bundler that's easy to setup and I did not find a lot of tutorial 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.

```js
{
  "type": "module",
  "dependencies": {
    "esbuild": "^0.19.4",
    "esbuild-svelte": "^0.8.0",
    "svelte": "^4.2.1"
  }
}
```

To install all of them, execute the npm install command:
```sh
npm i
```

If you don't want to create the package.json by hand, you can use this npm command :
```js
npm i esbuild esbuild-svelte svelte
```
But do not forget to add the line `"type": "module"` or you'll get an error at build time.

## esbuild.js

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

```js
import * as esbuild from 'esbuild';
import sveltePlugin from 'esbuild-svelte';

let ctx = await esbuild.context({
	entryPoints: ['app.svelte'],
	bundle: true,
	format: 'esm',
	outdir: './build',
	plugins: [
		sveltePlugin({
			compilerOptions: { customElement: true}
		})
	],
	banner: {
		js: "new EventSource('http://127.0.0.1:8888/esbuild').addEventListener('change', () => location.reload())"
	},
	logLevel: 'info'
});
await ctx.watch();
await ctx.serve({
	servedir: './',
	port: 8888,
	host: '127.0.0.1'
});
```

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.

## index.html

Create an index.html file : 
```html
<!DOCTYPE html>
<html lang="en">
	<head>
		<title></title>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<script defer src="build/app.js" type="module"></script>
	</head>
	<body>
		<app-input/>
	</body>
</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.

## app.svelte

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

```js
<svelte:options customElement="app-input" />

Hello world
```

Now, launch your local server with :

```sh
node 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 !

*This article was cross-posted from [my blog](https://barim.us/post/2023-09-29-esbuild-svelte-setup/).*