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.
Clone the official Ammo.js repository:
git clone https://github.com/kripken/ammo.js.git cd ammo.jsEnsure 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:
- Soft Body Physics: If your project only uses rigid
bodies, remove
btSoftBody,btSoftRigidDynamicsWorld, and associated helpers. - Vehicle Physics: If you are not building a driving
simulator, strip out
btRaycastVehicleandbtVehicleTuning. - Complex Constraints: Remove unused joints and
constraints like
btGearConstraint,btConeTwistConstraint, orbtSliderConstraint. - Collision Shapes: If you only use boxes and
spheres, remove complex shapes like
btHeightfieldTerrainShape,btMinkowskiSumShape, orbtConvexHullShape.
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:
-O3or-Oz: Use-Ozinstead of-O3. While-O3optimizes for performance,-Ozoptimizes aggressively for code size, which is critical for web delivery.--closure 1: This enables the Google Closure Compiler to minify the resulting JavaScript wrapper file and remove dead code.-s WASM=1: Ensure you are targeting WebAssembly, which inherently produces smaller binary sizes than pure asm.js.-g0: Disable debug symbols to prevent unnecessary bloat in the compiled binary.-s FILESYSTEM=0: If your physics simulation does not require local file reading/writing, disabling the virtual filesystem saves additional space.
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.pyThis 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.