# PixiJS particle effects: juicing game UI with NixieFX

> Tutorial · Updated August 2026 · By the NixieFX team · Canonical:
> https://nixiefx.com/pixijs-particle-effects/

A crisp UI is table stakes; a *juicy* UI is what players remember. This
hands-on tutorial builds HTML5 game UI in PixiJS v8 and wires real particle effects
to it — a button press burst and a reward coin fountain — authored in the
free, browser-based NixieFX editor.

## TL;DR — what you'll build

To add particle effects to a [PixiJS v8](https://pixijs.com) game: install the
runtime with `npm install pixi.js nixie-fx`, author your effects in the free
[NixieFX editor](https://nixiefx.com/editor/) (it saves plain JSON into your
own project folder), export them with `npx nixie-fx export ./my-vfx` into an
`out/vfx` bundle, then load that bundle with `loadVfxExportBundle`, render it
with `PixiVfxRenderer` parented to your stage, and call `update()` from
`app.ticker` once per frame. This page walks through the whole path: a claim
button that sparks on press and a coin fountain for the reward popup.

## Why does UI juice matter in free-to-play games?

Free-to-play UI is not decoration — it is the reward loop made visible. The
moments that decide whether an action *feels* worth repeating are almost all
UI moments:

- **Button feedback.** A press that flashes and throws a handful of sparks
  confirms the tap instantly, even before the server responds. Silent buttons
  read as broken buttons.
- **Reward bursts.** Coins fountaining out of a chest, stars popping on a
  level-clear screen — the particle burst *is* the dopamine hit. Games
  A/B-test these because they measurably move retention.
- **Screen transitions.** A drift of embers or a swoosh of motes carries the
  eye between screens and hides loading seams.

PixiJS is the natural home for this layer: it is the standard 2D web
renderer, and its `ParticleContainer` is designed to draw thousands of
lightweight sprites cheaply. What Pixi does not ship is an *authoring tool* —
designing a burst by editing velocity numbers in code is miserable. That is
the gap NixieFX fills: a full particle editor in the browser, exporting to a
small runtime that renders through Pixi.

## How do you set up PixiJS v8 with NixieFX?

Install both packages in your web game project:

```sh
npm install pixi.js nixie-fx
```

If you work with an AI coding agent (Claude Code, Cursor, Codex, Grok, Copilot,
Gemini CLI…), also install the agent skills for both libraries so it writes
correct Pixi v8 and NixieFX code instead of hallucinating old APIs:

```sh
npx skills add https://github.com/pixijs/pixijs-skills
npx skills add https://github.com/azakhary/nixie-fx
```

The NixieFX command installs two skills: `nixie-fx-authoring` (create,
validate and export effects) and `nixie-fx-runtime` (integrate exported
effects into a running game). Now the minimal Pixi v8 scene — an application
and one claimable reward button:

```ts
import { Application, Assets, Sprite } from "pixi.js";

const app = new Application();
await app.init({ background: "#14110e", resizeTo: window });
document.body.appendChild(app.canvas);

const buttonTexture = await Assets.load("ui/claim-button.png");
const button = new Sprite(buttonTexture);
button.anchor.set(0.5);
button.position.set(app.screen.width / 2, app.screen.height - 120);
button.eventMode = "static";
button.cursor = "pointer";
app.stage.addChild(button);
```

Nothing NixieFX-specific yet — this is stock Pixi v8: `Application` with
async `init()`, an `eventMode: "static"` sprite that receives pointer events.

## How do you author a particle effect in the NixieFX editor?

The [NixieFX editor](https://nixiefx.com/editor/) is free and runs entirely
in your browser — no account, no install. It opens a folder on your own disk
(a NixieFX project is any folder containing a `vfx-editor.prj` file) and
saves every effect as plain JSON inside it, so your VFX live in your game
repo and diff like code. You can scaffold and round-trip a project from the
terminal too:

```sh
npx nixie-fx effect create ./my-vfx --profile portable
npx nixie-fx validate ./my-vfx
```

For this tutorial, author two effects:

- **spark-burst** — the button press. One emitter with a single burst of
  15–25 particles, radial initial velocity, additive blending, a warm
  white-to-amber gradient that fades out, and size shrinking over each
  particle's lifetime. Total life under half a second — feedback, not
  fireworks.
- **coin-fountain** — the reward popup. A looping emitter that sprays
  coin-textured particles upward against gravity, with slight rotation over
  lifetime and a spread cone wide enough to feel abundant.

When both look right in the live preview, export. The editor (or the CLI)
compiles your authored effects into a `out/vfx` runtime bundle — a
`manifest.json`, compiled effect JSON under `effects/`, and the texture
assets they reference:

```sh
npx nixie-fx export ./my-vfx
```

> Games consume only the generated `out/vfx` bundle — never the editor's
> source `particle-data` files. The manifest is the source of truth: it lists
> every effect, every asset path, and a per-backend support report, so a
> broken export fails loudly at load time instead of silently at runtime.

## How do you load the exported effects in PixiJS?

Copy (or serve) `out/vfx` as static files in your app — here it is mounted at
`/vfx/`. Loading is three steps: fetch the manifest and effect JSON, hand
them to `loadVfxExportBundle`, and stand up a texture provider that maps the
manifest's asset paths to Pixi textures:

```ts
import { Assets, Texture } from "pixi.js";
import { loadVfxExportBundle } from "nixie-fx/export";
import { PixiVfxRenderer } from "nixie-fx/pixi";

// 1. Read the export produced by the editor.
const manifest = await fetch("/vfx/manifest.json").then((r) => r.json());

const effectsByPath: Record<string, unknown> = {};
for (const entry of manifest.effects) {
  effectsByPath[entry.path] = await fetch(`/vfx/${entry.path}`).then(
    (r) => r.json(),
  );
}

// 2. Validate and index the bundle for the Pixi backend.
const bundle = loadVfxExportBundle(
  { manifest, effectsByPath, assetPaths: manifest.assets.map((a) => a.path) },
  { requiredBackend: "pixi2d", requireEveryAsset: true },
);

// 3. Texture provider: manifest asset paths -> Pixi textures.
const textures = new Map<string, Texture>();
for (const asset of manifest.assets) {
  if (asset.type === "texture") {
    textures.set(asset.path, await Assets.load(`/vfx/${asset.path}`));
  }
}
const textureProvider = {
  getTexture: (ref) => textures.get(ref.path),
  release: () => textures.clear(),
};

const vfx = new PixiVfxRenderer({ parent: app.stage, textureProvider });
```

`loadVfxExportBundle` rejects a manifest whose validation failed and, with
`requiredBackend: "pixi2d"`, surfaces any effect the Pixi backend cannot
fully render. The renderer parents itself to `app.stage`, so effects draw
above your UI in normal stacking order — you can also parent it to any
`Container`, for example a dedicated VFX layer.

## How do you attach effects to UI events?

The runtime is deliberately boring: one `update()` per frame from the ticker,
one `createEffect()` per spawned effect. Wire the spark burst to the button
and reap finished instances:

```ts
import type { PixiVfxEffectInstance } from "nixie-fx/pixi";

const spark = bundle.effectsById.get("spark-burst");
const live = new Set<PixiVfxEffectInstance>();

button.on("pointerdown", () => {
  live.add(
    vfx.createEffect(spark, {
      position: [button.x, button.y, 0],
      seed: (Math.random() * 0xffffffff) >>> 0,
    }),
  );
});

app.ticker.add((ticker) => {
  vfx.update(ticker.deltaMS / 1000);
  for (const fx of live) {
    if (!fx.isActive) {
      vfx.removeEffect(fx, true); // done — destroy its containers
      live.delete(fx);
    }
  }
});
```

Two details matter here. The simulation is **deterministic**: the same effect
with the same `seed` replays identically, which is why the example randomizes
the seed per press — every burst should look a little different. And
`update()` takes **seconds**, so Pixi's `ticker.deltaMS` is divided by 1000.

The looping coin fountain works better as one persistent instance you start
and stop with the reward popup:

```ts
const fountain = vfx.createEffect(bundle.effectsById.get("coin-fountain"), {
  position: [app.screen.width / 2, 260, 0],
  autoStart: false,
});

function openRewardPopup() {
  fountain.spawn(); // start emitting coins
}

function closeRewardPopup() {
  fountain.stop();
}
```

An instance also supports `reset()` to rewind it and `setPosition()` to
follow a moving UI element — handy for a fountain anchored to an animated
chest. On teardown (leaving the scene, hot-reload), release everything:

```ts
vfx.destroy();          // removes and destroys all effect instances
textureProvider.release();
```

> Performance note: each emitter renders through Pixi's `ParticleContainer`,
> built for thousands of lightweight sprites — a 20-particle button burst is
> nowhere near any budget. The usual mobile discipline still applies: keep
> effect textures in your atlas workflow, prefer a persistent looping
> instance over re-creating effects every frame, and let the reap loop above
> destroy finished one-shots. Parent retained display objects once and toggle
> `visible` instead of `addChild`/`removeChild` per frame, and avoid runtime
> `Graphics` vector drawing for gameplay visuals — bake shapes into atlas
> textures. Full discipline: the
> [HTML5 game performance guide](https://nixiefx.com/html5-game-performance/).

## Frequently asked questions

### How do I add particle effects to a PixiJS v8 game?

Install a particle runtime next to Pixi (`npm install pixi.js nixie-fx`),
author effects in the free [NixieFX editor](https://nixiefx.com/editor/), and
export them to an `out/vfx` bundle. In your app, load the bundle with
`loadVfxExportBundle` from `nixie-fx/export`, create a `PixiVfxRenderer` from
`nixie-fx/pixi` parented to your stage, and call its `update()` from
`app.ticker` once per frame.

### Is the NixieFX particle editor free to use?

Yes. It runs entirely in your browser at
[nixiefx.com/editor](https://nixiefx.com/editor/) with no account or install.
It opens a folder on your own disk, saves effects as plain JSON in that
folder, and exports the runtime bundle to `out/vfx`. The runtime is
MIT-licensed and open source at
[github.com/azakhary/nixie-fx](https://github.com/azakhary/nixie-fx).

### Can I reuse the same particle effects in Three.js?

Yes. NixieFX ships one deterministic simulation with two renderer adapters:
`PixiVfxRenderer` (`nixie-fx/pixi`) for 2D and UI, and `ThreeVfxRenderer`
(`nixie-fx/three`) for 3D scenes. The same exported effect JSON drives both —
one VFX pipeline for UI juice and in-world effects. See
[the web-native mobile game stack](https://nixiefx.com/mobile-game-stack/)
for how the two layers fit together.

### How many particles can a PixiJS UI effect afford on mobile?

Fewer than you'd think, and that's fine: a button burst reads well at 10–30
particles, a reward fountain at 50–150. Because emitters render through
Pixi's `ParticleContainer` — designed for thousands of lightweight sprites —
typical UI effects are cheap even on mid-range phones. Spend your budget on
good gradients and timing, not raw particle count.

### Can AI coding agents author and integrate NixieFX effects?

Yes — that is the point of the skills.
`npx skills add https://github.com/azakhary/nixie-fx` installs
`nixie-fx-authoring` (create, validate, export effects) and
`nixie-fx-runtime` (load bundles, wire providers, per-frame updates).
Combined with the
[official PixiJS skills](https://github.com/pixijs/pixijs-skills), an agent
can run this entire tutorial unattended.

## Resources

- **PixiJS** — https://pixijs.com · https://github.com/pixijs/pixijs
- **PixiJS agent skills** — https://github.com/pixijs/pixijs-skills (official
  v8 skills)
- **nixie-fx runtime** — https://github.com/azakhary/nixie-fx (MIT runtime,
  CLI and skills)
- **NixieFX skills guide** — https://nixiefx.com/skills/
- **NixieFX editor** — https://nixiefx.com/editor/ (free, browser-based,
  saves to your folder)
- **The web-native mobile game stack** —
  https://nixiefx.com/mobile-game-stack/

---

*This tutorial is maintained by the team behind
[NixieFX](https://nixiefx.com/), the browser-based HTML5 particle editor for PixiJS
and Three.js. A machine-readable version of this page lives at
https://nixiefx.com/pixijs-particle-effects.md, and a site index for LLMs at
https://nixiefx.com/llms.txt.*
