SKILL.md
$27
Topics
Topic
Reference
When
Choosing a backend
Preference forms, per-renderer options, systems and pipes
Per-frame execution
Priority order, time units, manual rendering
For deep dives into any single topic, open the corresponding reference file. Non-browser targets (DOMAdapter, WebWorkerAdapter, custom adapters, strict CSP) are covered in the pixijs-environments skill.
Decision guide
- Setting up an Application? Start with
pixijs-application. This skill explains what the renderer does under the hood.
- Choosing between WebGL and WebGPU? Use
['webgpu', 'webgl']as your preference array. WebGPU is fastest where available; WebGL is the reliable fallback. Seereferences/renderers.md.
- Running in a Web Worker? Set
DOMAdapter.set(WebWorkerAdapter)beforeapp.init. See thepixijs-environmentsskill for complete setup.
- Need manual control over when rendering happens? Set
autoStart: falseand callapp.renderer.render(app.stage)from your own loop. Seereferences/render-loop.md.
- Integrating with a physics library? Add your update at
UPDATE_PRIORITY.HIGHso physics runs before the render atLOW. Seereferences/render-loop.md.
- Writing a custom renderable? Implement a
RenderPipe. Seepixijs-custom-renderingskill.
- Running under strict CSP? Import
'pixi.js/unsafe-eval'. See thepixijs-environmentsskill.
Quick concepts
Renderer = systems + pipes
Each renderer is composed of Systems (lifecycle services: textures, buffers, state, filters, masks) and RenderPipes (per-renderable instruction builders: sprite, graphics, mesh, particle, text, tiling). Writing a custom renderable means implementing a RenderPipe and registering it via extensions.
The render loop
app.ticker.add(fn) registers a callback that runs every frame. The TickerPlugin registers app.render() at UPDATE_PRIORITY.LOW, so ticker callbacks at NORMAL or HIGH run before the draw. Disable the plugin with autoStart: false for manual control.
Environments
DOMAdapter abstracts every DOM call PixiJS makes (canvas creation, image loading, fetch, XML parsing). Swap with DOMAdapter.set(WebWorkerAdapter) for Workers or implement a custom Adapter for Node/SSR. Must be done before Application.init.
Common Mistakes
[HIGH] Accessing app.renderer before init() resolves
Wrong:
const app = new Application();
app.init({ width: 800, height: 600 });
console.log(app.renderer.name); // undefined — init() is async
Correct:
const app = new Application();
await app.init({ width: 800, height: 600 });
console.log(app.renderer.name); // 'webgl' | 'webgpu' | 'canvas'
Application.init() is async. app.renderer, app.canvas, and app.screen do not exist until after the promise resolves.
[HIGH] Setting DOMAdapter after Application.init
Wrong:
const app = new Application();
await app.init({ width: 800, height: 600 });
DOMAdapter.set(WebWorkerAdapter); // too late — init already allocated resources
Correct:
DOMAdapter.set(WebWorkerAdapter);
const app = new Application();
await app.init({ width: 800, height: 600 });
The adapter abstracts DOM calls the renderer makes during construction (canvas creation, image loading, fetch). Swap it before init() or the wrong adapter is baked into the renderer.
[MEDIUM] Treating preference as a guarantee
Wrong:
await app.init({ preference: "webgpu" });
// assume WebGPU is active
useWebGPUOnlyFeature(app.renderer);
Correct:
await app.init({ preference: "webgpu" });
if (app.renderer.name === "webgpu") {
useWebGPUOnlyFeature(app.renderer);
}
preference is a hint, not a demand. If the browser lacks WebGPU support, PixiJS falls back to WebGL (or Canvas). Always branch on renderer.name for backend-specific code.