BabylonJS/Babylon.js · error

The WebGL2ParticleSystem class is not available! Make sure y

Error message

The WebGL2ParticleSystem class is not available! Make sure you have imported it.

What it means

On engines without compute shader support, GPUParticleSystem uses the WebGL2 update pipeline, looked up as registered class "BABYLON.WebGL2ParticleSystem". That class is registered by a separate module import; if it wasn't imported (common with ES6 tree-shaken imports), GetClass returns undefined and the constructor throws.

Source

Thrown at packages/dev/core/src/Particles/gpuParticleSystem.pure.ts:1103

        if (!sceneOrEngine || sceneOrEngine.getClassName() === "Scene") {
            this._scene = (sceneOrEngine as Scene) || EngineStore.LastCreatedScene;
            this._engine = this._scene.getEngine();
            this.uniqueId = this._scene.getUniqueId();
            this.layerMask = this._scene.defaultRenderableLayerMask;
            this._scene.particleSystems.push(this);
        } else {
            this._engine = sceneOrEngine as AbstractEngine;
            this.defaultProjectionMatrix = Matrix.PerspectiveFovLH(0.8, 1, 0.1, 100, this._engine.isNDCHalfZRange);
        }

        if (this._engine.getCaps().supportComputeShaders) {
            if (!GetClass("BABYLON.ComputeShaderParticleSystem")) {
                throw new Error("The ComputeShaderParticleSystem class is not available! Make sure you have imported it.");
            }
            this._platform = new (GetClass("BABYLON.ComputeShaderParticleSystem"))(this, this._engine);
        } else {
            if (!GetClass("BABYLON.WebGL2ParticleSystem")) {
                throw new Error("The WebGL2ParticleSystem class is not available! Make sure you have imported it.");
            }
            this._platform = new (GetClass("BABYLON.WebGL2ParticleSystem"))(this, this._engine);
        }

        this._customWrappers = { 0: new DrawWrapper(this._engine) };
        this._customWrappers[0]!.effect = customEffect;

        this._drawWrappers = { 0: new DrawWrapper(this._engine) };
        if (this._drawWrappers[0].drawContext) {
            this._drawWrappers[0].drawContext.useInstancing = true;
        }

        this._createIndexBuffer();

        // Setup the default processing configuration to the scene.
        this._attachImageProcessingConfiguration(null);

        options = options ?? {};

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Add the side-effect import registering WebGL2ParticleSystem (import the package index or the webgl2ParticleSystem module).
  2. Import from "@babylonjs/core" full bundle instead of deep paths.
  3. Check bundler config isn't dropping side-effect imports (sideEffects flag / sideEffects:false in package resolution).

Example fix

// before
import { GPUParticleSystem } from "@babylonjs/core/Particles/gpuParticleSystem";
// after
import "@babylonjs/core/Particles/webgl2ParticleSystem";
import { GPUParticleSystem } from "@babylonjs/core/Particles/gpuParticleSystem";
Defensive patterns

Strategy: validation

Validate before calling

if (!engine.getCaps().supportComputeShaders) {
  import("@babylonjs/core/Particles/webgl2ParticleSystem"); // ensure registered
}

Try / catch

try {
  const ps = new GPUParticleSystem("p", { capacity: 1000 }, engine);
} catch (e) {
  if (e.message.includes("WebGL2ParticleSystem")) {
    console.error("Add: import \"@babylonjs/core/Particles/webgl2ParticleSystem\";");
  }
}

Prevention

When it happens

Trigger: Constructing new GPUParticleSystem(...) on a WebGL2/limitless engine (supportComputeShaders false) while the module registering WebGL2ParticleSystem was never imported.

Common situations: Importing GPUParticleSystem from a deep/pure module path in an ES6 project without the webgl2ParticleSystem side-effect import; standard WebGL2 apps that tree-shake away the registration.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/a93a6b132d6aefc0. Report an issue: GitHub.