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

@automatajs/core

v0.2.0

Published

A focused cellular automata engine for the browser

Readme

@automatajs/core

npm version license

A focused cellular automata engine for the browser. Inspired by p5.js. Minimal API, instant feedback, decoupled rules and style.

Zero dependencies. Works with any canvas-based environment.

Installation

npm install @automatajs/core

Or with your preferred package manager:

pnpm add @automatajs/core
yarn add @automatajs/core

Quick Start

import { Automata, gameOfLife } from "@automatajs/core";

const canvas = document.querySelector("canvas");
const ca = new Automata(canvas, {
  cols: 80,
  rows: 60,
  fps: 10,
  rule: gameOfLife,
});

ca.randomize(0.3);
ca.play();

Writing Rules

The rule function runs once per cell per generation and decides the next state. It receives a CellContext and returns 0 (dead) or any positive integer (alive).

import { Automata } from "@automatajs/core";

// Game of Life rule
function rule(ctx) {
  if (ctx.self === 1) {
    return ctx.neighborCount === 2 || ctx.neighborCount === 3 ? 1 : 0;
  }
  return ctx.neighborCount === 3 ? 1 : 0;
}

const ca = new Automata(canvas, { rule });

CellContext

Every rule (and style) function receives a CellContext object:

| Property | Type | Description | |----------|------|-------------| | self | number | Current cell state (0 = dead, 1+ = alive) | | neighborCount | number | Count of alive neighbors | | neighbors | number[] | Individual neighbor states (Moore: 8, Von Neumann: 4) | | x | number | Column coordinate | | y | number | Row coordinate | | get(x, y) | number | Read any cell on the grid | | cols | number | Grid width | | rows | number | Grid height |

createRule(birth, survive)

Create a custom birth/survival rule from standard notation.

import { createRule } from "@automatajs/core";

// B3/S23 — Game of Life
const gol = createRule([3], [2, 3]);

// B36/S23 — HighLife
const highLife = createRule([3, 6], [2, 3]);

Styling Cells

A StyleFunction controls the color of every individual cell. It can return:

  • [r, g, b, a] — RGBA tuple (0–255 each)
  • "#rrggbb" — CSS color string
  • true — use the default alive color
  • false — transparent / dead
const ca = new Automata(canvas, {
  rule: gameOfLife,
  style: (state, ctx) => {
    if (state === 0) return false;
    // Neighbor heatmap: cool → warm
    const t = ctx.neighborCount / 8;
    return [Math.floor(255 * t), 80, 255 - Math.floor(255 * t), 255];
  },
});

// Set dynamically
ca.setStyle((state) => (state === 0 ? false : "#f472b6"));

// Reset to default
ca.setStyle(null);

API Reference

Auto-generated from src/engine.ts.

Constructor

new Automata(canvas: HTMLCanvasElement, options?: AutomataOptions)

Creates a new Automata instance bound to a canvas element. The canvas auto-resizes to fill its parent container. Cell size is computed automatically from grid dimensions and available space.

See AutomataOptions for all configuration options.

Grid Management

getGrid(): Grid

Get the underlying grid.


createGrid(cols: number, rows: number): void

Create a new grid, replacing the current one.


clearGrid(): void

Clear the grid.


randomize(density: number = 0.3): void

Randomize the grid.


getCell(x: number, y: number): number

Get cell state.


setCell(x: number, y: number, state: number): void

Set cell state.


toggleCell(x: number, y: number): void

Toggle cell state.


stamp(pattern: number[][], offsetX?: number, offsetY?: number): void

Stamp a pattern onto the grid.

Simulation

setRule(rule: RuleFunction): void

Set the rule function.


setStyle(style: StyleFunction | null): void

Set the style function for per-cell coloring. Pass null to reset to default.


step(): void

Advance one generation.


play(): void

Start the simulation loop.


pause(): void

Pause the simulation.


reset(): void

Reset to initial state (from last randomize or manual setup).


saveState(): void

Save the current grid state as the initial state.


get playing(): boolean

Is the simulation running?


get generation(): number

Current generation count.


get fps(): number

Get the current FPS setting.


setFrameRate(fps: number): void

Set the target frames per second.


get population(): number

Population count.


get cols(): number

Grid dimensions.


onStep(fn: (gen: number) => void): void

Register a callback after each step.

Rendering

render(): void

Force a re-render.


resize(): void

Resize the canvas to fit its container.


setAliveColor(color: string): void

Set alive cell color.


setDeadColor(color: string): void

