What’s New

pixijs

Games

pixijs release notes.

Latest v8.19.0 · by pixijsWebsitepixijs/pixijs

Changelog

v8.19.0

Added
  • Add HTML-in-Canvas texture support via pixi.js/html-source subpath with HTMLSource and ElementImageSource for rendering live DOM elements into PixiJS textures while keeping them interactive
  • Implement transientAttachment opt-in flag for MSAA RenderTextures in WebGPU to discard MSAA buffer instead of writing to memory on supported devices
Changed
  • Container.updateTransform now applies zero scale literally instead of coercing it to 1, so passing scaleX: 0 or scaleY: 0 will hide the container matching scale.set(0, 0)
  • ParticleContainer now respects blend mode inherited from ancestors instead of only reading its local blendMode
  • FillPattern gains a textureSpace option ('global' | 'local') to control pattern tiling behavior, with global as default, and setTransform(matrix) now applies the matrix directly without inversion
Fixed
  • Fix BitmapText trailing glyph after glyph-less word-break character
  • Fix SplitText crash when text begins with whitespace
  • Fix TilingSprite tileRotation shearing pattern on non-square sprites
  • Fix canvas renderer not rounding anchor offset when roundPixels is enabled
  • Fix renderer's maxBatchableTextures not being passed to non-default batchers
  • Handle null from getShaderSource/getShaderInfoLog on lost context
💾 Download

Installation:

npm install pixi.js@8.19.0

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.18.1...v8.19.0

