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

@muini/easy-ecs

v0.2.0

Published

Easy Entity Component System is a minimalist open-source Javascript library that helps you create games quickly

Downloads

21

Readme

Easy Entity Component System is a minimalist open-source Javascript library that helps you create games quickly. It's focused on developer happyness and performance. It has zero dependancies, is super lightweight and extensible.

Introduction

Prerequisites

Just get a simple javascript project with npm support. You can also use the build version and use it without any stack.

⚠️ Note: Very early developement, expect breaking changes.

Glossary

  • World: One class instance to rule them all.
  • Entity: It's a instantiable class that is composed of Components.
  • Component: The «data» of your entity. Never instantiated, only declarative.
  • System: Where the logic happens. A system process Entities that have a specific set of Components.
  • Addon: This is a way to extend the World.

Getting Started

Installing

Install package from npm in your project or get the build/easy-ecs.js file.

npm i @muini/easy-ecs

Usage

Creating the structure of your game is a declarative process

Component

import { Component } from '@muini/easy-ecs';
// Component
export class Position extends Component{
  static name = "Position";
  static x = 0;
  static y = 0;
}
// Component inheritence
export class Position3D extends Position{
  static name = "Position3D";
  static z = 0;
}
// Another component
export class Health extends Component{
  static name = "Health";
  static health = 0;
  static maxHealth = 0;
}

Entity

import { Entity } from '@muini/easy-ecs';
// Entity is just a list of Component classes
export class Character extends Entity {
  static components = [Position]
}
// Entity inheritence, you need to spread the parent components array
export class Hero extends Character {
  static components = [...super.components, Health]
}

System

import { System } from '@muini/easy-ecs';
// System declaration
export class CharacterMovement extends System {
  // Component list that will filter entities that have those components
  dependencies = [Position]; 
  // onUpdate Will fire every world.update (or every frame if Loop Addon is added)
  onUpdate = (entities) => { 
    // entities is filtered entities
    entities.forEach(entity => {
      entity.x += 0.1 * Time.delta; //Time is an Addon, see below
      // You can access world with this.world
      // You can query entities with 
      // - this.world.getEntitiesWithComponents([...ComponentsClass])
      // - this.world.getEntitiesOfType(Class)
      // - this.world.getEntityById(id)
    })
  };
}
// Make your own system
export class MySystem extends System {
  dependencies = [MyComponent, ...]; 
  onInit = (entities) => {};
  onUpdate = (entities) => {};
}

World & Game start example


import { World } from '@muini/easy-ecs';
import { Loop, Time, Input, Renderer, SaveSystem } from '@muini/easy-ecs/addons';

import { Character } from './your-game/entities';
import { PlayerMovement, CharacterMovement, CharacterRenderer } from './your-game/systems';

//Instantiate your world
const world = new World({
  // Add as much addon as you can to extend the world and engine
  addons: [Loop, Time, Input, Renderer, SaveSystem, ...],
  // Order of systems is the order of execution
  systems: [PlayerMovement, CharacterMovement, CharacterRenderer, ...]
});
// Instantiate an entity, first arg is a World, second is default values
const bob = new Character(world, {
  x: 10,
  y: 10,
  health: 100,
  maxHealth: 100
})

// Start the world, that's all !
world.start()

Addon

Addon is an easy way to extend the world engine. Addon will never be instantiated and all properties must be static.

Official Addons

  • 🔁 Loop: Will set a loop calling world.update(timestamp) based on requestAnimationFrame
  • ⏱️ Time: Access Time.time, Time.delta and Time.elapsed easily anywhere
  • 🕹️ Input: Access to current input, either Input.mouse position or Input.isPressed(key) to check if a specific key is pressed, or Input.keypress to get all keys pressed
  • 🖼️ Renderer: Canvas Renderer with basic access to Renderer.canvas and context Renderer.ctx
  • 💾 SaveSystem: Save & restore world state from localStorage using const id = SaveSystem.saveWorld(world, saveName) and SaveSystem.restoreWorld(world, saveName)

Custom Addon

// Example of a new addon
export class MyAddon extends Addon {
  static onInit = (world) => { /*Do stuff*/ }
  static onBeforeUpdate = (world, time) => { /*Do stuff*/ }
  static onAfterUpdate = (world, time) => { /*Do stuff*/ }
}
// Example of Time Addon
export class Time extends Addon {
  static time = 0;
  static delta = 0;
  static elapsed = 0;
  static onBeforeUpdate = (world, time) => {
    Time.delta = time - Time.time;
    Time.time = time;
    Time.elapsed += Time.delta;
  }
}

Roadmap

  • [x] Core
  • [x] Addons: Loop, Time, Input, Renderer(canvas), SaveSystem
  • [x] Readme
  • [x] Example
  • [ ] Addon: Audio
  • [ ] Documentation
  • [ ] Addon: AssetManager
  • [ ] Addon: Network

Other Addon ideas = UI (html based?), WebGL Renderer, ...

Inspired by

  • Unity - ECS approach from Unity game engine
  • ECSY - ECS approach from Mozilla team
  • MattDesl - ECS approach from MattDesl

Contributing

Feel free to open issues for questions, bugs or improvements & PR !

Authors

  • Corentin Flach - Initial work - Github

License

This project is licensed under the MIT License