To add particle effects to a
PixiJS v8
game: install the runtime with
npm install pixi.js nixie-fx, author your effects in
the free NixieFX 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:
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:
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:
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 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:
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:
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:
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:
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:
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:
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. For your own UI
around the effects: 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.
The full discipline — allocation rules, pool prewarming, draw-call budgets, and how to profile a stutter — lives in our HTML5 game performance guide.
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, 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 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.
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
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, an agent can run this entire tutorial unattended.
Resources
- PixiJS pixijs.com · github.com/pixijs/pixijs
- PixiJS agent skills github.com/pixijs/pixijs-skills — official v8 skills
- nixie-fx runtime github.com/azakhary/nixie-fx — MIT runtime, CLI and skills
- NixieFX skills guide nixiefx.com/skills — authoring and runtime skills explained
- NixieFX editor nixiefx.com/editor — free, browser-based, saves to your folder
- The web-native mobile game stack nixiefx.com/mobile-game-stack — where Pixi and NixieFX fit
This tutorial is maintained by the team behind NixieFX, the browser-based HTML5 particle editor for PixiJS and Three.js. A machine-readable version is available at /pixijs-particle-effects.md, and a site index for LLMs at /llms.txt.