Build the RPG you always wanted to make — then put it online as an MMORPG, with the same code.
Quick start · Documentation · Watch the intro · Discord
RPGJS is a TypeScript framework for 2D RPGs and MMORPGs in the browser. Maps, events, dialogs, inventory, skills, combat, save/load, GUI and multiplayer synchronization are already there — you write the game, not the engine.
![]() |
![]() |
| RPGJS explained Build an RPG once, run it as an MMORPG |
Getting started tutorial From an empty folder to a multiplayer RPG in 5 steps |
npx degit rpgjs/starter#v5 my-rpg-game
cd my-rpg-game
npm install
npm run dev VITE v8.0.16 ready in 654 ms
➜ Local: http://localhost:5173/
RPGJS v5.0.0 RPG
➜ Game: ./src/standalone.ts
➜ Server: runs in the browser (standalone)Open the link: your hero is already walking around a map. Prefer to follow along? Watch the 5-step getting started tutorial.
The gameplay you write runs on a server-owned model from day one. Switching from a single-player RPG to an MMORPG is a runtime choice, not a rewrite.
| Standalone RPG | MMORPG |
|---|---|
startGame({
...config,
providers: [provideRpg(startServer)],
});npm run dev |
startGame({
...config,
providers: [provideMmorpg({})],
});RPG_TYPE=mmorpg npm run dev |
In MMORPG mode the server stays authoritative, each map becomes a synchronized room, and the client predicts movement so the game still feels instant.
import { type EventDefinition, type RpgPlayer } from "@rpgjs/server";
export function Merchant(): EventDefinition {
return {
name: "Merchant",
onInit() {
this.setGraphic("merchant");
},
async onAction(player: RpgPlayer) {
const choice = await player.showChoices("Need something for the road?", [
{ text: "A potion (20 gold)", value: "potion" },
{ text: "Just looking", value: "no" },
]);
if (choice?.value === "potion" && player.gold >= 20) {
player.gold -= 20;
player.addItem("potion");
await player.showText("Safe travels!");
}
},
};
}Want enemies that fight back? Give an event a battle AI:
new BattleAi(this, { enemyType: EnemyType.Aggressive });![]() |
![]() |
| Maps painted in RPGJS Studio or Tiled | Prebuilt, themeable game screens |
| 🗺️ World | Maps, world maps, Tiled support, events, shared and per-player scenarios, weather, lighting, day/night |
| ⚔️ Gameplay | Items, skills, states, classes, real-time action battle, projectiles, hotbar, save/load |
| 🌐 Multiplayer | Authoritative server, map rooms, client prediction and reconciliation, live map updates, accounts, chat |
| 🖼️ Interface | Title screen, dialogs, menus, shop, HUD, character select, themes, mobile controls, gamepad, Vue overlays |
| 🌍 i18n | One translation catalog for server dialogs, client menus and modules |
| 🛠️ Tooling | TypeScript first, Vite, Vitest testing helpers, dependency injection, modules and plugins |
| ☁️ Deploy | Node or Cloudflare Workers, with no lock-in to a database or host |
Teach your coding assistant how RPGJS v5 works:
npx skills add https://github.com/RSamaium/RPG-JS#v5- Quick start and project structure
- Create your first map and an event
- Design your GUI
- Save and load, translate your game
- Put your MMORPG online
Want the ideas behind the architecture? Read the RPGJS philosophy.
Coming from RPGJS v4? compatibilityV4Plugin() from @rpgjs/vite runs a
v4 project layout on the v5 runtime. See the
migration guide.
- Questions, ideas and showcases: Discord
- News and updates: @rpgjs_dev on X
- Bugs: GitHub Issues
- Want to contribute? Start with CONTRIBUTING.md
If RPGJS helps you build your game, a ⭐ on GitHub helps others find it.
MIT — free for commercial use.





