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

polymatic

v0.0.11

Published

Minimalist framework for building games and interactive visual application

Downloads

74

Readme

Minimalist middleware framework for making games and interactive visual application

Examples

Ocean - Polymatic, Stage.js
Watermelon Game - Polymatic, Planck/Box2D, SVG
8-Ball Pool - Multiplayer including server and client implementation with Socket.io, Planck/Box2D, SVG
Air Traffic Control - Polymatic, Stage.js

Community

Discord

GitHub

Install

NPM

  npm install polymatic

CDN - UNPKG

  <script src="//unpkg.com/[email protected]"></script>

CDN - jsDelivr

  <script src="//cdn.jsdelivr.net/npm/[email protected]"></script>

User Guide - 5 Minutes

Polymatic is a minimalist middleware framework. It does not have game loop, rendering, physics, or any other game specific functions. Instead, it provides a simple way to implement your game functions, and integrate other libraries. Polymatic is designed to use other libraries for rendering, sound, physics, storage, networking, etc.

Polymatic is inspired by ECS (entity-component-system) architecture: middlewares can be used to implement systems, and data-drivers can be used to decouple data (entity) from behavior (component). However unlike mainstream ECS frameworks, Polymatic does not manage your data, and doesn't have queries.

Polymatic is distributed as a simple JavaScript library, and is compatible with frontend and backend development tools and environments.

Middleware

Middlewares are the building blocks of a polymatic application. You can simplify a complex applications by breaking it down to small middlewares. Middlewares share data in the context, can send and receive events, and use other middlewares.

To create a middleware simply extend the Middleware class:

class Main extends Middleware {
}

Context

Context is an object which can be accessed by all middlewares in an application. It can be used be to store game entities and state. You can use any object as context.

Events

Middlewares can communicate by sending and receiving events. To send an event we use the emit method, and to receive an event we use the on method.

this.emit("event-name", data);

this.on("event-name", (data) => {
});

Activation

To start a polymatic application we need to activate the entry middleware. To activate a middleware we pass an instance of your application entry middleware and context object to Runtime.activate():

  Runtime.activate(new Main(), new MainContext());

A middleware can communicate with other middlewares and access context object if it is activated. All middlewares that are used by an activated middleware are also activated.

When a middleware is activated it will receive "activate" event, and when it is deactivated it will receive "deactivate" event. You could use them to initialize and cleanup resources.

Use

To use a middleware in another middleware we use the use method:

class Main extends Middleware {
  constructor() {
    super();
    this.use(new FrameLoop());
  }
}

Working with data

Middlewares share game entities and state in the context. A middleware might have internal representation of game entities to implement new behavior for an entity. For example, in a user-interface middleware we create visual elements such as sprite, or svg element, or in a physics middleware we create and add new bodies to the physics simulation for each game entity. Binder and drivers are used by middlewares to map shared entities to middleware components.

Drivers are used to implement new behavior for entities. A driver is responsible for creating, updating and removing components for entities that it handles. A binder is used to track entities and call driver functions when entities are added, updated or removed.

Driver

To create a Driver we need to implement filter, enter, update and exit functions. When we pass new data to a binder, these functions are called on all drivers that are added to the binder:

  • filter: select entities that a driver should handle
  • enter: called when new entity is added to the data
  • update: called for existing entities and new entities
  • exit: called when an entity is removed from the data

We can create a driver by extending the Driver class, or using the Driver.create method:

const fruitRenderDriver = Driver.create<Fruit, Element>({
  filter: (entity) => data.type == "fruit",
  enter: (entity) => {
    // create new svg element, or add physics body
    return component;
  },
  update: (entity, component) => {
    // in the ui middleware update the svg element
    // in the physics middleware copy body position to data entity
  },
  exit: (entity, component) => {
    // remove the svg element or physics body
  },
});

Binder

Binder needs to uniquely identify entities between updates, so it requires a key function. We can create a binder by extending the Binder class, or using the Binder.create method:

// create binder with key function and drivers
const renderBinder = Binder.create({
  key: (entity) => entity.key,
  drivers: [fruitRenderDriver],
});

Now we can pass data to binder, and it will call driver functions:

// in rendering loop
// pass entities to binder
// this will call driver functions
renderBinder.data(entities);

License

Polymatic is licensed under the MIT License. You can use it for free in your projects, both open-source and commercial. License file is in the root directory of the project source code.