Skip to content
PixiJS Getting Started — Complete Beginner's Guide to 2D WebGL

PixiJS Getting Started — Complete Beginner's Guide to 2D WebGL

DodaTech Updated Jun 6, 2026 10 min read

PixiJS is a fast 2D WebGL renderer that creates rich interactive graphics using hardware acceleration. In this guide you’ll build your first scene from scratch.

What You’ll Learn

  • What PixiJS is and why it beats plain Canvas for 2D graphics
  • How to install PixiJS via npm or CDN
  • How the Application, renderer, and stage work together
  • How to create sprites from textures and position them
  • How to build a responsive interactive scene builder

Why PixiJS Matters

Modern web applications need smooth, hardware-accelerated 2D graphics. PixiJS is the most popular WebGL 2D framework, used by thousands of games, data dashboards, and security visualization tools.

At DodaTech, we use PixiJS in Durga Antivirus Pro to render real-time threat maps, live network traffic flows, and animated security dashboards. When a threat is detected, the UI animates a heatmap overlay using PixiJS sprites — all at 60fps. This is the kind of performance you can only get with GPU-accelerated rendering.

Prerequisites: Basic JavaScript knowledge (variables, functions, DOM). No WebGL or graphics experience needed — we explain every concept from the ground up.

Learning Path

    flowchart LR
    GS["Getting Started ⬅ You Are Here"] --> GT["Graphics & Textures"]
    GT --> AI["Animation & Interactivity"]
    AI --> TF["Text & Bitmap Fonts"]
    TF --> PB["Performance & Best Practices"]
    style GS fill:#4a90d9,stroke:#fff,color:#fff
    linkStyle default stroke:#4a90d9,stroke-width:2
  

PixiJS vs Canvas API vs Raw WebGL

FeaturePixiJSCanvas 2D APIRaw WebGL
Ease of useEasy — scene graph APIModerate — imperative drawingHard — shaders & buffers
GPU accelerationYes (WebGL)Software rasterizationYes
Draw callsAutomatic batchingManualManual
Filters & effectsBuilt-inNone nativelyYou write shaders
Best forGames, dashboards, toolsSimple 2D drawings3D or custom rendering

When to use PixiJS: You need smooth 60fps rendering with hundreds of sprites, interactive elements, and visual effects — without writing shader code.

How PixiJS Works — The Big Picture

Think of PixiJS like a movie projector and your code like the film reel:

  • The renderer is the projector — it takes your scene and draws it on screen
  • The stage is the screen where everything appears
  • Sprites are paper cutouts you place on the screen
  • Textures are the stickers you stick onto those cutouts

Every frame, the projector (renderer) scans the screen (stage), checks where all the cutouts (sprites) are, and draws them. The magic is that the projector uses the GPU to do this extremely fast.

Setting Up PixiJS

Via npm (for build tools)

npm install pixi.js

Then in your JavaScript file:

import * as PIXI from 'pixi.js';

Via CDN (for HTML pages)

<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.x/dist/pixi.min.js"></script>

After this, the global PIXI object is available. No build step needed — perfect for prototyping and tutorials.

The Application — Your Starting Point

The Application class is like a starter kit that creates three things at once:

  1. A renderer (the projector) — connected to a <canvas> element
  2. A stage (the screen) — a root container for all objects
  3. A ticker (the clock) — runs your animation code every frame
const app = new PIXI.Application({
  width: 800,
  height: 600,
  backgroundColor: 0x1099bb,
  resolution: window.devicePixelRatio || 1,
  autoDensity: true,
});

document.body.appendChild(app.view); // app.view is the <canvas>

Let’s break this down:

OptionWhat it doesWhy it matters
width / heightCanvas size in CSS pixelsDefines your drawing area
backgroundColorHex color of the background0x1099bb is a nice blue
resolutionPixel density multiplierdevicePixelRatio makes text sharp on Retina displays
autoDensityAdjust CSS size automaticallyPrevents blurry rendering on HiDPI screens

Why set resolution? Without it, your crisp vector graphics look blurry on Retina Macs and high-end phones. The devicePixelRatio tells PixiJS to render at 2x or 3x the CSS size, then shrink it back — giving you razor-sharp visuals.

Renderer Types — What Runs Under the Hood

PixiJS tries WebGL2 first, then WebGL1, then falls back to Canvas 2D. You don’t need to pick — it just works.

// Force Canvas mode if needed
const app = new PIXI.Application({ forceCanvas: true });

// Check at runtime
console.log(app.renderer.type); // 1 = WebGL, 2 = Canvas

Why does the renderer type matter? WebGL runs on the GPU, which is optimized for parallel drawing operations. Canvas 2D runs on the CPU, which is slower. For a threat visualization dashboard in Durga Antivirus Pro, WebGL means we can animate hundreds of threat nodes simultaneously without dropping frames.