🚨 Behavior Change
  • fix: Container.updateTransform honors zero scale (#12044) by @Zyie in https://github.com/pixijs/pixijs/pull/12046
    • Container.updateTransform({ scaleX: 0, scaleY: 0 }) previously coerced a zero scale to 1 (the code used opts.scaleX || 1), so passing 0 left the container at full size. It now applies zero scale literally, matching scale.set(0, 0). If you relied on updateTransform ignoring a zero scale, stop passing 0 when you mean full scale.
    const container = new Container();
    container.updateTransform({ scaleX: 0, scaleY: 0 });
    // before: scale coerced to (1, 1) — container stayed full-size
    // after:  scale applied as (0, 0) — container hidden, matching scale.set(0, 0)
    
  • fix: particle container inherit blend mode by @DmitriyGolub in https://github.com/pixijs/pixijs/pull/11978
    • ParticleContainer now respects the blend mode inherited from its ancestors. Previously the render pipe read the container's own local blendMode instead of the resolved groupBlendMode, so setting e.g. stage.blendMode = 'add' had no effect on particles. Particles nested under a parent with a non-default blend mode will now render differently (e.g. additive brightening) where they were silently ignored before. A blendMode set directly on the ParticleContainer is unchanged.
  • fix: FillPattern tiling and radial gradient sizing by @Zyie in https://github.com/pixijs/pixijs/pull/12037
    • FillPattern gains a textureSpace option ('global' | 'local'), while fixing several long-standing pattern/gradient sizing bugs. textureSpace defaults to 'global', so patterns now tile continuously across adjacent shapes instead of remapping per shape; setTransform(matrix) now applies the matrix you pass directly (it previously inverted and rescaled it by the texture size); and textureSpace: 'local' radial gradients now scale to the gradient's outer radius. Existing pattern fills and local radial gradients can render differently.

      If you hand-compensated for the old setTransform behavior (pre-inverting or scaling by texture size), remove that compensation. The legacy positional new FillPattern(texture, repetition) form still works.

    import { Assets, FillPattern, Graphics } from 'pixi.js';
    
    const texture = await Assets.load('pattern.png');
    
    // new options-object constructor with explicit textureSpace
    const pattern = new FillPattern({ texture, repetition: 'repeat', textureSpace: 'local' });
    
    const g = new Graphics().rect(0, 0, 200, 100).fill({ fill: pattern });
    
🎁 Added
  • feat: add HTML-in-Canvas texture support by @Zyie in https://github.com/pixijs/pixijs/pull/12053
    • A new opt-in pixi.js/html-source subpath renders live DOM elements into PixiJS textures while the element stays fully interactive in the browser (inputs editable, links clickable, CSS animations running). Use HTMLSource for a live element or ElementImageSource for an immutable snapshot. The element must be a direct child of the Pixi canvas. Importing the subpath also registers a lowest-priority Texture.from fallback for generic HTML elements, so it cannot affect apps that don't import it.
    import { Application, Sprite } from 'pixi.js';
    import { HTMLSource } from 'pixi.js/html-source';
    
    const app = new Application();
    await app.init({ resizeTo: window });
    document.body.appendChild(app.canvas);
    
    const form = document.createElement('form');
    form.innerHTML = '<input value="still editable" />';
    app.canvas.appendChild(form); // must be a direct child of the Pixi canvas
    
    const sprite = Sprite.from(new HTMLSource({ resource: form, autoUpdate: true }));
    app.stage.addChild(sprite); // live DOM mirrored to the GPU; the form stays interactive
    
  • feat: implement transientAttachment for MSAA RenderTextures for WebGPU by @GoodBoyDigital in https://github.com/pixijs/pixijs/pull/12050
    • Texture sources gain an opt-in transient flag so the WebGPU backend can discard the MSAA buffer at the end of a render pass (storeOp: 'discard') instead of writing it back to memory, and keep MSAA contents in tile memory on TBDR mobile GPUs where GPUTextureUsage.TRANSIENT_ATTACHMENT is available. This cuts memory bandwidth for single-pass MSAA render targets. Only set it on antialiased textures that follow a single-pass-then-discard pattern; a later loadOp: 'load' on a transient attachment yields undefined contents. Default is false, so existing code is unaffected. A WebGPU-only renderer.device.extensions.transientAttachment probe reports device support.
🐛 Fixed
🧹 Chores
New Contributors

Full Changelog: https://github.com/pixijs/pixijs/compare/v8.18.1...v8.19.0

v8.18.1

Fixed
  • Prevent error when using Application.domContainerRoot in Node.js

v8.18.0

Added
  • Add graphicsContextToSvg() function to export Graphics or GraphicsContext to a self-contained SVG string
  • Add mask channel selection option to setMask() to pick which texture channel (red or alpha) drives visibility
  • Allow preference parameter to accept an array of renderer types in autoDetectRenderer and Application.init
  • Add domContainerRoot getter to Application to access the HTMLDivElement wrapping DOMContainer elements
  • Add width option to MeshRope to allow explicit rope thickness decoupled from texture height
  • Add defaultAnchor option to renderer.generateTexture() and textureOptions parameter to RenderTexture.create()
Changed
  • Text/HTMLText/BitmapText with wordWrap: true and non-left align now return the true rendered width from text.width instead of reporting wordWrapWidth
Fixed
  • Text.width and word wrap returning incorrect values
  • Stroke-only Graphics masks now render correctly on Canvas renderer
  • Skip _applyMipRange for single-mip textures on iOS 18.0–18.1
  • Stale TextureMatrix when pooled textures reuse the same reference
  • Unhandled actions in GraphicsPath.transform() switch statement
  • VideoSource play/mediaReady recursion before video dimensions are known
💾 Download

Installation:

npm install pixi.js@8.18.0

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.17.1...v8.18.0

🚨 Behavior Change
  • fix: text.width and word wrap returning incorrect values by @Zyie in https://github.com/pixijs/pixijs/pull/12007
    • Text/HTMLText/BitmapText with wordWrap: true and non-left align (center/right/justify) now return the true rendered width from text.width instead of reporting wordWrapWidth. If you relied on text.width === wordWrapWidth for layout, use wordWrapWidth directly or wrap the text in a sized container.
    const text = new Text({
        text: 'hello',
        style: { wordWrap: true, wordWrapWidth: 800, align: 'center' },
    });
    // before: text.width === 800
    // after:  text.width reflects the rendered string width
    
🎁 Added
  • feat: add graphicsContextToSvg() for Graphics → SVG export by @GoodBoyDigital in https://github.com/pixijs/pixijs/pull/11989
    • Adds graphicsContextToSvg(source, precision?), a pure function that serializes a Graphics or GraphicsContext to a self-contained SVG string. Supports rects, circles, ellipses, rounded rects, polygons, bezier/quadratic/arc paths, strokes, holes (via fill-rule="evenodd"), and linear/radial gradients.
    import { Graphics, graphicsContextToSvg } from 'pixi.js';
    
    const g = new Graphics()
        .rect(0, 0, 100, 50)
        .fill({ color: 0xff0000 })
        .circle(150, 25, 25)
        .stroke({ color: 0x0000ff, width: 4 });
    
    const svgString = graphicsContextToSvg(g, 2);
    await navigator.clipboard.writeText(svgString);
    
  • feat: add mask channel selection for sprite masks by @Zyie in https://github.com/pixijs/pixijs/pull/11987
    • setMask() gains a channel option ('red' | 'alpha') to pick which texture channel drives visibility, matching how design tools like Figma apply PNG masks. Default remains 'red'.
    import { Assets, Sprite } from 'pixi.js';
    
    const photo = new Sprite(await Assets.load('photo.png'));
    const maskSprite = new Sprite(await Assets.load('mask-alpha.png'));
    
    photo.setMask({
        mask: maskSprite,
        channel: 'alpha',
    });
    
  • feat: allow preference to accept an array of renderer types by @Zyie in https://github.com/pixijs/pixijs/pull/11963
    • autoDetectRenderer and Application.init now accept an array of renderer names for preference, letting you restrict the fallback chain (e.g. disable WebGPU entirely) rather than only reorder it. A new RendererPreference type is exported.
    import { Application, autoDetectRenderer } from 'pixi.js';
    
    const renderer = await autoDetectRenderer({
        preference: ['webgl', 'canvas'],
    });
    
    const app = new Application();
    await app.init({ preference: ['webgl', 'canvas'] });
    
  • feat: provide a getter to the domElement via app.domContainerRoot by @carlos22 in https://github.com/pixijs/pixijs/pull/11974
    • Application exposes a read-only domContainerRoot getter returning the HTMLDivElement that wraps all DOMContainer elements, so apps can add CSS classes, inline styles, or customize the DOM overlay root.
    import { Application } from 'pixi.js';
    
    const app = new Application();
    await app.init({ resizeTo: window });
    
    app.domContainerRoot.classList.add('pixi-dom-layer');
    app.domContainerRoot.style.pointerEvents = 'auto';
    
  • feat: add width option to MeshRope by @mehmetcanakbay in https://github.com/pixijs/pixijs/pull/11990
    • MeshRope now accepts an explicit width for rope thickness, decoupling it from the texture's height. Omitting width preserves the previous texture.height default.
    import { MeshRope, Point, Texture } from 'pixi.js';
    
    const points = [new Point(0, 0), new Point(100, 50), new Point(200, 0)];
    
    const rope = new MeshRope({
        texture: Texture.from('snake.png'),
        points,
        width: 40,
    });
    
  • feat: add a default anchor to texture generation by @ksv90 in https://github.com/pixijs/pixijs/pull/12011
    • renderer.generateTexture() accepts a defaultAnchor option that's forwarded onto the produced Texture. RenderTexture.create() also gains a textureOptions parameter to pass through fields like defaultAnchor to the underlying Texture.
    import { Graphics, Sprite } from 'pixi.js';
    
    const shape = new Graphics().circle(0, 0, 50).fill(0xff3366);
    
    const texture = app.renderer.generateTexture({
        target: shape,
        defaultAnchor: { x: 0.5, y: 0.5 },
    });
    
    const sprite = new Sprite(texture);
    sprite.position.set(200, 200); // centered by default
    
🐛 Fixed
🧹 Chores
New Contributors

v8.17.1

Fixed
  • compressed textures ignoring resolution from URL (e.g. `@0.75x`)
  • center-align text correctly when words exceed wordWrapWidth
  • BitmapFont char keys from char codes to character strings
💾 Download

Installation:

npm install pixi.js@8.17.1

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.17.0...v8.17.1

🐛 Fixed
🧹 Chores

v8.17.0

Added
  • SplitText now supports tagStyles, so styled runs are correctly split into per-character Text objects with individual styles preserved
  • Bitmap text now supports whiteSpace modes (normal, pre, nowrap, pre-line, pre-wrap) with proper space and newline collapsing
  • Bitmap text word wrap now supports break-after characters including hyphens, en-dash, em-dash, and soft hyphen
  • Canvas text and split text now render align: 'justify' by distributing extra word spacing
  • Dynamic bitmap fonts scale drop shadow blur and distance proportionally to font size
  • Bitmap font xAdvance now uses true advance width from measureText() instead of bounding-box width
  • Kerning values are correctly scaled by fontScale in dynamic bitmap fonts
  • Add visibleChanged event to container that fires when visibility changes
  • Add function for removing aliases from resolver
Changed
  • BlurFilter now uses an optimized halving strength scheme by default, which changes visual output compared to previous versions
  • Text with align: 'justify' now uses wordWrapWidth for width calculation instead of maxLineWidth, matching CSS behavior, and the last line is no longer stretched
  • breakWords: true in HTMLText now correctly uses CSS word-break: break-word instead of break-all to match behavior of other text renderers
Fixed
  • Prevent filter corruption with TexturePool mipmap separation
  • Correctly handle offset in ColorMatrixFilter
  • Apply global filter offset to ParticleContainer rendering
  • Respect texture trim offset in NineSliceSprite
  • Return valid empty bounds from empty Graphics
  • Graphics getLocalBounds no longer returns stale data between operations in same frame
  • Graphics bounds now account for miter joins at sharp angles
  • Remove listener from old resource in BindGroup.setResource
💾 Download

Installation:

npm install pixi.js@8.17.0

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.16.0...v8.17.0

🚨 Behavior Change
  • BlurFilter now uses an optimized halving strength scheme by default, which changes visual output compared to previous versions. Set legacy: true to restore the old behavior.
    new BlurFilter({ legacy: true });
    // or globally:
    BlurFilter.defaultOptions.legacy = true;
    
  • Text with align: 'justify' now uses wordWrapWidth for width calculation instead of maxLineWidth, matching CSS behavior. The last line is no longer stretched.
  • breakWords: true in HTMLText now correctly uses CSS word-break: break-word instead of break-all to match behavior of other text renderers.
🎁 Added
  • feat: add tagged text support to canvasTextSplit by @Zyie in https://github.com/pixijs/pixijs/pull/11949
    • SplitText now supports tagStyles, so styled runs (e.g. <red>Hello</red> <blue>World</blue>) are correctly split into per-character Text objects with individual styles preserved.
  • feat: Improves text rendering and layout handling by @Zyie in https://github.com/pixijs/pixijs/pull/11947
    • Bitmap text now supports whiteSpace modes (normal, pre, nowrap, pre-line, pre-wrap) with proper space/newline collapsing
    • Bitmap text word wrap supports break-after characters (hyphens, en-dash, em-dash, soft hyphen)
    • Canvas text and split text now render align: 'justify' by distributing extra word spacing
    • Dynamic bitmap fonts scale drop shadow blur and distance proportionally to font size
    • Bitmap font xAdvance now uses true advance width from measureText() instead of bounding-box width
    • Kerning values correctly scaled by fontScale in dynamic bitmap fonts
  • feat: add visibleChanged event to container by @ikigai-bjorn-s in https://github.com/pixijs/pixijs/pull/11940
    container.on('visibleChanged', (visible) => {
        console.log('Visibility changed to:', visible);
    });
    
  • feat: Add function for removing aliases from resolver by @Sertion in https://github.com/pixijs/pixijs/pull/11921
🐛 Fixed
🧹 Chores
New Contributors

v8.16.0

Added
  • Canvas renderer support with experimental status
  • Tagged text feature for Text and HTMLText allowing custom tag styles
  • SplitText now automatically regenerates when TextStyle changes via styleChanged()
  • External texture support
  • parseSync method for spritesheet
  • Improved Pool typing for pool.get() method
  • Cube texture support
  • Mip level rendering support in the rendering system
  • Render to array layer capability
Changed
  • SplitText now more accurately splits Text across a wider range of TextStyle configurations, which may result in slight changes to character positioning
  • SplitText.from now correctly transfers the source anchor to the new instance by mapping the anchor to pivot coordinates
  • SplitBitmapText now correctly defaults to white fill, matching BitmapText behavior
  • HTMLText now correctly respects breakWords and no longer cuts off words that exceed wordWrapWidth
  • HTMLText now respects the alpha value of its fill and stroke
  • Text now correctly aligns when using align: 'right' or align: 'center'
  • Container.cullArea is now correctly interpreted in the container's local coordinate space and transformed to global coordinates before culling checks
  • graphics.texture() will now correctly apply a black tint
Fixed
  • Improve HTML text measurement accuracy
  • GlGeometrySystem VAO cache is now preserved
  • GC system now ensures render groups are marked as dirty
💾 Download

Installation:

npm install pixi.js@8.16.0

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.15.0...v8.16.0

🚨 Behavior Change
  • SplitText now more accurately splits Text across a wider range of TextStyle configurations. This may result in slight changes to character positioning.
  • Using SplitText.from from an existing Text now correctly transfers the source anchor to the new instance by mapping the anchor to pivot coordinates. This changes layout and positioning compared to previous behavior.
  • SplitBitmapText now correctly defaults to a white fill, matching the behavior of BitmapText.
  • HTMLText now correctly respects breakWords and no longer cuts off words that exceed wordWrapWidth.
  • HTMLText now respects the alpha value of its fill and stroke.
  • Text now correctly aligns when using align: 'right' or align: 'center', resulting in a small positional adjustment.
  • Container.cullArea is now correctly interpreted in the container’s local coordinate space and transformed to global coordinates before culling checks.
    // cullArea is defined in local space and transformed during culling
    container.cullArea = new Rectangle(0, 0, 100, 100);
    
  • graphics.texture(texture, 0x000000) will now correctly apply a black tint
🎁 Added
🐛 Fixed
🧹 Chores
New Contributors

v8.15.0

Added
  • Add unified GC system (GCSystem) with gcActive, gcMaxUnusedTime, and gcFrequency options
  • Add autoGarbageCollect option to view containers to disable automatic garbage collection for a node
  • Add unload method to manually release GPU resources associated with nodes
  • Move GPU context storage to GraphicsContext._gpuData
  • Move GPU data to Geometry._gpuData
  • Move GPUData to TextureSource
  • Move GL/GPU buffer storage to Buffer._gpuData and manage buffers list
  • Add descriptive names GCManagedHash
  • Update text GPU lifecycle and resolution updates
  • Improve ParticleContainer type definitions
  • Allow RenderTexture.create to accept dynamic option
Fixed
  • Allow negative values for Polygon and polyline in SVGParser
  • Prevent double returning of batches to pool
  • Add error handling for message processing in KTX worker
  • Fix RenderTexture ignoring format setting in WebGL
  • Add Multiple Render Targets (MRT) support
  • Correct viewport Y calculation for root render targets
  • Fix garbage collection for bitmap text
Deprecated
  • Deprecate TextureGCSystem and RenderableGCSystem in favor of GCSystem
💾 Download

Installation:

npm install pixi.js@8.15.0

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.14.3...v8.15.0

🎁 Added
🐛 Fixed
🧹 Chores
New Contributors

v8.15.0-rc

Pre-release
Added
  • Allow RenderTexture.create to accept dynamic option
  • Add unload method to reset GPU data
  • Add unified GC
  • Move GPU context storage to GraphicsContext._gpuData
  • Move GPU data to Geometry._gpuData
  • Move GPUData to TextureSource
  • Move GL/GPU buffer storage to Buffer._gpuData and manage buffers list
  • ParticleContainer type improvements
Changed
  • Update text GPU lifecycle and resolution updates
Fixed
  • SVGParser.ts allow negative values for Polygon(s)/polyline(s)
  • Prevent double returning of batches to pool
  • Add error handling for message processing in KTX worker
  • RenderTexture ignoring format setting (WebGL)
  • Add Multiple Render Targets (MRT) support
💾 Download

Installation:

npm install pixi.js@8.15.0-rc

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.14.3...v8.15.0-rc

🎁 Added
🐛 Fixed
New Contributors

v8.14.3

Fixed
  • Only create stage Container on init if it doesn't exist

v8.14.2

Fixed
  • Fix graphics memory leak and cleanup
  • Parse resolution and format from URLs in object sources in assets resolver
  • Track item count in Pool class
  • BitmanFontXMLParser should recognize xml fonts with versions
  • Remove automatically added 'resize' event listener from TextureSource on Texture destroy()
  • Resolve a typescript annoyance with Container.filters
  • Enable proper application reinitialization
  • Correct uBackTexture binding for filters with blendRequired
💾 Download

Installation:

npm install pixi.js@8.14.2

Development Build:

Production Build:

Documentation:

Changed

https://github.com/pixijs/pixijs/compare/v8.14.1...v8.14.2

🐛 Fixed
🧹 Chores
New Contributors