Modern HTML5 Game Engine โ ES Module packages, esbuild powered.
Egret Engine R is a modernized version of the Egret HTML5 game engine, repackaged as ES Module npm packages with esbuild as the build toolchain. It provides 2D rendering (Canvas/WebGL), an EUI component library, audio, networking, resource management, and more.
| Package | Description | Size (min) |
|---|---|---|
@egret-r/core |
Core engine: DisplayList, Events, Media, Net, Rendering | 309 KB |
@egret-r/eui |
UI component library: Button, List, Scroller, Layouts, EXML | 190 KB |
@egret-r/game |
Game extensions: MovieClip, URLLoader, ScrollView | 33 KB |
@egret-r/tween |
Easing animation: Tween, Ease (chain, parallel, wait) | 10 KB |
@egret-r/socket |
WebSocket wrapper | 3 KB |
npm install @egret-r/core @egret-r/eui @egret-r/game @egret-r/tween
npm create vite@latest my-game -- --template vanilla-ts
cd my-game
npm install @egret-r/core @egret-r/eui @egret-r/game
// src/main.ts
import { egret } from '@egret-r/core';
import '@egret-r/eui';
class Main extends egret.DisplayObjectContainer {
constructor() {
super();
this.once(egret.Event.ADDED_TO_STAGE, () => {
this.stage.frameRate = 60;
}, this);
}
}
window.Main = Main;
window.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('game-container') as HTMLDivElement | null;
if (!container) return;
container.classList.add('egret-player');
container.setAttribute('data-entry-class', 'Main');
container.setAttribute('data-scale-mode', egret.StageScaleMode.NO_SCALE);
container.setAttribute('data-frame-rate', '60');
container.setAttribute('data-content-width', String(container.clientWidth || window.innerWidth));
container.setAttribute('data-content-height', String(container.clientHeight || window.innerHeight));
egret.runEgret({ renderMode: 'webgl' });
});
# from repository root โ one command
npm run dev
# or manually:
npm install
npm run build
cd examples/basic && npx vite --host 127.0.0.1 --port 3005 --strictPort
Open http://127.0.0.1:3005/ in your browser. Use the top-right dropdown to switch between 23 test cases covering all packages.
| Module | Cases |
|---|---|
| Core | Geometry, Event/Touch, Graphics, Text, Transform, RenderTexture, BlendMode, Benchmarkร3, HttpRequest, Sound, Video, ImageLoader |
| EUI | ArrayCollection, Button, CheckBox/RadioButton, List/Scroller |
| Game | URLVariables, MovieClip |
| Tween | Easing, Multi-target |
| Socket | WebSocket |
Standalone playable games in examples/:
| Project | Directory | Dev Server |
|---|---|---|
| ๐ฎ Flappy Bird | examples/flappy-bird/ |
npm -w examples/flappy-bird run dev โ http://localhost:3001 |
| ๐ฎ Breakout | examples/breakout/ |
npm -w examples/breakout run dev โ http://localhost:3002 |
| ๐ฎ 2048 | examples/2048/ |
npm -w examples/2048 run dev โ http://localhost:3003 |
Single command (build + dev server):
npm run dev
For fast iteration during development, open two terminals:
| Terminal 1 | Terminal 2 |
|---|---|
npm run watch |
npm -w examples/basic run dev |
Watches src/ changes โ auto-rebuilds packages |
Vite dev server โ HMR auto-refreshes browser |
# Copy the template from the egret-r repository
cp -r templates/vite-game my-game
cd my-game
# Install dependencies
npm install
# Link local packages (monorepo dev)
npm link ../../packages/core ../../packages/eui ../../packages/game ../../packages/tween
# Start dev server
npm run dev
The template (templates/vite-game/) includes a ready-to-run game skeleton with Stage, Button, Label and Tween animation examples. See templates/vite-game/README.md for details.
<script> tag<script type="module">
import { egret } from './node_modules/@egret-r/core/dist/index.js';
import { eui } from './node_modules/@egret-r/eui/dist/index.js';
const stage = egret.Stage.getInstance();
// ...
</script>
import { egret } from '@egret-r/core';
// Display objects
const bitmap = new egret.Bitmap(texture);
const shape = new egret.Shape();
shape.graphics.beginFill(0xff0000);
shape.graphics.drawRect(0, 0, 100, 100);
// Stage
const stage = egret.Stage.getInstance();
stage.addChild(bitmap);
// Events
bitmap.addEventListener(egret.TouchEvent.TOUCH_TAP, () => {
console.log('Tapped!');
}, this);
// HTTP
const request = new egret.HttpRequest();
request.open('https://api.example.com/data.json', egret.HttpMethod.GET);
request.addEventListener(egret.Event.COMPLETE, () => {
const data = JSON.parse(request.response);
}, this);
request.send();
// Sound
const sound = new egret.Sound();
sound.load('https://example.com/click.mp3');
sound.play();
import { eui } from '@egret-r/eui';
// Components
const list = new eui.List();
const scroller = new eui.Scroller();
const panel = new eui.Panel();
// Layout
const layout = new eui.HorizontalLayout();
layout.gap = 10;
scroller.layout = layout;
// Data binding
const collection = new eui.ArrayCollection([
{ label: 'Item 1', value: 1 },
{ label: 'Item 2', value: 2 },
]);
list.dataProvider = collection;
import { Tween, Ease } from '@egret-r/tween';
// Basic tween
Tween.get(target)
.to({ x: 200, y: 300 }, 500)
.to({ scaleX: 1.5, scaleY: 1.5 }, 300, Ease.backOut);
// Chain
Tween.get(obj1)
.to({ alpha: 0 }, 400)
.wait(200)
.call(() => console.log('Done!'));
import { egret } from '@egret-r/core';
import { game } from '@egret-r/game';
// MovieClip
const mcData = game.MovieClipDataFactory.generateMovieClipData(jsonData, texture);
const mc = new game.MovieClip(mcData);
mc.gotoAndPlay('walk');
// URLLoader
const loader = new game.URLLoader();
loader.dataFormat = game.URLLoaderDataFormat.TEXT;
loader.load(new game.URLRequest('https://example.com/data.txt'));
egret-r/
โโโ packages/
โ โโโ core/ # @egret-r/core
โ โโโ eui/ # @egret-r/eui
โ โโโ game/ # @egret-r/game
โ โโโ tween/ # @egret-r/tween
โ โโโ socket/ # @egret-r/socket
โโโ src/ # ESM source (namespaceโESM migration)
โโโ scripts/ # Build tooling
โโโ package.json # Monorepo root (npm workspaces)
npm install # Install dependencies
npm run build # Build all 5 packages
npm run build:core # Build @egret-r/core only
npm run dev # Build + start example dev server
npm run clean # Remove all dist/ directories
npm test # Run all tests (88 tests, 5 suites)
src/egret/*.ts src/extension/*.ts (ESM source)
โ
โโโ Defines.debug.ts โ injected first (debug constants)
โโโ Kahn topological sort โ resolve circular dependencies
โโโ import type โ break remaining cycles
โ
โโโ esbuild
โโโ bundle + ESM โ dist/index_tmp.js
โโโ IIFE wrap โ var hoisting for class extends
โโโ inline namespace assignments โ dist/index.js
| Platform | Status |
|---|---|
| Chrome, Edge, Firefox, Safari | โ Full |
| iOS Safari, Android Chrome | โ Full |
| WeChat Mini Game | โ (via Web API) |
| Facebook Instant Games | โ |
BSD License โ see LICENSE.md for details.