Getting started with Babylon.js using Vite and GitHub actions

Viktor
5 min readApr 26, 2021

Babylon.js team created a fantastic prototyping tool — playground. It’s straightforward to begin putting prototypes together. Once the project grows, you will want to set up a local environment with your favorite code editor, source control, automatic builds, and deployments. This tutorial will explore such setup with the following tools: Vite, GitHub Actions, and Pages.

We will use an example from the playground (Spot Light Examples) and convert it to a local project.

Vite refresh speeds

The primary tool of this setup is Vite - an opinionated frontend tool based on rollup.js and esbuild. It provides a fantastic development experience — a fast startup and refresh cycle. All it does is not bundle your code on every file change. To learn more, visit Why Vite.

Preparing the assets

The first step is downloading external resources used by the scene: models and textures. Open developer tools on the network tab, search for Dude.babylon, and save it to your computer.

Repeat for model’s textures: 0.jpg, 1.jpg, 2.jpg, 3.jpg.

Creating the project

Let’s get started by creating a new project with Vite. Make sure you have NodeJS 12+ installed. Run the following command in your terminal:

npm init @vitejs/app

Next, install BabylonJS itself. Run commands in the terminal:

cd <project-name>
npm install --save @babylonjs/core

After install finishes, open the newly created folder in your code editor. Open index.html and replace a div element with a canvas. Replace

<div id=”app”></div>

with

<canvas id=”app”></canvas>

Open style.css and replace contents with

#app {
width: 100%;
height: 100%;
}

Open the main.js file and copy the code from the playground. Leaving

import './style.css'

at the top of the file.

For Babylon to work, we need a canvas and an engine. Place the following piece at the end of the file:

const canvas = document.getElementById('app');
const engine = new BABYLON.Engine(canvas);
const scene = createScene(engine);
engine.runRenderLoop(() => {
scene.render();
})

To resolve references to BABYLON namespace, add the following on top:

import * as BABYLON from ‘@babylonjs/core/Legacy/legacy’;

Here is a complete code for reference:

The final step is to place all the downloaded assets (Dude.babylon, 0.jpg, 1.jpg, 2.jpg, 3.jpg) in /public/scenes/Dude folder.

Run the following command in the terminal to see the results:

npm run dev

Open the browser on localhost:3000. There you have it. A fully functioning playground project is working locally. Try changing any vector values and save to observe near-instant browser refresh.

Setting up GitHub

After making sure your project works, it’s time to put it under source control and set up automatic builds. If you’re not familiar with how git and GitHub work, please follow Introduction to GitHub tutorial to learn the basics.

Create a new repository for the project and commit all the changes. Mine is here — https://github.com/sotovviktor/babylonjs-project.

To build the project automatically, we will use GitHub Actions. Each action needs its definition file under the .github/workflows folder. Create main.yml with contents below. Our action is triggered on every push to the main branch and will execute the following steps:

  1. Checkout code
  2. Setup Nodejs
  3. Pull node_modules from cache (if available). It is used to speed up execution and not fetch packages on every build.
  4. Build the project with predefined Vite configuration
  5. Deploy new version to GitHub Pages
  6. Save the artifacts

To learn more about writing your actions, please visit — Quickstart for GitHub Actions.

For GitHub Pages to find our assets, we need to append the path of our repository to the URL. Find the function to load the model in the file - SceneLoader.ImportMesh and change its rootUrl argument from

"/scenes/Dude/"

to

import.meta.env.BASE_URL + "scenes/Dude/"

and push changes to the repository.

Open the Actions tab on your repository page and wait for the action to finish executing.

Go to Settings > Pages and choose gh-pages branch as the Souce. Click Save.

Now, your project is live. Grab the URL and check your results.

⚠ Sometimes going directly to the URL returns a 404 error. It fixes itself after the next update to the repository. In case it happens, append index.html to the URL.

Optimizing shipped code (tree-shaking)

The project is working; however, we can further optimize it. Now we are sending the entire Babylon.js library to the client. It adds extra bytes to be shipped over the wire and takes time to parse on the browser. We can minimize the amount of code we send to the client using tree-shaking.

Big vendor size. The size shown is a compressed response.

To utilize tree-shaking, we need to make minor adjustments to our code:

  1. Remove all BABYLON. prefixes
  2. Change import from legacy version to specific modules

After applying the steps above, you should have a code similar to the code below. There are some specific imports with side effects. To read more about side-effects in Babylon.js modules, please refer to - Babylon.js ES6 support with Tree Shaking.

Push the changes to the repository and wait for the GitHub Action to finish executing. Take a look at the newly created vendor file; it’s ~2.5 times smaller.

Smaller vendor file after tree-shaking

In this tutorial, we have taken the prototype from the playground and converted it to a project that you can develop locally from the comfort of your favorite editor. You can quickly iterate on ideas and not wait for bundling on every file change. Also, we have set up GitHub Actions to build and deploy every change to GitHub pages automatically.

--

--