completengine Documentation #
Last updated: March 27, 2026
completengine is a concurrent event simulation engine designed for completeness. Every edge case is handled, every lifecycle hook is exposed, and every configuration option is documented. Whether you are building real-time simulations, event-driven architectures, or complex state machines, completengine provides the tools to get it done right.
This documentation covers installation, configuration, the full API surface, plugin development, and advanced topics including performance tuning, error handling, and testing strategies.
completengine v2.4.1 is the latest stable release. For migration guides from v1.x, see the Advanced section.
Getting Started #
This section walks you through installing completengine, setting up your first project, and understanding the core configuration options.
Installation #
Install completengine via your package manager of choice. The engine requires Node.js 18 or later and supports all major operating systems.
# Using npm npm install completengine # Using yarn yarn add completengine # Using pnpm pnpm add completengine
For global CLI access, install with the -g flag:
npm install -g completengine completengine init my-project
completengine automatically detects your project structure and configures itself on first run. No additional setup is required for most projects.
Verify installation by checking the version:
npx completengine --version # Output: completengine v2.4.1
Configuration #
While zero-config works for most cases, you can customize behavior with a complete.config.js file at your project root. The configuration file supports both ESM and CommonJS formats.
// complete.config.js export default { target: 'universal', optimize: true, concurrency: 4, plugins: [ compression(), analytics({ silent: true }) ], events: { maxListeners: 100, errorStrategy: 'propagate' } }
Setting optimize: false in production environments is not recommended and may result in degraded performance. Always enable optimization for deployed applications.
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
target | string | 'universal' | Build target platform |
optimize | boolean | true | Enable output optimization |
concurrency | number | 4 | Max parallel simulation threads |
plugins | Plugin[] | [] | Array of plugin instances |
events.maxListeners | number | 100 | Max event listeners per type |
events.errorStrategy | string | 'propagate' | Error handling strategy |
Environment Variables #
completengine reads several environment variables to adjust runtime behavior. These take precedence over configuration file values.
| Variable | Description | Default |
|---|---|---|
CE_LOG_LEVEL | Logging verbosity (debug, info, warn, error) | info |
CE_CONCURRENCY | Override max parallel threads | 4 |
CE_CACHE_DIR | Custom cache directory path | .cache/ |
CE_NO_COLOR | Disable colored terminal output | false |
# Run with debug logging CE_LOG_LEVEL=debug npx completengine build # Run with 8 parallel threads CE_CONCURRENCY=8 npx completengine build
API Reference #
The engine exposes a small, complete API surface. Every method is documented with types, parameters, and return values. The API is designed to be predictable and composable.
Core Methods #
These are the primary methods you will use to create, build, watch, and manage engine instances.
| Method | Parameters | Returns | Description |
|---|---|---|---|
engine.create() | config: Object | Engine | Create a new engine instance |
engine.build() | options?: Object | Promise<Result> | Run the simulation build |
engine.watch() | glob: string | Watcher | Watch files for changes |
engine.destroy() | none | void | Clean up resources |
engine.simulate() | scenario: Scenario | Promise<SimResult> | Run a simulation scenario |
engine.getState() | none | State | Get current engine state |
engine.create(config)
Creates and returns a new engine instance with the specified configuration. The instance is immediately ready for use.
import { engine } from 'completengine' const app = engine.create({ target: 'node', concurrency: 8, optimize: true }) const result = await app.build()
engine.simulate(scenario)
Runs a complete simulation based on the provided scenario definition. Scenarios describe the initial state, event sequences, and expected outcomes.
const scenario = { name: 'load-test', actors: 1000, duration: 5000, events: [ { type: 'spawn', at: 0, count: 100 }, { type: 'interact', at: 500, pattern: 'random' }, { type: 'checkpoint', at: 2500 } ] } const result = await app.simulate(scenario) // result.completed -> true // result.elapsed -> 4230 // result.events -> 15420
Use engine.simulate() with the dry: true option to validate your scenario definition without actually running the simulation.
Events #
completengine provides a robust event system for monitoring simulation lifecycle, build progress, and error states. Events are typed and fully documented.
const app = engine.create({ /* config */ }) app.on('build:start', (ctx) => { // Fires before build begins }) app.on('build:complete', (result) => { // Fires when build finishes }) app.on('sim:tick', (tick) => { // Fires each simulation tick // tick.frame, tick.actors, tick.elapsed }) app.on('error', (err) => { // Centralized error handler })
Event Reference
| Event | Payload | Description |
|---|---|---|
build:start | BuildContext | Emitted when a build begins |
build:complete | BuildResult | Emitted when a build completes |
sim:start | SimContext | Emitted when simulation starts |
sim:tick | TickData | Emitted each simulation frame |
sim:complete | SimResult | Emitted when simulation ends |
error | EngineError | Emitted on any engine error |
plugin:load | PluginMeta | Emitted when a plugin loads |
Plugins #
Extend the engine with first-party and community plugins. Plugins hook into the build and simulation lifecycle and can modify behavior at any stage.
import { compression, profiler } from 'completengine/plugins' const app = engine.create({ plugins: [ compression({ level: 9 }), profiler({ output: './profile.json' }) ] })
Writing a Plugin
Plugins are plain objects with lifecycle hooks. Each hook receives a context object and can return modified data or void.
export function myPlugin(options = {}) { return { name: 'my-plugin', version: '1.0.0', setup(engine) { // Called once during engine.create() }, beforeBuild(ctx) { // Modify build context before build starts ctx.meta.startTime = Date.now() }, afterBuild(ctx, result) { // Access build result, emit metrics, etc. const elapsed = Date.now() - ctx.meta.startTime }, teardown() { // Called on engine.destroy() } } }
Plugins are loaded in order. Place performance-critical plugins first in the array for optimal build times.
Available Plugins
| Plugin | Description | Size |
|---|---|---|
compression | Compress simulation output data | 2.1 KB |
profiler | Generate performance profiles | 3.4 KB |
analytics | Collect usage and build metrics | 1.8 KB |
cache | Intelligent build caching layer | 4.2 KB |
validator | Validate simulation inputs/outputs | 2.7 KB |
Performance #
completengine is designed for speed. Cold builds complete in under 100ms for typical projects. Hot rebuilds are sub-millisecond thanks to incremental compilation and intelligent caching.
| Metric | Cold | Hot | Notes |
|---|---|---|---|
| Build time | ~80ms | ~0.4ms | With optimization enabled |
| Memory usage | 12 MB | 4 MB | Heap allocation peak |
| Output size | Optimized | Cached | Gzip compressed |
| Sim throughput | 50k evt/s | 120k evt/s | Events per second |
Optimization Tips
To get the best performance from completengine, consider the following strategies:
// 1. Use the cache plugin for repeated builds import { cache } from 'completengine/plugins' const app = engine.create({ plugins: [cache({ maxAge: 3600000 })], concurrency: navigator.hardwareConcurrency || 4 }) // 2. Use incremental builds in watch mode const watcher = app.watch('src/**/*.js') // 3. Limit simulation scope for dev const devResult = await app.simulate({ actors: 100, // Fewer actors in dev duration: 1000, // Shorter duration sampling: 0.1 // Sample 10% of events })
The profiler plugin generates flame charts compatible with Chrome DevTools. Use it to identify bottlenecks in complex simulations.
Error Handling #
completengine uses structured errors with codes, messages, and recovery hints. All errors extend the base EngineError class.
import { EngineError } from 'completengine' try { await app.build() } catch (err) { if (err instanceof EngineError) { // err.code -> 'BUILD_FAILED' // err.message -> 'Build failed: missing entry' // err.hint -> 'Check that src/index.js exists' // err.context -> { file: 'src/index.js' } } }
Error Codes
| Code | Meaning | Recovery |
|---|---|---|
BUILD_FAILED | Build process encountered an error | Check config and inputs |
SIM_TIMEOUT | Simulation exceeded time limit | Increase duration or reduce actors |
PLUGIN_ERROR | A plugin threw an exception | Check plugin compatibility |
CONFIG_INVALID | Configuration validation failed | Review config schema docs |
STATE_CORRUPT | Engine state became inconsistent | Call engine.destroy() and recreate |
Always handle the error event on your engine instance. Unhandled engine errors will terminate the process in strict mode.
Testing #
completengine includes a built-in test runner for verifying simulations. Write declarative test scenarios and run them with the CLI or programmatic API.
import { test, expect } from 'completengine/test' test('handles 1000 concurrent actors', async () => { const app = engine.create({ concurrency: 8 }) const result = await app.simulate({ actors: 1000, duration: 5000 }) expect(result.completed).toBe(true) expect(result.errors).toHaveLength(0) expect(result.elapsed).toBeLessThan(6000) }) test('recovers from actor failure', async () => { const app = engine.create() const result = await app.simulate({ actors: 10, failAt: 5, events: [{ type: 'crash', target: 3 }] }) expect(result.recovered).toBe(true) expect(result.activeActors).toBe(9) })
Run tests from the command line:
# Run all tests npx completengine test # Run with coverage npx completengine test --coverage # Run specific test file npx completengine test sim.test.js
Use the --watch flag during development to automatically re-run tests when source files change.
Was this page helpful?