The Stage — Your Root Container

The stage is a Container that acts as the root of your scene graph. Think of it like the root folder on your computer — everything you create lives inside it.

const container = new PIXI.Container();
app.stage.addChild(container);

Scene graph means: when you move a parent container, all its children move with it. This is like picking up a tray of drinks — all the cups move together.

Sprites & Textures — Paper Cutouts with Stickers

A sprite is a display object that shows an image. A texture is the image data that the sprite displays.

The analogy: a texture is a sticker, and a sprite is the paper cutout you put the sticker on. You can move the cutout around, rotate it, or scale it — the sticker moves with it.

Loading a texture from a URL

const texture = PIXI.Texture.from('https://pixijs.com/assets/bunny.png');
const bunny = new PIXI.Sprite(texture);
app.stage.addChild(bunny);

Three steps:

  1. Texture.from() — load the image and wrap it as a texture (the sticker)
  2. new PIXI.Sprite(texture) — create a sprite (the cutout) with that sticker
  3. app.stage.addChild(bunny) — place the cutout on the screen

Loading from a local file (Webpack / Vite)

import bunnyImg from './assets/bunny.png';
const texture = PIXI.Texture.from(bunnyImg);

Positioning, Rotation & Scale

Once you have a sprite, you can control its position, rotation, and scale like this:

const sprite = new PIXI.Sprite(texture);

sprite.x = 100;           // move 100px right
sprite.y = 200;           // move 200px down
sprite.rotation = Math.PI / 4;  // rotate 45 degrees
sprite.scale.set(2);      // make it 2x bigger
sprite.anchor.set(0.5);   // center the rotation point

The anchor is important. By default, anchor is at (0,0) — the top-left corner. This means rotation and scale happen around the top-left corner, which looks weird. Setting anchor.set(0.5) centers the pivot point, so rotation spins the sprite around its middle — like a spinning coin.

Responsive Auto-Resize

Make your canvas adapt to window size changes:

window.addEventListener('resize', () => {
  app.renderer.resize(window.innerWidth, window.innerHeight);
});

For a fixed aspect ratio (e.g., 16:9):

const resize = () => {
  const ratio = 16 / 9;
  let w = window.innerWidth;
  let h = window.innerHeight;
  if (w / h > ratio) w = h * ratio;
  else h = w / ratio;
  app.renderer.resize(w, h);
};
window.addEventListener('resize', resize);
resize();

Common Mistakes

MistakeWhy it happensHow to fix it
Sprites appear blurryMissing autoDensity and resolutionAlways set resolution: window.devicePixelRatio and autoDensity: true
Rotation looks wrongAnchor is at (0,0) instead of centerCall sprite.anchor.set(0.5) before rotating
Image not showingTexture URL is wrong or CORS blockedCheck the console for 404 errors; use same-origin or CORS-enabled URLs
Width/height is 0You checked dimensions before first renderMake sure the sprite is added to stage and a frame has passed
Canvas is tiny or hugeForgot to call document.body.appendChild(app.view)Always append the canvas to the DOM
Code runs before texture loadsTexture.from() is async for remote URLsUse app.loader or ensure the image is cached

Practice Questions

  1. What does anchor.set(0.5) do and why is it useful?

    • It sets the pivot point to the center of the sprite. Without it, rotation and scale happen around the top-left corner.
  2. What is the difference between WebGL and Canvas mode in PixiJS?

    • WebGL uses the GPU for hardware-accelerated rendering. Canvas mode renders on the CPU and is significantly slower.
  3. Why does app.renderer.resize() matter for responsive design?

    • Without resize, the canvas stays at its initial size when the browser window changes, causing clipping or empty space.
  4. What three things does the Application constructor create?

    • A renderer (projector), a stage (screen), and a ticker (clock).
  5. How do you share the same image across multiple sprites efficiently?

    • Create one Texture and pass it to multiple Sprite instances. PixiJS batches them into a single draw call.

Challenge: Build a scene with 5 sprites positioned around a circle. Each sprite should face the center. Hint: use Math.sin and Math.cos with anchor.set(0.5).

FAQ

Why does my sprite appear at the wrong position?
: Check the anchor. Default is (0,0), meaning the top-left corner. Use anchor.set(0.5) for centered positioning.
Should I use forceCanvas?
: Only as a last resort. WebGL is much faster. Canvas mode is useful for testing or environments without WebGL.
How do I preload multiple assets?
: Use app.loader.add(...).load(() => { /* start */ }). The loader handles queues and progress tracking.
What is the difference between sprite.x and sprite.position.x?
: They are identical. sprite.x is a shortcut for sprite.position.x.
Can I change the canvas size after creation?
: Yes. Call app.renderer.resize(newWidth, newHeight) at any time.

Try It Yourself

