Use JSX in Phaser.
npm install phaser-jsx



- CodeSandbox
- Replit
- JSFiddle
- Examples
With JSX:
``tsx
// index.jsx
import Phaser from 'phaser';
import { Text, render } from 'phaser-jsx';
new Phaser.Game({
scene: {
create() {
render(
},
},
});
`
Without JSX:
`ts
// index.js
import Phaser from 'phaser';
import { jsx, render } from 'phaser-jsx';
new Phaser.Game({
scene: {
create() {
render(jsx(Phaser.GameObjects.Text, { text: 'Hello, world!' }), this);
},
},
});
`
NPM:
`sh`
npm install phaser-jsx
Yarn:
`sh`
yarn add phaser-jsx
CDN:
`html`
ES Modules:
`ts`
import { createElement, render } from 'phaser-jsx';
CommonJS:
`ts`
const { createElement, render } = require('phaser-jsx');
UMD:
`html`
For better type support, install @types/react:
`sh`
npm install @types/react --save-dev
Import the GameObject from phaser-jsx instead of phaser:
`ts`
import { Text } from 'phaser-jsx';
> [!TIP]
> All GameObjects exported from phaser-jsx are aliases of the GameObjects from phaser.
Update your tsconfig.json:
`json`
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "phaser-jsx"
}
}
Update your Vite config:
`ts
// vite.config.mjs
import { defineConfig } from 'vite';
export default defineConfig({
esbuild: {
jsxImportSource: 'phaser-jsx',
},
});
`
If you're not using jsxImportSource, you can set a JSX pragma at the top of your file:
`tsx`
/* @jsx jsx /
import { jsx } from 'phaser-jsx';
This package follows React conventions like having createElement and jsx-runtime.
The render function renders game objects inside a scene.
If you need nesting and relative positioning, use Container:
`tsx`
Create a ref for your game object:
`ts
import { useRef } from 'phaser-jsx';
function MyComponent() {
const textRef = useRef
// ...
}
`
Pass your ref to the JSX element:
`tsx`
// ...
return
Access your game object:
`ts`
function handleClick() {
textRef.current?.text = 'Clicked';
}
Alternatively, you can get the game object with a callback ref:
`tsx`
gameObject.text = 'Hello, world!';
}}
/>
Retrieve the current Scene with the useScene hook:
`ts
import { useScene } from 'phaser-jsx';
function MyComponent() {
const scene = useScene();
// ...
}
`
> [!WARNING]
> Don't use the useScene hook if you start multiple Scenes.
Type your Scene with TypeScript:
`ts
class MyScene extends Phaser.Scene {
// ...
}
const scene = useScene
``
Release is automated with Release Please.