pixi-console captures console.log, warnings and uncaught errors and draws them on top
of your scene. It's built for debugging on phones, tablets and TVs where you can't open devtools.
npm install pixi-console
Tap the > prompt (or press ` to open the console) and type
help.
Captures everything
It captures log, info, debug, warn and
error, plus uncaught errors, unhandled promise rejections and
console.clear(). Harmless ResizeObserver loop notices are left out.
Your devtools keep working as usual.
Reads like devtools
It supports printf-style %s %d %o substitutions. Objects, Maps, Sets, typed arrays
and sparse arrays print like in devtools, circular references included. Errors show their stack,
cause chain and extra properties like code. Repeated messages collapse
into one line.
Virtualized & fast
Only the visible lines exist as display objects, drawn with BitmapText from a
single glyph atlas. Layout happens at most once per frame, and the console is its own render
group, so a flood of logs doesn't make PixiJS rebuild your stage. Hidden, it skips layout
entirely.
Touch friendly
Scroll with the wheel or by dragging. Taps and the wheel over the log don't reach objects under
it, and the wheel scrolls the log instead of the page. The toolbar filters by level, clears and
closes, with compact labels on narrow screens. It opens itself when an error happens.
Fits any screen
autoResize follows your renderer across window resizes and orientation changes. Put
the console anywhere with a layout function. Filters, timestamps, maxEntries, the
toolbar and the prompt can change at any time.
Tiny & typed
Zero runtime dependencies besides pixi.js. Ships ESM, CommonJS and a
<script> build with full TypeScript types.
Command line
Turn on prompt to run commands on the device itself. help and
clear are built in, addCommand() adds your own, and
createJsEvaluator() runs JavaScript in development builds. ↑↓ recall earlier lines, Tab completes command names, and
execute() runs a line from your code. It's a real text field over the canvas, so
phone keyboards, IME and paste just work.
import { createJsEvaluator, PixiConsole } from"pixi-console";
const devConsole = newPixiConsole({
prompt: true,
autoResize: { renderer: app.renderer },
commands: {
spawn: {
usage: "<count>",
description: "Spawn enemies",
run: ([count = "1"]) => game.spawn(Number(count)),
},
},
// JavaScript too, in development builds only
evaluator: import.meta.env.DEV
? createJsEvaluator({ scope: { app } })
: null,
});
app.stage.addChild(devConsole);
devConsole.addCommand("fps", () => app.ticker.FPS.toFixed(1));
await devConsole.execute("spawn 3"); // run a line from code
Change it at runtime
devConsole.filter = ["warn", "error"];
devConsole.timestamps = true;
devConsole.maxEntries = 100; // drops the oldest entries now
devConsole.toolbar = false;
devConsole.prompt = true;
devConsole.history = savedLines; // for ↑ and ↓// In a tap handler, so phones open the keyboard
button.addEventListener("click", () => devConsole.focusPrompt());