Skip to main content

Migrate from v4 to v5

This page is a stabilization draft. The compatibility matrix will be completed and verified against real v4 projects before the v5 stable release.
RPGJS v5 keeps the core v4 product model: the same gameplay can run as a standalone RPG or an MMORPG, the server owns multiplayer gameplay state, maps act as rooms, and players, events, hooks, database content, and GUI commands remain the primary framework concepts. The main migration is architectural. V5 favors explicit entries, plain module definitions, providers, replaceable runtime adapters, and CanvasEngine game components over compiler-controlled autoload and decorators.

Migration Paths

Run the v4 project structure on the v5 runtime

Use compatibilityV4Plugin() when the project should keep its v4 directory layout, rpg.toml, flagged imports, and Tiled asset conventions. See V4 Compatibility for the current setup and known limitations. This is the preferred first step for an existing game because it separates the runtime upgrade from the source migration.

Migrate incrementally to native v5 modules

After the game runs on the v5 runtime, migrate one module at a time:
  1. keep server gameplay hooks and commands
  2. replace decorated module configuration with defineModule()
  3. register runtime integrations through provideX() providers
  4. move visual components to the chosen v5 GUI or CanvasEngine integration
  5. validate the module in standalone and MMORPG modes
The compatibility layer and native v5 modules may coexist during this process.

Replace Signe types leaked by early v5 betas

Early v5 betas re-exported reactive and DI implementation types from RPGJS packages. Replace those imports before v5 stable: Plugins that deliberately use Signe internals should import and declare their @signe/* dependencies directly. See Advanced Signe Extension Points.

Register providers through RPGJS contracts

Import provider types from @rpgjs/common, including on the client and server. Factories may initialize asynchronously; the runtime waits for their result before exposing the provider:
Each object provider must choose exactly one creation strategy: useValue, useClass, useFactory, or useExisting. These contracts catch conflicting strategies during type checking instead of silently ignoring one. For synchronized gameplay property declarations, import RpgReadableSignal or RpgWritableSignal from @rpgjs/common. See Synchronization for the gameplay-level API. Import @signe/reactive directly only when an advanced plugin intentionally needs Signe behavior that RPGJS does not expose.

Use the stable Node storage names

Node storage factories and their RPGJS-owned contracts come from the same entry:
SQLite configuration requires exactly one source: databasePath for an RPGJS-owned connection or database for an existing compatible connection. See Node server in production for the memory lifecycle and production persistence guidance.

Compatibility Matrix

Compatibility Categories

Every v4 feature must be assigned one category before v5 stable:
  • Compatible: works without source changes
  • Translated: the compatibility layer adapts it automatically
  • Migration required: a documented, mechanical source change is required
  • Deprecated: still works in v5 but native v5 code should use another API
  • Unsupported: intentionally removed with a documented reason and alternative
Unclassified behavior is a release blocker.

Stable v5 Promise

Once v5.0 is stable, documented v5 APIs will not be removed or behaviorally redefined in a minor release. V4 compatibility APIs that ship in v5.0 will remain available throughout the v5 major line unless they are explicitly identified as experimental before that release. The final migration guide will include tested before/after examples, plugin status, save-data guidance, and a troubleshooting section based on migrations of real projects.