Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
pixijs avatar

Pixijs Ticker

  • 3k installs
  • 293 repo stars
  • Updated June 4, 2026
  • pixijs/pixijs-skills

pixijs-ticker is a PixiJS v8 skill for Ticker callbacks, deltaTime timing, priority ordering, and FPS control.

About

PixiJS Ticker covers per-frame callbacks, render loop control, and timing units in PixiJS v8 where app.ticker drives registered updates and app.render at UPDATE_PRIORITY.LOW. deltaTime is a frame-rate-independent multiplier near 1.0 at 60fps, deltaMS provides speed-scaled milliseconds for pixels-per-second math, and elapsedMS exposes raw uncapped frame timing for profiling. Priority ordering runs INTERACTION at 50, HIGH at 25, NORMAL at 0, LOW at -25 where render registers, and UTILITY at -50. Patterns show rotation with deltaTime, movement with deltaMS, maxFPS and speed scaling, and per-object onRender hooks for lightweight per-sprite updates. Ticker.shared versus dedicated instances and add, addOnce, and remove lifecycle are documented alongside manual rendering paths when you bypass the default loop. Related skills link to pixijs-application for sharedTicker setup, pixijs-performance for frame budget work, and pixijs-migration-v8 for signature changes from v7.

  • deltaTime versus deltaMS versus elapsedMS timing units.
  • UPDATE_PRIORITY ordering for physics before render.
  • maxFPS, minFPS, and speed scaling on app.ticker.
  • Per-object onRender hook for sprite-local updates.
  • Ticker.shared versus custom Ticker instance patterns.

Pixijs Ticker by the numbers

  • 3,017 all-time installs (skills.sh)
  • +218 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Ranked #166 of 2,277 Frontend Development skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

pixijs-ticker capabilities & compatibility

Capabilities
ticker add addonce remove lifecycle · deltatime deltams elapsedms selection · update_priority callback ordering · maxfps minfps and speed controls · per object onrender updates · manual rendering and shared ticker guidance
Use cases
frontend
Pricing
Free
From the docs

What pixijs-ticker says it does

app.render() is registered at LOW by the TickerPlugin
SKILL.md
sprite.rotation += 0.01 * ticker.deltaTime;
SKILL.md
npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-ticker

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs3k
repo stars293
Security audit3 / 3 scanners passed
Last updatedJune 4, 2026
Repositorypixijs/pixijs-skills

How do I write frame-rate-independent animation and ordered update logic in PixiJS v8?

Run per-frame PixiJS v8 logic with Ticker deltaTime, priority ordering, FPS caps, and onRender hooks.

Who is it for?

PixiJS developers implementing game loops, animations, and physics ticks in canvas apps.

Skip if: Skip for non-Pixi animation, CSS transitions, or scene graph structure without per-frame logic.

When should I use this skill?

User works with app.ticker, deltaTime, UPDATE_PRIORITY, maxFPS, or onRender in PixiJS v8.

What you get

Correct Ticker callback with deltaTime or deltaMS usage, priority placement, and optional FPS caps.

  • Ticker callback setup
  • Frame-timing configuration
  • Render-loop priority ordering

Files

SKILL.mdMarkdownGitHub ↗

app.ticker runs registered callbacks every frame and drives app.render() at UPDATE_PRIORITY.LOW. Each callback receives the Ticker instance; read deltaTime as a frame-rate-independent multiplier (≈1.0 at 60fps) or deltaMS for real-time calculations.

Quick Start

app.ticker.add((ticker) => {
  sprite.rotation += 0.01 * ticker.deltaTime;
  sprite.x += (200 / 1000) * ticker.deltaMS;
});

app.ticker.add(
  (ticker) => {
    updatePhysics(ticker.deltaMS);
  },
  undefined,
  UPDATE_PRIORITY.HIGH,
);

app.ticker.maxFPS = 30;
app.ticker.speed = 0.5;

sprite.onRender = () => {
  sprite.scale.x = Math.sin(performance.now() / 500);
};

