npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jolly-pixel/engine

v2.5.0

Published

Minimal and opiniated ECS framework on top of three.js.

Readme

📌 About

Minimal and opinionated ECS built on top of Three.js inspired by Superpowers and Craftstudio.

[!WARNING] The engine is still in a heavy phase of development (expect frequent API breaking changes).

💡 Features

  • ECS architecture with Actors, Components, and Scenes
  • Godot-like Signals
  • Behavior scripts
  • Input controls (mouse, keyboard, gamepads, touchpad)
  • Built-in renderers (3D models, 3D text, sprites, …)
  • Asset management
  • Audio (background music, sound library, spatial audio)
  • UI toolkits for minimal in-game interfaces

💃 Getting Started

This package is available in the Node Package Repository and can be easily installed with npm or yarn.

$ npm i @jolly-pixel/engine
# or
$ yarn add @jolly-pixel/engine

🔎 Guides (WIP 🚧)

📚 API

⚙️ Systems

[!TIP] @jolly-pixel/runtime manage most of that for you

Systems are responsible for driving the game loop, orchestrating rendering, and managing shared resources such as assets. They operate on actors and their components each frame.

  • World — top-level orchestrator that ties the renderer, scene, input, and audio into a unified game loop.
    • Renderer — abstracts the Three.js render pipeline and supports direct and post-processing render strategies.
    • SceneManager — the ECS world manager that owns the actor tree and drives per-frame lifecycle (awake → start → update → destroy).
  • Asset — lazy-loading asset pipeline with a registry of loaders, a queue, and a cache.
import { Systems, Actor } from "@jolly-pixel/engine";

const sceneManager = new Systems.SceneManager();
const renderer = new Systems.ThreeRenderer(canvas, {
  sceneManager,
  renderMode: "direct"
});
const game = new Systems.World(renderer, {
  enableOnExit: true,
  sceneManager
});

game.connect();

🎭 Actor

An Actor is a named node in the scene tree that holds a Transform, a list of Components, and a dictionary of Behaviors. The engine uses the name Actor (inspired by Superpowers) instead of the traditional Entity term.

  • Actor — the entity itself, holding its transform, components, and behaviors.
    • Transform — built-in component wrapping a Three.js Object3D and exposing a complete local/global transform API (position, orientation, scale, movement).
    • ActorTree — tree structure that manages parent-child actor relationships and provides pattern-based lookups.
const player = world.createActor("Player");
player.transform.setLocalPosition({ x: 0, y: 1, z: 0 });

const child = world.createActor("Weapon", {
  parent: player
});

player.destroy();

🧩 Components

Components are pure data and logic units attached to an Actor. They come in three flavours:

  • ActorComponent — the base class all components extend (behaviors and renderers are ActorComponent).
    • Signals — lightweight pub/sub event emitter for actor-level communication (Godot-inspired signals).
  • Renderers — visual components (sprites, models, text, tiled maps) that know how to draw themselves.
  • Behavior — script components with a property system and decorator-driven initialization.
import { Behavior, Actor, SignalEvent } from "@jolly-pixel/engine";

export interface PlayerBehaviorOptions {
  speed?: number;
}

class PlayerBehavior extends Behavior {
  onMovement = new SignalEvent();
  speed = 0.1;

  constructor(
    actor: Actor, options: PlayerBehaviorOptions = {}
  ) {
    super(actor);
    this.speed = options?.speed ?? 0.1;
  }

  update() {
    if (this.actor.world.input.isKeyDown("ArrowUp")) {
      this.onMovement.emit();
      this.actor.transform.moveForward(this.speed);
    }
  }
}

new Actor(world, { name: "player" })
  .addComponent(ModelRenderer, { path: "models/Player.glb" })
  .addComponent(PlayerBehavior, { speed: 0.5 });

🎮 Device Controls

Aggregates all physical devices (mouse, keyboard, gamepads, touchpad, screen) behind a unified query API so that behaviors can react to player actions without coupling to a specific device.

import { InputCombination } from "@jolly-pixel/engine";

const { input } = world;

if (input.isKeyDown("Space")) {
  console.log("jump!");
}

const dashCombo = InputCombination.all(
  InputCombination.key("ShiftLeft"),
  InputCombination.key("ArrowRight")
);
if (dashCombo.evaluate(input)) {
  console.log("dash!");
}

[!TIP] In ActorComponent or Behavior input are accessible through this.actor.world.input

🔊 Audio

Manages sound playback across the engine. It provides a global volume controller, a factory for creating audio sources, and a playlist-based background music manager.

  • Audio — global audio controller owning the AudioContext and master volume.
    • AudioLibrary
    • AudioBackground — playlist-based background music with sequential track playback, pause/resume/stop, and playlist chaining.
import { GlobalAudioManager, AudioBackground } from "@jolly-pixel/engine";

const audioManager = GlobalAudioManager.fromWorld(world);
const bg = new AudioBackground({
  audioManager,
  autoPlay: true,
  playlists: [{
    name: "main",
    onEnd: "loop",
    tracks: [
      { name: "theme", path: "audio/theme.mp3" }
    ]
  }]
});

world.audio.observe(bg);
world.audio.volume = 0.5;

🖼️ UI

An orthographic 2D overlay drawn on top of the 3D scene. UI elements are anchored to screen edges and support pointer interaction through signals.

  • UIRenderer — orthographic camera and CSS2D overlay that drives the UI layer.
    • UINode — base positioning component with anchor, offset, and pivot.
    • UISprite — interactive sprite with style, hover states, text labels, and pointer signals.

Contributors guide

If you are a developer looking to contribute to the project, you must first read the CONTRIBUTING guide.

Once you have finished your development, check that the tests (and linter) are still good by running the following script:

$ npm run test
$ npm run lint

[!CAUTION] In case you introduce a new feature or fix a bug, make sure to include tests for it as well.

📦 Internals

License

MIT