I this article, I'll show who to build SolidJS application with esbuild.
Code generation
First I generate code following the documentation:
$ npx degit solidjs/templates/js esbuild-solid
npx: installed 1 in 0.664s
> cloned solidjs/templates#HEAD to esbuild-solid
Add HTML
To add esbuild, without breaking the default Vite setup let's add a separate output directory. First, we will add www/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="#" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Solid App</title>
<link href="./main.css" rel="stylesheet" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="./main.js"></script>
</body>
</html>
If you have HTTP access to the folder - as I do on http://localhost/github/esbuild-solid/www/ - you will see a white screen app, that complains in the browser console about files missing. We need to build the JS & CSS files for the app to work, but first, we need to install the dependencies.
Dependencies
To install dependencies, we can run:
$ npm install --save-dev esbuild esbuild-plugin-solid
> esbuild@0.12.19 postinstall /home/marcin/workspace/github/esbuild-solid/node_modules/esbuild
> node install.js
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN esbuild-plugin-solid@0.3.1 requires a peer of esbuild@^0.11 but none is installed. You must install peer dependencies yourself.
npm WARN esbuild-plugin-solid@0.3.1 requires a peer of solid-js@>= 0.26 but none is installed. You must install peer dependencies yourself.
npm WARN vite-template-solid@0.0.0 No repository field.
+ esbuild@0.12.19
+ esbuild-plugin-solid@0.3.1
added 61 packages from 62 contributors and audited 61 packages in 4.124s
3 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
- esbuild is already required by Vite, but it makes sense to add it explicitly as a dependency of our project - we are going to use it directly from here
- esbuild-plugin-solid - a neat plugin that allows us to use Solid's babel preset for compiling the JSX files. The JSX loader provided by esbuild outputs JS files in a format that is not compatible with Solid - so this plugin is currently the only way to have it all run together.
Build script
Because we are using an esbuild plugin, we have to set up a build script instead of having a long CLI command. We can put the following code to ./build.js:
const { build } = require("esbuild");
const { solidPlugin } = require("esbuild-plugin-solid");
build({
entryPoints: ["src/index.jsx"],
bundle: true,
outfile: "www/main.js",
minify: true,
loader: {
".svg": "dataurl",
},
logLevel: "info",
plugins: [solidPlugin()],
}).catch(() => process.exit(1));
The build passes correctly:
$ node build.js
www/main.js 12.8kb
www/main.css 674b
⚡ Done in 82ms
CSS gotcha
If you visit the output directory, the application is there, but the styling is not working as it should:

That's because the generated code uses css-modules, ie. we have:
2 import styles from "./App.module.css";
3
4 function App() {
5 return (
6 <div class={styles.App}>
7 <header class={styles.header}>
Which is not yet supported in esbuild - the ticket. The workaround, for now, would be replacing the CSS module with simply scoping the styles with classes.
Links
The repository & the demo page (with broken css).
Summary
In this article, we have seen how to build a SolidJS application with esbuild. It's working pretty smoothly. The only issue is that we would need to refactor away the CSS modules pattern.
About the author
I'm JS developer with 13 years of professional experience. I'm always happy to teach my craft.
Comments
Join the discussionPerfect timing! I just had a question on this and your article solved the problem I had! I tried and it works beautifully!
Just a couple of minor improvements:
- The build script can be made a simple executable by adding
!/usr/bin/env nodeas the first line and then runningchmod +x build.js - After this the
scriptssection inpackage.jsoncan be updated to run this script whennpm run buildis called:"scripts": { "start": "vite", "dev": "vite", "build": "./build.js", "serve": "vite preview" },
For typescript, I found that I simply needed to change the entryPoints value to entryPoints: ["src/index.tsx"],.
thanks for sharing!