Related skills: pixijs-application (Application setup and sharedTicker option), pixijs-performance (frame rate optimization), pixijs-migration-v8 (v7 ticker signature changes).

Core Patterns

Time units

The Ticker exposes three timing values, each for different use cases:

PropertyTypeScaled by speed?Capped by minFPS?Use case
deltaTimedimensionless (~1.0 at 60fps)yesyesFrame-rate-independent animation multipliers
deltaMSmillisecondsyesyesTime-based calculations (pixels/sec)
elapsedMSmillisecondsnonoRaw measurement, profiling
import { Application } from "pixi.js";

const app = new Application();
await app.init({ width: 800, height: 600 });

app.ticker.add((ticker) => {
  // deltaTime: dimensionless scalar, ~1.0 at 60fps
  sprite.rotation += 0.1 * ticker.deltaTime;

  // deltaMS: real milliseconds (speed-scaled, capped)
  sprite.x += (200 / 1000) * ticker.deltaMS; // 200 pixels per second

  // elapsedMS: raw milliseconds (no scaling, no cap)
  console.log(`Raw frame time: ${ticker.elapsedMS}ms`);
});

Tension note: deltaTime is not milliseconds. It is deltaMS * Ticker.targetFPMS where targetFPMS is 0.06 (i.e. 1/16.67). At exactly 60fps, deltaTime is 1.0. At 30fps, deltaTime is 2.0. This catches people who treat it as a time value.

Priority ordering and context binding

import { Application, UPDATE_PRIORITY } from "pixi.js";

const app = new Application();
await app.init({ width: 800, height: 600 });

// INTERACTION (50) > HIGH (25) > NORMAL (0) > LOW (-25) > UTILITY (-50)
// app.render() is registered at LOW by the TickerPlugin

app.ticker.add(
  (ticker) => {
    // Physics runs before normal-priority callbacks
    updatePhysics(ticker.deltaMS);
  },
  undefined,
  UPDATE_PRIORITY.HIGH,
);

app.ticker.add((ticker) => {
  // Default priority (NORMAL = 0), runs after HIGH but before render
  updateAnimations(ticker.deltaTime);
});

// Pass `this` as the second argument to preserve context on class methods
class GameSystem {
  public speed = 5;
  public position = 0;

  public update(ticker: Ticker): void {
    this.position += this.speed * ticker.deltaTime;
  }
}

const system = new GameSystem();
app.ticker.add(system.update, system);
app.ticker.remove(system.update, system); // must match both fn and context

Frame rate capping

import { Ticker } from "pixi.js";

const ticker = new Ticker();

ticker.maxFPS = 30; // Cap at 30fps (skips frames to maintain interval)
ticker.minFPS = 10; // Cap deltaTime so it never exceeds 10fps worth

// If maxFPS < minFPS, minFPS is lowered to match
// If minFPS > maxFPS, maxFPS is raised to match

maxFPS skips update calls to enforce a ceiling. minFPS caps deltaTime/deltaMS so large frame drops don't produce enormous deltas (default minFPS is 10).

Per-object onRender hook

import { Sprite, Assets, Application } from "pixi.js";

const app = new Application();
await app.init({ width: 800, height: 600 });

const texture = await Assets.load("bunny.png");
const sprite = new Sprite(texture);
app.stage.addChild(sprite);

sprite.onRender = (renderer) => {
  sprite.rotation += 0.01;
};

onRender is called during scene graph traversal, before GPU rendering. It is an alternative to a global ticker callback when logic is tied to a specific display object.

Ticker.shared, Ticker.system, and new Ticker

import { Ticker, UPDATE_PRIORITY } from "pixi.js";

// Ticker.shared: singleton, autoStart=true, protected from destroy()
const shared = Ticker.shared;

// Ticker.system: separate instance used by engine background tasks,
// independent of the main scene ticker. It's a plain Ticker instance
// (autoStart=true, _protected=true) with no intrinsic priority; listeners
// are typically added at UTILITY priority by convention.
const system = Ticker.system;

