@bhaumiktalwar/crunch
v0.1.2
Published
A simple ECS library for rapid dev
Readme
Crunch
Crunch is a minimal, bitset-based Entity-Component-System (ECS) library written in JavaScript.
It’s designed for small to medium projects, quick prototypes, or learning purposes not for large-scale or performance-critical production systems.
Crunch focuses on simplicity and flexibility, making it easy to plug into rendering pipelines such as Three.js, Canvas, or any other system.
Features
- Lightweight, minimal API surface
- Bitset-based ECS architecture (up to 32 component types)
- Simple entity lifecycle management
- Efficient component views for iteration
- No external dependencies
Installation
npm install @bhaumiktalwar/crunchArchitecture
- Crunch uses a bitset-based ECS architecture, assigning each component type a unique bit within a 32-bit mask.
- Entities are represented by their active component bitsets, allowing fast filtering and view creation.
- This approach provides a compact, efficient representation for small-scale ECS systems while maintaining straightforward, readable code.
Usage
Defining Components
Components are factory functions that return plain objects or Can be Class Constructors
import { Registry } from '@bhaumiktalwar/crunch';
function Position(x = 0, y = 0) {
return { x, y };
}
function Velocity(dx = 0, dy = 0) {
return { dx, dy };
}
class Renderable {
constructor(color = "#fff") {
this.color = color;
}
}Creating and Managing Entities
const registry = new Registry();
// Create entity with components
const player = registry.create([
[Position, [100, 100]],
[Velocity, [0, 0]],
[Renderable, ['#00ff00']]
]);
// Add component to existing entity
registry.addComp(player, Health, [100]);
// Check if entity has component
if (registry.hasComp(player, Position)) {
// Get component data
const pos = registry.getComp(player, Position);
pos.x += 10;
}
// Remove component
registry.removeComp(player, Velocity);
// Delete entity
registry.delEntity(player);Querying Entities with Views
Views allow efficient iteration over entities with specific component combinations:
// Create a view for entities with Position and Velocity
const movementView = registry.createView([Position, Velocity]);
// Update all moving entities
movementView.forEach((entityId, pos, vel) => {
pos.x += vel.dx;
pos.y += vel.dy;
});Integration Example
// Game loop with Canvas 2D
const registry = new Registry();
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
// Create some entities
for (let i = 0; i < 10; i++) {
registry.create([
[Position, [Math.random() * canvas.width, Math.random() * canvas.height]],
[Velocity, [Math.random() * 2 - 1, Math.random() * 2 - 1]],
[Renderable, ['#ff0000']]
]);
}
// Systems
const movementView = registry.createView([Position, Velocity]);
const renderView = registry.createView([Position, Renderable]);
function update(dt) {
movementView.forEach((id, pos, vel) => {
pos.x += vel.dx * dt;
pos.y += vel.dy * dt;
});
}
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
renderView.forEach((id, pos, renderable) => {
ctx.fillStyle = renderable.color;
ctx.fillRect(pos.x, pos.y, 10, 10);
});
}
function gameLoop() {
update(16);
render();
requestAnimationFrame(gameLoop);
}
gameLoop();API Reference
Registry
create(components)- Create entity with initial components. Returns entity ID.addComp(entityId, component, args)- Add component to entityremoveComp(entityId, component)- Remove component from entitydelEntity(entityId)- Delete entity and all its componentshasComp(entityId, component)- Check if entity has componentgetComp(entityId, component)- Get component data for entitygetComponents(entityId)- Get all components for entity as arraygetComponentsGen(entityId)- Get all components for entity as generatorcreateView(components)- Create view for querying entities with specific components
View
forEach(callback)- Iterate over matching entities. Callback receives(entityId, ...componentData)get(component, entityId)- Get specific component data for entity in view
Limitations
- Maximum 32 component types per registry
- Entity IDs are reused when entities are deleted
- No built-in system scheduling or dependency management
- Intended for small to medium games, prototypes, or educational use.
- Does not include rendering, physics, or scene management — it’s purely ECS.
License
MIT