Open the HTML below in your browser to run a fully interactive PixiJS scene builder. No build tools needed — just save and open.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>PixiJS Getting Started — Scene Builder</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background: #1a1a2e; font-family: system-ui, sans-serif; display: flex; justify-content: center; padding: 20px; }
    .app { display: flex; gap: 20px; flex-wrap: wrap; }
    canvas { border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.4); }
    .panel { background: #16213e; border-radius: 12px; padding: 20px; color: #fff; width: 240px; display: flex; flex-direction: column; gap: 14px; }
    .panel h2 { font-size: 18px; margin-bottom: 4px; }
    .panel label { font-size: 13px; color: #a8b2d1; }
    .panel input[type="range"] { width: 100%; accent-color: #4a90d9; }
    .panel input[type="color"] { width: 100%; height: 40px; border: none; border-radius: 6px; cursor: pointer; }
    .btn { padding: 10px; border: none; border-radius: 8px; background: #4a90d9; color: #fff; font-weight: 600; cursor: pointer; }
    .btn:hover { background: #357abd; }
    .btn.danger { background: #e63946; }
    .stats { font-size: 12px; color: #8892b0; }
  </style>
</head>
<body>
<div class="app">
  <div id="canvas-container"></div>
  <div class="panel">
    <h2>Scene Builder</h2>
    <label>Rotation <span id="rotVal">0</span>°</label>
    <input type="range" id="rotation" min="0" max="360" value="0" />
    <label>Background Color</label>
    <input type="color" id="bgColor" value="#1099bb" />
    <label>Opacity</label>
    <input type="range" id="opacity" min="0" max="1" step="0.05" value="1" />
    <button class="btn" id="addBtn">+ Add Sprite</button>
    <button class="btn danger" id="clearBtn">Clear All</button>
    <div class="stats">Sprites: <span id="spriteCount">0</span></div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.x/dist/pixi.min.js"></script>
<script>
const ASSETS = [
  'https://pixijs.com/assets/bunny.png',
  'https://pixijs.com/assets/eggHead.png',
  'https://pixijs.com/assets/flowerTop.png',
  'https://pixijs.com/assets/goblin.png',
  'https://pixijs.com/assets/helix.png',
];

const app = new PIXI.Application({
  width: 800, height: 600,
  backgroundColor: 0x1099bb,
  antialias: true,
  resolution: window.devicePixelRatio || 1,
  autoDensity: true,
});

document.getElementById('canvas-container').appendChild(app.view);

let sprites = [];
let selectedIndex = 0;

function addSprite() {
  const url = ASSETS[selectedIndex % ASSETS.length];
  const sprite = new PIXI.Sprite(PIXI.Texture.from(url));
  sprite.anchor.set(0.5);
  sprite.x = Math.random() * 700 + 50;
  sprite.y = Math.random() * 500 + 50;
  sprite.scale.set(Math.random() * 1.5 + 0.5);
  sprite.rotation = Math.random() * Math.PI * 2;
  app.stage.addChild(sprite);
  sprites.push(sprite);
  document.getElementById('spriteCount').textContent = sprites.length;
  selectedIndex++;
}

document.getElementById('rotation').addEventListener('input', e => {
  const deg = parseFloat(e.target.value);
  document.getElementById('rotVal').textContent = deg;
  sprites.forEach(s => { s.rotation = (deg * Math.PI) / 180; });
});

document.getElementById('bgColor').addEventListener('input', e => {
  app.renderer.backgroundColor = parseInt(e.target.value.slice(1), 16);
});

document.getElementById('opacity').addEventListener('input', e => {
  sprites.forEach(s => { s.alpha = parseFloat(e.target.value); });
});

document.getElementById('addBtn').addEventListener('click', addSprite);
document.getElementById('clearBtn').addEventListener('click', () => {
  sprites.forEach(s => app.stage.removeChild(s));
  sprites = [];
  document.getElementById('spriteCount').textContent = 0;
});

addSprite(); addSprite(); addSprite();

window.addEventListener('resize', () => {
  const w = Math.min(window.innerWidth - 280, 800);
  const h = Math.min(window.innerHeight - 40, 600);
  app.renderer.resize(Math.max(w, 200), Math.max(h, 200));
});
</script>
</body>
</html>

What’s Next

TopicLink
Drawing shapes and managing textureshttps://tutorials.dodatech.com/frontend/libraries/pixijs/pixijs-graphics-textures/
Animation and interactivityhttps://tutorials.dodatech.com/frontend/libraries/pixijs/pixijs-animation-interactivity/
WebGL rendering fundamentalsWebGL Guide
Canvas 2D API basicsCanvas API Tutorial

Related Tutorials


Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. PixiJS powers real-time threat visualization in Durga Antivirus Pro’s security dashboard.

What’s Next

Congratulations on completing this Pixijs Getting Started tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro