A modern, plugin-free HTML5 game engine
npm install melonjs
import { Application, Sprite, loader } from "melonjs";
// create a new melonJS application
const app = new Application(1218, 562, {
parent: "screen",
scale: "auto",
backgroundColor: "#202020",
});
// initialize it (builds the renderer and appends the canvas)
await app.init();
// load and add a sprite
loader.preload([{ name: "player", type: "image", src: "player.png" }], () => {
app.world.addChild(new Sprite(609, 281, { image: "player" }));
});
Note: since version 20.0,
await app.init()is required after constructing theApplication. The WebGPU backend, whichAUTOtries first where available, acquires its GPU device asynchronously; the call resolves without suspending on the WebGL and Canvas backends.
| Feature | Description |
|---|---|
| Rendering | WebGPU, WebGL 2 and Canvas 2D with automatic fallback — the same feature set on every backend |
| 3D | Perspective Camera3d, mesh instancing, ground shadows, distance fog, point and spot lights, glTF/GLB and OBJ/MTL loading |
| Tiled Maps | First-class Tiled map editor support (TMX/JSON), with GPU-accelerated tile rendering for orthogonal maps |
| Sprites | Texture atlas, animation, TexturePacker & Aseprite support |
| Physics | Built-in SAT collision with gravity and friction, shape-level collision events, and a PhysicsAdapter interface for Box2D (planck) or Matter.js |
| Audio | Web Audio API with format fallback, plus procedural tone and noise generation |
| Input | Keyboard, mouse, touch, gamepad |
| Particles | Configurable ParticleEmitter, with a reference space so particles can be measured from the emitter, the world, or any container |
| Effects | All thirteen CSS blend modes on every renderer, tinting, masking, and camera post-processing chains |
| Custom Shaders | Per-sprite ShaderEffect carrying both GLSL and WGSL, so one effect runs on either GPU backend |
| UI | Built-in UI components (buttons, text input, containers) |
Load a level created with the Tiled map editor. melonJS supports orthogonal, isometric, and hexagonal maps with multiple layers, animated tiles, and collision shapes.
import { level } from "melonjs";
// load a level by name (must be preloaded first)
level.load("myLevel");
See: level, TMXTileMap
Create a sprite from a texture atlas (e.g. exported from TexturePacker or Aseprite) and define animation sequences from named frames.
import { Sprite, TextureAtlas, loader } from "melonjs";
// create a texture atlas from preloaded JSON + image
const atlas = new TextureAtlas(loader.getJSON("atlas"), loader.getImage("atlas"));
// create a sprite with animation frames from the atlas
const player = new Sprite(100, 100,
atlas.getAnimationSettings(["walk01.png", "walk02.png", "walk03.png"])
);
See: Sprite, TextureAtlas
Bind physical keys or gamepad buttons to named actions, then check those actions in your game logic.
import { input } from "melonjs";
// bind the spacebar and gamepad button to a "jump" action
input.bindKey(input.KEY.SPACE, "jump");
// check if the action is active (e.g. in an update loop)
if (input.isKeyPressed("jump")) {
// make the player jump
}
See: input
Attach a physics body with a collision shape to any renderable. The engine handles gravity, velocity, friction, and collision detection automatically.
import { Body, Rect, collision } from "melonjs";
// create a rectangular collision body (x, y, width, height)
this.body = new Body(this, new Rect(0, 0, 32, 32));
// set collision type so the engine knows how to handle collisions
this.body.collisionType = collision.types.PLAYER_OBJECT;
// set movement limits and friction
this.body.setMaxVelocity(3, 15);
this.body.setFriction(0.4, 0);
Apply a per-sprite fragment shader using ShaderEffect. You only need to write the color transformation — the vertex shader and texture sampling are handled automatically. Runs on both GPU backends — write the body once and it is realized as GLSL or WGSL for the active renderer — and is silently ignored in Canvas mode.
import { ShaderEffect } from "melonjs";
// apply a grayscale effect to a sprite
mySprite.addPostEffect(new ShaderEffect(renderer, `
vec4 apply(vec4 color, vec2 uv) {
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
return vec4(vec3(gray), color.a);
}
`));
See: ShaderEffect, addPostEffect
Three things here are meant for assistants as much as for people.
llms.txt — melonjs.github.io/melonJS/llms.txt
indexes every exported class, function, interface and type with a one-line
summary and a link to its page, and marks the deprecated ones. It is
regenerated on every docs build, so it never drifts from the release. Point an
assistant at that single URL rather than asking it to guess an API name.
Copy page — the button in the header above copies the page you are reading as Markdown, with its canonical URL attached, or hands it straight to an assistant. Useful when you want to ask about one class without the model fetching half the reference.
Skills — the engine ships guidance files that teach an assistant its
conventions, and more usefully the mistakes that fail silently rather than
raising an error: a custom draw() that ignores this.pos, isKinematic
blocking pointer events, .z set after addChild. They are versioned with the
engine, so a copy matching your exact release always ships inside the package.
Install them into whatever assistant you use, with one command:
npx skills add https://github.com/melonjs/melonJS/tree/master/packages/melonjs/skills
That writes each agent's own convention — .claude/skills/, .agents/skills/,
.windsurf/skills/ and around seventy others — so there is nothing to place by
hand. It installs from master; swap that for a release tag in the URL to pin.
They are plain Markdown — readable by any agent, or by you.