Build a Unity WebGL game and serve it with an express.js server
Introduction
This post is about compiling a unity project to WebAssembly and using it in the browser. So to make things easy, I made a little project, which you can copy into your own project. I will explain how to do that later. After setting up, we compile the game to a WebGL build with some important configurations. To finish this project, we will make a server in node.js with express and serve the game.

**For the speedrunners**
For the people who just want to get this to work: Make a new Unity project, replace your Assets folder with this one. Read the Build Settings section, copy the javascript code in server.js and run npm init -y && npm i express && node server.js
.
WebAssembly
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.
So this project is made possible by Wasm, but what is it? For what I understand, Wasm is a new type of code that is meant to run in the browser. You can have your source code in different languages, like C#, C++ and Rust and compile it to WebAssembly. The browser takes that code and turns it into binary so your machine can run it. Please do not quote me on this. Do yourself a favour and educate yourself about this rather new and complex subject. https://webassembly.org/
Let’s start
To follow along, you will need Unity, node.js installed, an IDE, like VSCode and some patience because compiling to WebGl can take a while. (It took 8 minutes for me)
Let’s open Unity Hub and create a new project with the 3D template. You can copy the Assets folder here and replace the Assets folder of your new project. Press play to check if it is working. Hover over a cube with your cursor and use the ‘w a s d’ keys to rotate that block. If it is not working, please leave a comment and I will try to resolve your issues.
Build Settings
First, open the scene from the Assets>Scenes folder by double clicking it. Then press Ctrl+shift+B to open the build settings. We need to add the open scene to these settings, so press the according button. Under ‘Platform’, our platform is still on ‘PC, MAC & Linux Standalone’. Click on ‘WebGl’ and ‘switch platform’ to get the correct modules.
We are almost there, just hold on a little longer. In the bottom left you have the ‘player settings’, where we will need to change some settings as well. Under ‘Player>Resolution and Presentation’, choose the Minimal template instead of the Default one, to save yourself from some ugly windowed application.
Before you build the project, create a new folder for the output. Name it whatever you want it to be, just remember the location, because we will create a javascript file inside the same folder for the server.
Finally, you are ready to build the project. Return to the build settings and build your app.
Serving the build
Open up the build folder in your favourite IDE and make a file named server.js in the root of that folder. Copy the following code into that file.
const express = require('express');const app = express();const http = require('http');const path = require('path');const port = 8000;// Use the whole root as static files to be able to serve the html file and// the build folderapp.use(express.static(path.join(__dirname, '/')));// Send html on '/'pathapp.get('/', (req, res) => {res.sendFile(path.join(__dirname, + '/index.html'));})// Create the server and listen on porthttp.createServer(app).listen(port, () => {console.log(`Server running on localhost:${port}`);});
Open a terminal and run npm init -y && npm i express
to install express and run node server.js
to activate the server. You are nowserving your Wasm application.
Fixing small things
The functionality is done, but there are still some visual aspects that I would like to fix. As you can see, the application is not fullscreen. Unity provides a method to be able to do that. You need a unity instance and an event to trigger the fullscreen method.
In the index.html file, there is an internal script with UnityLoader.instantiate(“unityContainer”, “Build/Cubes.json”);
Make that let unityInstance = UnityLoader.instantiate(“unityContainer”, “Build/Cubes.json”);
You can now access the instance and call unityInstance.SetFullscreen(1)
from a button click event or any event you like, for instance, the window.onload
event.
Conclusion
I’ll start of by saying that this was my first post and I’m not a native English speaker, so I apologize for my English and writing style. But besides that, I hope at least a couple of you got some use out of this. Please leave some feedback in the comments and stay safe.