Set dead cell color.


setBackground(color: string): void

Set background color.


toggleGridLines(show?: boolean): void

Toggle grid lines on/off.


toDataURL(format?: "png" | "jpeg"): string

Export canvas as data URL.

Interaction

onCellClick(fn: CellCallback): void

Set custom cell click handler.


onCellDrag(fn: CellCallback): void

Set custom cell drag handler.


enableInteraction(): void

Enable mouse/touch interaction.


disableInteraction(): void

Disable mouse/touch interaction.

Lifecycle

destroy(): void

Clean up all resources.

Types

Auto-generated from src/types.ts.

GridOptions

| Property | Type | Default | Description | |----------|------|---------|-------------| | wrap? | boolean | true | Enable toroidal wrapping | | neighborhood? | NeighborhoodType | "moore" | Neighborhood type |

CellContext

Context object passed to each cell during a rule evaluation. Provides easy access to the cell's own state, its neighbors, and the ability to read any cell on the grid.

| Property | Type | Default | Description | |----------|------|---------|-------------| | self | number | — | Current state of this cell (0 = dead, 1+ = alive / multi-state) | | x | number | — | Column coordinate | | y | number | — | Row coordinate | | neighborCount | number | — | Number of alive neighbors (count of neighbors with state > 0) | | neighbors | number[] | — | Array of individual neighbor state values (Moore: 8, Von Neumann: 4) | | cols | number | — | Grid width | | rows | number | — | Grid height |

AutomataOptions *(extends GridOptions)*

| Property | Type | Default | Description | |----------|------|---------|-------------| | cols? | number | — | Number of columns | | rows? | number | — | Number of rows | | fps? | number | 10 | Frames per second | | aliveColor? | string | "#22d3ee" | Color for alive cells | | deadColor? | string | "#0f172a" | Color for dead cells | | backgroundColor? | string | "#020617" | Background color | | showGridLines? | boolean | true | Show grid lines | | gridLineColor? | string | "#1e293b" | Grid line color | | cellSize? | number | — | Cell size in pixels (auto-calculated if omitted) | | rule? | RuleFunction | — | Rule function — determines next state for each cell | | style? | StyleFunction | — | Style function — determines visual appearance per cell (optional) |

ExportOptions

| Property | Type | Default | Description | |----------|------|---------|-------------| | scale? | number | — | | | format? | "png" | "jpeg" | — | |

NeighborhoodType

type NeighborhoodType = "moore" | "vonneumann"

RGBA

RGBA color tuple: [red, green, blue, alpha], each 0–255.

type RGBA = [number, number, number, number]

StyleFunction

Style function signature. Determines the visual appearance of a cell based on its state and context. Return an RGBA color tuple, a CSS color string, or a boolean (true = alive color).

Parameters:

  • state — Current state of the cell
  • ctx — Cell context with position and grid access
type StyleFunction = (
  state: number,
  ctx: CellContext
) => RGBA | string | boolean

CellCallback

type CellCallback = (x: number, y: number, state: number) => void

Presets

Built-in rules ready to use. Import directly or via the presets registry.

Auto-generated from src/presets.ts.

import { gameOfLife, highLife, seeds, presets } from "@automatajs/core";

ca.setRule(gameOfLife);

// Access by name via registry
ca.setRule(presets["dayAndNight"]);

| Export | Description | |--------|-------------| | gameOfLife | Conway's Game of Life (B3/S23) - A dead cell with exactly 3 neighbors becomes alive. - A live cell with 2 or 3 neighbors survives. - All other cells die or stay dead. | | highLife | HighLife (B36/S23) Like Game of Life but also births at 6 neighbors. Famous for replicators. | | seeds | Seeds (B2/S) Dead cells with exactly 2 neighbors come alive; all live cells die. Creates explosive growth patterns. | | dayAndNight | Day & Night (B3678/S34678) Symmetric rule — patterns behave the same inverted. | | diamoeba | Diamoeba (B35678/S5678) Creates large diamond-shaped regions. |

Patterns

Famous patterns as 2D arrays for stamping onto the grid.

Auto-generated from src/presets.ts.

import { Automata, gameOfLife, patterns } from "@automatajs/core";

const ca = new Automata(canvas, { cols: 80, rows: 60, rule: gameOfLife });

ca.stamp(patterns.glider, 10, 10);
ca.stamp(patterns.gosperGliderGun, 2, 2);
ca.play();

| Pattern | Size | Description | |---------|------|-------------|

License

MIT