// new Ticker(): custom instance, autoStart=false, you manage the lifecycle
const custom = new Ticker();
custom.autoStart = true; // start when first listener is added
custom.add((ticker) => {
  console.log(ticker.deltaMS);
});

// One-shot callback that auto-removes after firing
custom.addOnce(() => console.log("fires once"), null, UPDATE_PRIORITY.NORMAL);

// When done:
custom.stop();
custom.destroy();

Application creates its own Ticker by default. Set sharedTicker: true in app.init() to use Ticker.shared instead. Ticker.shared and Ticker.system are both _protected and will not actually be destroyed if you call destroy() on them. Read ticker.FPS for the measured frame rate and ticker.count for the current listener count.

App lifecycle and manual rendering

import { Application } from "pixi.js";

const app = new Application();
await app.init({ autoStart: false });

// Pause and resume the built-in render loop at any time.
app.start();
app.stop();

// Or drive the loop yourself (headless, visibility-gated, fixed timestep, etc.)
function animate() {
  app.ticker.update(); // fires registered callbacks
  app.render(); // renders the stage
  requestAnimationFrame(animate);
}
animate();

app.start() and app.stop() are added by the TickerPlugin and map to ticker.start() / ticker.stop(). Use autoStart: false plus your own frame driver when you need to pause on tab blur, run a fixed-timestep loop, or render offscreen.

Speed scaling

import { Application } from "pixi.js";

const app = new Application();
await app.init({ width: 800, height: 600 });

app.ticker.speed = 0.5; // Half speed (slow motion)
app.ticker.speed = 2.0; // Double speed

// speed affects deltaTime and deltaMS, but NOT elapsedMS

Common Mistakes

[CRITICAL] Ticker callback expects delta as first argument

Wrong:

app.ticker.add((dt) => {
  bunny.rotation += dt;
});

Correct:

app.ticker.add((ticker) => {
  bunny.rotation += ticker.deltaTime;
});

v8 passes the Ticker instance as the callback argument, not a delta number. The v7 pattern (dt) => ... compiles but dt is the entire Ticker object, so arithmetic on it produces NaN.

[HIGH] Using updateTransform for per-frame logic

Wrong:

class MySprite extends Sprite {
  updateTransform() {
    super.updateTransform();
    this.rotation += 0.01;
  }
}

Correct:

class MySprite extends Sprite {
  constructor() {
    super();
    this.onRender = this._onRender.bind(this);
  }
  private _onRender() {
    this.rotation += 0.01;
  }
}

updateTransform was removed in v8. Use the onRender callback for per-object per-frame logic.

[MEDIUM] Treating deltaTime as milliseconds

Wrong:

app.ticker.add((ticker) => {
  // Tries to move 100px/sec but deltaTime is ~1.0, not ~16.67
  sprite.x += (100 * ticker.deltaTime) / 1000;
});

Correct:

app.ticker.add((ticker) => {
  // Using deltaMS for time-based movement
  sprite.x += (100 / 1000) * ticker.deltaMS;
  // Or using deltaTime as a frame-rate multiplier
  sprite.x += 1.5 * ticker.deltaTime;
});

deltaTime is a dimensionless scalar (~1.0 at 60fps), not milliseconds. Use deltaMS for real time calculations. Use deltaTime as a simple multiplier when you want "per frame at 60fps" behavior.

API Reference

Related skills

How it compares

Pick pixijs-ticker over generic animation skills when PixiJS v8 Ticker APIs, UPDATE_PRIORITY, and deltaTime semantics must be exact.

FAQ

Is deltaTime in milliseconds?

No. deltaTime is dimensionless, about 1.0 at 60fps; use deltaMS for real-time math.

Where does rendering run in priority?

app.render registers at UPDATE_PRIORITY.LOW, below HIGH physics callbacks.

How cap frame rate?

Set app.ticker.maxFPS or adjust ticker.speed for slow-motion effects.

Is Pixijs Ticker safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.