Phaser JSX

Home Edit


What

phaser-jsx allows you to use JSX in Phaser.

Why

I created this package to solve a personal pain point of mine—creating user interfaces in Phaser.

Currently, to add a text to a Phaser scene, you’d do something like this:

this.add.text(0, 0, 'Hello, world!');

Not so bad, right? But imagine you’re building a dialog modal with multiple shapes and event listeners:

const button = this.add.rectangle(/* ... */);
button.setInteractive();
button.on('pointerdown', () => {
  // ...
});

Now things get hairy.

Given my experience with React, I really enjoyed how the framework made imperative programming declarative. So to make this possible in Phaser, I created phaser-jsx.

How

Install the npm package:

npm install phaser-jsx

Enable JSX syntax by setting jsxImportSource to phaser-jsx in your build config like TypeScript:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "phaser-jsx"
  }
}

Now you can use JSX in files with the extension .jsx or .tsx:

// game.jsx
import Phaser from 'phaser';
import { Text, render } from 'phaser-jsx';

new Phaser.Game({
  scene: {
    create() {
      render(<Text text="Hello, world!" />, this);
    },
  },
});

This means you can refactor your UI to the following:

import { Rectangle, Text } from 'phaser-jsx';

function Button() {
  return (
    <Rectangle onPointerDown={(pointer) => console.log('Clicked!')}>
      <Text
        text="Button"
        style={{ fontSize: 18 }}
        ref={(text) => console.log(text)}
      />
    </Rectangle>
  );
}

Nice, right?

Let me know what you think. I’m open to feedback and ideas. Pull requests are welcome!