BassEngine is a lightweight, WebGL-powered game engine crafted for indie developers. Write less boilerplate, ship faster, and run at a solid 60 fps on every device.
A complete toolkit out of the box — no plugins needed for the core gameplay loop.
Batched draw calls, sprite atlases, custom GLSL shaders, and camera transforms. Renders thousands of sprites at 60fps without breaking a sweat.
Entity-Component-System keeps game logic composable, testable, and cache-friendly. Attach, detach, and query components at runtime with no overhead.
Keyboard, mouse, gamepad, and touch — all through one unified API with named action maps and configurable dead zones.
Web Audio API with positional audio, reverb, pitch control, and a real-time gain mixer. Sounds exactly where it should be.
Tree-based scene graph with async asset loading, smooth fade transitions, and persistent global state between scenes.
Arcade-quality AABB and circle physics, rigidbody gravity, raycasting, and per-entity collision events — zero external deps.
Pool-based particle emitter with burst mode, gravity, size/color interpolation, and continuous emission. Plug onto any entity.
Three steps from nothing to a full game loop with physics, renderer, and input.
Run npm i bass-engine or include the CDN script tag in your HTML.
Extend Scene, add entities in onCreate(), update them in onUpdate(dt).
Call BassEngine.run(new MyScene()) — the loop, renderer, and physics all start.
import { BassEngine, Scene, Sprite } from 'bass-engine'; class GameScene extends Scene { onCreate() { this.player = new Sprite({ texture: 'player.png', x: 100, y: 200, tag: 'player' }); this.add(this.player); } onUpdate(dt) { this.player.x += 200 * dt; } } BassEngine.run(new GameScene());
import { Input } from 'bass-engine'; // Map named actions to keys Input.mapAction('jump', ['Space', 'ArrowUp']); Input.mapAxis('move', { pos: 'ArrowRight', neg: 'ArrowLeft' }); // Use in onUpdate(dt) onUpdate(dt) { const dir = Input.axis('move'); this.player.x += dir * 200 * dt; if (Input.actionPressed('jump')) rb.vy = -500; }
import { Sprite, Rigidbody, BoxCollider } from 'bass-engine'; const player = new Sprite({ texture: 'player.png' }); // Add gravity + velocity const rb = player.addComponent( new Rigidbody({ gravity: 980 }) ); // Add AABB collider player.addComponent(new BoxCollider()); // React to collisions player.on('collide', other => { if (other.tag === 'ground') rb.vy = 0; });
import { Audio, Assets } from 'bass-engine'; // Preload sounds via AssetLoader await Assets.sound('jump', '/sfx/jump.ogg'); await Assets.sound('coin', '/sfx/coin.ogg'); // Play with options Audio.play('jump', { volume: 0.8, pitch: 1.2 }); // 3D positional audio Audio.play3D('coin', player.x, player.y);
We built exactly what indie web game developers actually need — no more, no less.
Full-featured desktop engines ported to the web — powerful but massive and complex.
Purpose-built for the web. Lightweight, fast to learn, and ships instantly anywhere a browser runs.
Rolling your own engine from scratch — total control, but you reinvent the wheel every time.
"I shipped my first game in a weekend using BassEngine. The ECS setup is incredibly intuitive and the renderer is blazing fast. Nothing else comes close at this level of simplicity."
"Finally an engine that doesn't feel like overkill for a 2D platformer. The physics feel great out of the box, docs are clear, and the JS API is a genuine joy to work with."
"We ported our prototype from another engine in two days flat. BassEngine's scene system and input abstraction saved us hundreds of lines of code. Would absolutely recommend."
BassEngine is free, open source, and MIT licensed. Everything you need is already in the box — no strings attached.