PluginBench
Skill
Pass
Audit score 90

pixijs-core-concepts

pixijs/pixijs-skills

Understand PixiJS v8 rendering: backend selection, render loop, and frame pipeline.

What is pixijs-core-concepts?

This skill covers how PixiJS v8 gets pixels on screen through its systems-and-pipes renderer architecture, the per-frame render loop, and environment adaptation. Use it when working with renderer backends (WebGL/WebGPU/Canvas), the render pipeline, RenderTextures, context/device loss recovery, and code-splitting renderer systems.

  • Choose between WebGLRenderer, WebGPURenderer, and CanvasRenderer via autoDetectRenderer and preference hints
  • Understand the render loop: ticker callbacks, UPDATE_PRIORITY ordering, and manual vs. automatic rendering
  • Render into RenderTextures and RenderTargets with flipY, mipLevel, layer, and depth attachment control
  • Handle WebGL context loss and WebGPU device loss recovery
  • Lazy-load renderer systems and pipes through WebGLLoader, WebGPULoader, and CanvasLoader extensions
  • Adapt PixiJS to non-browser environments (Web Workers, SSR) via DOMAdapter swapping

How to install pixijs-core-concepts

npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-core-concepts
Prerequisites
  • PixiJS v8 installed
  • Familiarity with async/await (Application.init is async)
  • Basic understanding of GPU rendering concepts (optional but helpful)
Claude Code
Cursor
Windsurf
Cline

How to use pixijs-core-concepts

  1. 1.Check app.renderer.name after await app.init() to confirm which backend was selected
  2. 2.Register ticker callbacks with app.ticker.add(fn) to run logic each frame; use UPDATE_PRIORITY constants to control order
  3. 3.Call app.renderer.render({ container, target }) manually if autoStart: false, or let TickerPlugin drive it automatically
  4. 4.Use app.renderer.extract.texture({ target }) to render a subtree into a texture
  5. 5.Set DOMAdapter before Application.init if targeting Web Workers or custom environments
  6. 6.Inspect references/renderers.md and references/render-loop.md for deep dives into backend selection and priority ordering

Use cases

Good for
  • Selecting the best GPU backend for your target browsers and falling back gracefully when WebGPU is unavailable
  • Integrating physics or custom update logic into the render loop at the correct priority
  • Rendering scenes into textures for post-processing, UI composition, or off-screen rendering
  • Recovering from GPU context loss in long-running applications
  • Running PixiJS in a Web Worker or server-side rendering context
Who it's for
  • PixiJS application developers building games or interactive graphics
  • Graphics engineers optimizing for multiple GPU backends
  • Developers integrating PixiJS with physics engines or custom rendering pipelines
  • Teams deploying PixiJS in Web Workers or non-DOM environments

pixijs-core-concepts FAQ

Why is app.renderer undefined after new Application()?

Application.init() is async and must be awaited. The renderer, canvas, and screen properties do not exist until the promise resolves.

How do I guarantee WebGPU is used?

You cannot. Set preference: ['webgpu', 'webgl'] as a hint, but always check app.renderer.name to branch on the actual backend, since WebGPU may not be available.

When should I set DOMAdapter?

Before Application.init(). The adapter abstracts DOM calls during renderer construction; setting it after init() is too late.

How do I run custom logic before or after rendering each frame?

Use app.ticker.add(fn, priority) to register callbacks. Callbacks at UPDATE_PRIORITY.HIGH run before the render (at LOW), so physics or updates happen first.

Can I render a scene into a texture?

Yes. Call app.renderer.extract.texture({ target: myContainer }) or pass target to renderer.render({ container, target }) to render into a RenderTexture or RenderTarget.

Full instructions (SKILL.md)

Source of truth, from pixijs/pixijs-skills.


name: pixijs-core-concepts description: "Use this skill when understanding how PixiJS v8 renders frames: the systems-and-pipes renderer, the render loop, and how the library adapts to different environments. Covers WebGLRenderer/WebGPURenderer/CanvasRenderer selection, renderer.render() pipeline, environment detection, rendering into RenderTextures and RenderTargets (flipY, mipLevel, layer, bind/push/pop, copyDepthTexture), WebGL context loss and WebGPU device loss recovery, and pointers to per-topic deep dives. Triggers on: renderer, WebGL, WebGPU, Canvas, render loop, render pipeline, systems, environments, autoDetectRenderer, RenderTexture, RenderTarget, render to texture, flipY, mipLevel, renderTarget.bind, copyToTexture, copyDepthTexture, depth-only, WebGLLoader, WebGPULoader, CanvasLoader, RendererLoader, lazy-load renderer systems, code splitting, context lost, webglcontextlost, device lost, GPUDevice.lost." license: MIT

Foundational model for how PixiJS v8 gets pixels on the screen: the renderer decides which GPU backend to use, the render loop drives per-frame work, and the environment layer adapts the library to browser, Web Worker, or SSR contexts. For the scene graph itself (Containers, transforms, destroy), see pixijs-scene-core-concepts.

Quick Start

console.log(app.renderer.name); // 'webgl' | 'webgpu' | 'canvas'

app.ticker.add((ticker) => {
  sprite.rotation += 0.01 * ticker.deltaTime;
});

const tex = app.renderer.extract.texture({ target: app.stage });

app.renderer.render({ container: app.stage });

app.renderer is the WebGLRenderer, WebGPURenderer, or CanvasRenderer chosen by autoDetectRenderer. The TickerPlugin drives renderer.render() automatically; call it manually only with autoStart: false. Backend selection happens in Application.init({ preference }); see pixijs-application for setup.

Related skills: pixijs-application (Application construction and lifecycle), pixijs-ticker (per-frame logic, priorities, FPS capping), pixijs-environments (Web Worker, SSR, strict CSP), pixijs-custom-rendering (writing a RenderPipe), pixijs-scene-core-concepts (scene graph basics).

Topics

TopicReferenceWhen
Choosing a backendreferences/renderers.mdPreference forms, per-renderer options, systems and pipes
Per-frame executionreferences/render-loop.mdPriority 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. See references/renderers.md.
  • Running in a Web Worker? Set DOMAdapter.set(WebWorkerAdapter) before app.init. See the pixijs-environments skill for complete setup.
  • Need manual control over when rendering happens? Set autoStart: false and call app.renderer.render(app.stage) from your own loop. See references/render-loop.md.
  • Integrating with a physics library? Add your update at UPDATE_PRIORITY.HIGH so physics runs before the render at LOW. See references/render-loop.md.
  • Writing a custom renderable? Implement a RenderPipe. See pixijs-custom-rendering skill.
  • Rendering into a texture or a custom render target? Pass target to renderer.render(), or build a RenderTarget with explicit color and depth attachments. See references/renderers.md.
  • Running under strict CSP? Import 'pixi.js/unsafe-eval'. See the pixijs-environments skill.

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. Backend-specific systems and pipes can be dynamic-imported through a renderer loader extension (WebGLLoader, WebGPULoader, CanvasLoader); see references/renderers.md.

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.

API Reference