Create a Smaller Custom Ammo.js Build

This article explains how to significantly reduce the file size of ammo.js—the Emscripten port of the Bullet physics engine—by stripping out unused features. You will learn how to customize the WebIDL interface file, configure Emscripten compiler flags for optimal compression, and rebuild the library to generate a lightweight, production-ready WebAssembly physics engine.

Understanding the Ammo.js Build Pipeline

Ammo.js is not written in JavaScript from scratch; it is a direct C++ port of the Bullet Physics SDK compiled using Emscripten. The compilation process relies on a WebIDL (Interface Definition Language) file named ammo.idl.

This IDL file acts as a bridge, defining which C++ classes, methods, and properties are exposed to JavaScript. By default, Ammo.js includes almost the entire Bullet feature set, resulting in a large file size (often over 1.5MB). To create a smaller build, you must remove unused bindings from the IDL file and recompile the project.

Step 1: Set Up the Build Environment

To build Ammo.js, you need Emscripten installed on your system, or you can use a pre-configured Docker container.

  1. Clone the official Ammo.js repository:

    git clone https://github.com/kripken/ammo.js.git
    cd ammo.js
  2. Ensure you have Python and the Emscripten SDK (emsdk) installed and activated in your terminal helper environment.

Step 2: Strip Unused Features from the IDL File

The key to reducing size is editing the ammo.idl file located in the root directory. Open this file in a text editor.

Identify features your application does not require and delete or comment them out. Common candidates for removal include:

For example, to remove soft body support, delete the corresponding interfaces:

// Remove or comment out interfaces like this if unused:
interface btSoftBodyWorldInfo {
  void btSoftBodyWorldInfo();
  attribute float air_density;
  attribute float water_density;
  ...
};

Step 3: Optimize Emscripten Compilation Flags

Next, modify the build configuration to ensure the compiler aggressively optimizes the remaining code. Open make.py in the root directory. This script coordinates the build process.

Locate the Emscripten compiler flags array and ensure the following flags are set:

Example modification in make.py:

# Look for the emcc argument list and update/add:
emcc_args = [
    '-Oz',
    '--closure', '1',
    '-s', 'WASM=1',
    '-s', 'FILESYSTEM=0',
    '-s', 'AGGRESSIVE_VARIABLE_ELIMINATION=1',
    '-s', 'ELIMINATE_DUPLICATE_FUNCTIONS=1'
]

Step 4: Run the Build Script

Once the ammo.idl file is trimmed and make.py is configured, execute the build script to generate your custom build:

python make.py

This script will parse the modified IDL file, generate the glue code, compile the selected C++ Bullet source files, and output the optimized files into the builds/ directory.

Step 5: Verify and Test the Output

Compare the file size of your new ammo.wasm and ammo.js files against the default builds. In many cases, stripping soft bodies, vehicles, and unused collision shapes can reduce the final Wasm file size by 50% or more.

Finally, integrate the new build into your application. If your application throws a TypeError: Ammo.XXX is not a constructor error, it means you stripped a class or method in the IDL file that your application still relies on. If this occurs, restore that specific interface in ammo.idl and rebuild.