A Container groups display objects together. Moving, rotating, or scaling a container applies to everything inside it. Containers themselves are invisible; only their children render.
Containers can hold other containers, letting you build nested hierarchies (e.g., a game world container holding level containers, each holding sprite containers).
import { Container, Sprite } from 'pixi.js';
const group = new Container();
const sprite = Sprite.from('bunny.png');
group.addChild(sprite);
PixiJS provides an API for adding, removing, reordering, and swapping children in a container:
const container = new Container();
const child1 = new Container();
const child2 = new Container();
container.addChild(child1, child2);
container.removeChild(child1);
container.addChildAt(child1, 0);
container.swapChildren(child1, child2);
You can also remove a child by index or remove all children within a range:
container.removeChildAt(0);
container.removeChildren(0, 2);
To move a child to another container while keeping its current position on screen (preserving its world transform), use reparentChild or reparentChildAt:
otherContainer.reparentChild(child);
Containers emit lifecycle events you can listen to. There are two perspectives: events on the parent and events on the child.
childAdded and childRemoved fire on the container whose children changed:
group.on('childAdded', (child, parent, index) => { ... });
group.on('childRemoved', (child, parent, index) => { ... });
added and removed fire on the child itself when its parent changes:
const sprite = Sprite.from('bunny.png');
sprite.on('added', (parent) => {
console.log('Added to:', parent.label);
});
sprite.on('removed', (oldParent) => {
console.log('Removed from:', oldParent.label);
});
When using addChildAt to reposition a child that is already in the same container, the child is moved silently. None of the add/remove events fire, since the parent-child relationship hasn't changed.
visibleChanged fires whenever a container's visible property changes:
container.on('visibleChanged', (visible) => {
console.log('Visibility:', visible);
});
destroyed fires when destroy() is called, after internal cleanup but before listeners are removed:
container.on('destroyed', (container) => {
console.log('Destroyed:', container.label);
});
Containers support searching children by label using helper methods:
const child = new Container({ label: 'enemy' });
container.addChild(child);
container.getChildByLabel('enemy');
container.getChildrenByLabel(/^enemy/); // all children whose label starts with "enemy"
Set deep = true to search recursively through all descendants.
container.getChildByLabel('ui', true);
Use zIndex and sortableChildren to control render order within a container:
child1.zIndex = 1;
child2.zIndex = 10;
container.sortableChildren = true;
Call sortChildren() to manually re-sort if needed:
container.sortChildren();
Use this feature sparingly, as sorting can be expensive for large numbers of children.
A render group isolates a container's rendering instructions from its parent, so the GPU can transform the entire group without recalculating each child. Promote a container by setting isRenderGroup = true or calling enableRenderGroup().
Good candidates: UI layers that overlay the game world, large subtrees that move as a unit, or particle systems. See the Render Groups guide for details.
const uiLayer = new Container({ isRenderGroup: true });
cacheAsTexture optimizes rendering by drawing a container and its children to a single texture. Subsequent renders reuse this texture instead of rendering each child individually. This is useful for containers with many static elements, as it reduces the rendering workload.
cacheAsTexture is PixiJS v8's equivalent of the previous cacheAsBitmap functionality. If you're migrating from v7 or earlier, replace cacheAsBitmap with cacheAsTexture in your code.
const container = new Container();
const sprite = Sprite.from('bunny.png');
container.addChild(sprite);
// enable cache as texture
container.cacheAsTexture();
// update the texture if the container changes
container.updateCacheTexture();
// disable cache as texture
container.cacheAsTexture(false);
For more advanced usage, including setting cache options and handling dynamic content, refer to the Cache as Texture guide.