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

@nexart/codemode-sdk

v1.1.1

Published

NexArt Code Mode SDK - Canonical execution engine for deterministic generative art

Readme

NexArt Code Mode Runtime SDK

Version: 1.0.2 (Protocol v1.0.0)

╔══════════════════════════════════════════════════════════════════════════════╗ ║ @nexart/codemode-sdk — Canonical Code Mode Authority ║ ║ ║ ║ This SDK defines the official Code Mode execution surface. ║ ║ All implementations (NexArt, ByX, external) MUST use this SDK. ║ ║ ║ ║ Protocol: nexart ║ ║ Engine: codemode ║ ║ SDK Version: 1.0.2 ║ ║ Protocol Version: 1.0.0 ║ ║ Phase: 1 ║ ║ Enforcement: HARD ║ ╚══════════════════════════════════════════════════════════════════════════════╝


PROTOCOL LOCK — v1.0.0

| Property | Value | |----------|-------| | Protocol Name | NexArt Code Mode | | Version | v1.0.0 | | Status | HARD LOCKED | | Phase | 1 | | Lock Date | December 2024 |

This protocol surface is frozen. Any breaking change requires v2.0.0.

The following are locked and will not change in v1.x:

  • Execution model (Static and Loop modes)
  • VAR[0..9] specification (0-10 read-only variables, missing indices return 0)
  • Determinism guarantee (seed + VAR → identical output)
  • Time semantics (t, frameCount, time, tGlobal)
  • Random and noise behavior (seeded Mulberry32, Perlin)
  • Forbidden patterns list (13 patterns)
  • Canvas pre-initialization (no createCanvas)

A minimal, deterministic rendering engine for generative art.

Protocol Authority

This SDK is the single source of truth for Code Mode semantics.

If someone asks: "How does Code Mode work in NexArt?"

The answer is: "Whatever @nexart/codemode-sdk does — that is the protocol."


What's New in v1.0.2

  • VAR input is now optional (0-10 elements)
    • Omit vars or pass [] for empty (defaults to all zeros)
    • Input length must be 0-10 (throws if > 10)
    • Values must be finite numbers in [0, 100] (throws if out of range)
    • Runtime VAR is ALWAYS 10 elements (padded with zeros for consistency)
  • Backwards compatible: existing code passing 10 elements works unchanged

v1.0.1

  • Protocol Lock section formalized with HARD LOCKED status
  • VAR specification clarified with enforcement tables

v1.0.0 (Protocol Lock)

  • Protocol Lock: Phase 1 execution surface is now LOCKED
  • Canonical Entry Point: executeCodeMode() is the official execution API
  • Protocol Metadata: All executions include protocol headers for verification
  • VAR[0..9] Protocol Variables: First-class protocol inputs (read-only, 0-100)
  • Full CSS Color Support: hex, rgb(), rgba(), hsl(), hsla()
  • Determinism Guarantee: Same code + seed + vars = identical output

What This SDK Is

This SDK provides the canonical runtime for executing p5.js-style generative art:

  • Static Mode: Executes setup() only, outputs PNG
  • Loop Mode: Frame-authoritative rendering, outputs MP4
  • Deterministic: Seed-controlled randomness, no external state
  • Protocol-Compliant: All outputs include verification metadata

The SDK enforces the NexArt Code Mode Protocol v1.0.0 for reproducible, mint-safe generative art.


What This SDK Is NOT

  • Not a suggestion — This SDK IS the protocol, not a reference implementation
  • Not a UI library — No React components, no wallet integration
  • Not an IPFS client — Does not handle storage or minting
  • Not p5.js — Uses a minimal subset of p5.js-like functions

Installation

# Copy the sdk/codemode folder to your project
cp -r sdk/codemode your-project/lib/codemode

Canonical API

executeCodeMode(input: ExecuteCodeModeInput): Promise<ExecuteCodeModeResult>

This is the official, canonical entry point for Code Mode execution.

All implementations MUST use this function.

import { executeCodeMode } from '@nexart/codemode-sdk';

const result = await executeCodeMode({
  source: `
    function setup() {
      background(255);
      fill(0);
      let size = map(VAR[0], 0, 100, 50, 200);
      ellipse(width/2, height/2, size);
    }
  `,
  width: 1950,
  height: 2400,
  seed: 12345,
  vars: [50, 75, 0, 0, 0, 0, 0, 0, 0, 0],
  mode: 'static'
});

// Result includes protocol metadata
console.log(result.metadata.protocol);        // 'nexart'
console.log(result.metadata.engine);          // 'codemode'
console.log(result.metadata.protocolVersion); // '1.0.0'
console.log(result.metadata.deterministic);   // true
console.log(result.image);                    // PNG Blob

Input Parameters

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | source | string | ✅ | Code with setup() and optional draw() | | width | number | ✅ | Canvas width in pixels | | height | number | ✅ | Canvas height in pixels | | seed | number | ✅ | Seed for deterministic randomness | | vars | number[] | ❌ | VAR[0..9] values (0-100), defaults to all zeros | | mode | 'static' \| 'loop' | ✅ | Execution mode | | totalFrames | number | ⚠️ | Required for loop mode |

Result Structure

interface ExecuteCodeModeResult {
  image?: Blob;          // Static mode: PNG
  video?: Blob;          // Loop mode: MP4
  frames?: ImageData[];  // Optional: raw frame data
  metadata: {
    protocol: 'nexart';
    engine: 'codemode';
    protocolVersion: '1.0.0';
    phase: 1;
    deterministic: true;
    seed: number;
    vars: number[];
    width: number;
    height: number;
    mode: 'static' | 'loop';
    totalFrames?: number;
  }
}

Legacy API

⚠️ Note: The createEngine() API is still supported but new implementations should use executeCodeMode().

createEngine(config: EngineConfig): Engine

Create a rendering engine instance.

import { createEngine } from './codemode';

const engine = createEngine({
  mode: 'static',      // 'static' | 'loop'
  width: 1950,         // Optional, default: 1950
  height: 2400,        // Optional, default: 2400
  duration: 2,         // Loop mode only, 1-4 seconds
  fps: 30,             // Loop mode only, default: 30
});

engine.run(options: RunOptions): Promise<void>

Execute code and produce output.

await engine.run({
  code: `
    function setup() {
      background(255);
      fill(0);
      // Use VAR for external control
      let size = map(VAR[0], 0, 100, 50, 200);
      ellipse(width/2, height/2, size);
    }
  `,
  seed: 12345,              // Optional: seed for deterministic randomness
  vars: [50, 75, 0, 0, 0, 0, 0, 0, 0, 0],  // Optional: VAR[0..9] values (0-100)
  onPreview: (canvas) => {
    // Optional: called with canvas after first frame
  },
  onProgress: (info) => {
    // Optional: progress updates
    console.log(info.message, info.percent + '%');
  },
  onComplete: (result) => {
    // Required: called with final result
    console.log(result.type); // 'image' | 'video'
    console.log(result.blob); // Blob
  },
  onError: (error) => {
    // Optional: called on error
    console.error(error);
  },
});

Protocol Variables (VAR[0..9]) — Protocol v1.0.0

Protocol variables are first-class inputs that control artwork parameters.

VAR Specification (SDK v1.0.2):

| Property | Value | Enforcement | |----------|-------|-------------| | Input count | 0-10 (VAR[0]..VAR[9]) | HARD — throws if > 10 | | Runtime count | Always 10 | Padded with zeros | | Type | finite number | HARD — throws if non-number | | Range | 0-100 | HARD — throws if out of range | | Mutability | Read-only | HARD — Proxy blocks writes | | Injection | Before execution | Guaranteed | | Lifecycle | Stable for entire render | Guaranteed | | Default | All zeros | If not provided |

// Pass values when running (0-10 elements)
await engine.run({
  code: myCode,
  vars: [80, 50, 25],  // VAR[0]=80, VAR[1]=50, VAR[2]=25, VAR[3..9]=0
  onComplete: (result) => { /* ... */ },
});

// Or omit entirely (all zeros)
await engine.run({
  code: myCode,
  onComplete: (result) => { /* ... */ },
});

// Access in sketch code
function setup() {
  let density = map(VAR[0], 0, 100, 10, 200);
  let speed = map(VAR[1], 0, 100, 0.5, 5);
  // VAR[5] returns 0 if not provided
}

Rules (Protocol Law):

  • Input accepts 0-10 elements; runtime VAR is always 10 elements
  • VAR is injected BEFORE code execution (padded with zeros if needed)
  • VAR values are READ-ONLY at runtime (Proxy-protected)
  • Writing to VAR throws a protocol error
  • Values MUST be in range 0-100 (throws if out of range)
  • Same code + same seed + same VARs = identical output

engine.stop(): void

Cancel a running render (Loop mode only).

engine.getConfig(): EngineConfig

Get the resolved engine configuration.


Execution Rules

Static Mode

  1. setup() is executed once
  2. draw() is NOT executed
  3. Canvas is captured as PNG
  4. Time variables are all 0

Loop Mode

  1. setup() is executed once
  2. draw() is executed once per frame
  3. Canvas is cleared before each draw() call
  4. If artist calls background() in draw, it paints over the clear
  5. No canvas persistence between frames

Time Variables:

| Variable | Type | Description | |----------|------|-------------| | frameCount | int | Current frame (0, 1, 2, ...) | | t | float | Normalized time [0.0, 1.0) | | time | float | Elapsed seconds | | tGlobal | float | Alias for t |


Forbidden Patterns — LOCKED v1.0.0

The following 13 patterns are rejected with [Code Mode Protocol Error]:

| Pattern | Reason | |---------|--------| | setTimeout | Async timing breaks determinism | | setInterval | Async timing breaks determinism | | requestAnimationFrame | Async timing breaks determinism | | Date.now() | Time-based entropy forbidden | | new Date() | Time-based entropy forbidden | | Math.random() | Use seeded random() instead | | fetch() | External IO forbidden | | XMLHttpRequest | External IO forbidden | | createCanvas() | Canvas is pre-initialized | | document.* | DOM access forbidden | | window.* | DOM access forbidden | | import | External imports forbidden | | require() | External imports forbidden |

Additionally in Loop Mode:

  • noLoop() — Incompatible with frame capture

Example: Static Mode

import { createEngine } from './codemode';

const engine = createEngine({ mode: 'static' });

await engine.run({
  code: `
    function setup() {
      background(30);
      noStroke();
      for (let i = 0; i < 100; i++) {
        fill(random(255), random(255), random(255));
        ellipse(random(width), random(height), 50);
      }
    }
  `,
  onComplete: (result) => {
    // result.type === 'image'
    // result.blob is a PNG Blob
    const url = URL.createObjectURL(result.blob);
    document.body.innerHTML = `<img src="${url}" />`;
  },
});

Example: Loop Mode

import { createEngine } from './codemode';

const engine = createEngine({
  mode: 'loop',
  duration: 2,  // 2 second loop
});

await engine.run({
  code: `
    function setup() {
      // Called once
    }
    
    function draw() {
      background(30);
      
      // t goes from 0 to 1 over the loop duration
      let x = width/2 + cos(t * TWO_PI) * 200;
      let y = height/2 + sin(t * TWO_PI) * 200;
      
      fill(255);
      ellipse(x, y, 80);
    }
  `,
  onProgress: (info) => {
    console.log(info.message);
  },
  onComplete: (result) => {
    // result.type === 'video'
    // result.blob is an MP4 Blob
    const url = URL.createObjectURL(result.blob);
    document.body.innerHTML = `<video src="${url}" autoplay loop />`;
  },
});

Supported Functions

The SDK includes a minimal p5.js-like runtime with:

Drawing: background, clear, fill, noFill, stroke, noStroke, strokeWeight

Shapes: ellipse, circle, rect, square, line, point, triangle, quad, arc

Vertex: beginShape, vertex, endShape

Transform: push, pop, translate, rotate, scale, resetMatrix

Color: colorMode, color, lerpColor, red, green, blue, alpha, hue, saturation, brightness

Color Formats: All of the following are accepted by fill(), stroke(), background():

  • Grayscale: fill(128), fill(128, 127)
  • RGB: fill(255, 0, 0), fill(255, 0, 0, 128)
  • Hex: fill('#ff0000'), fill('#f00')
  • CSS: fill('rgb(255,0,0)'), fill('rgba(255,0,0,0.5)'), fill('hsl(180,50%,50%)')

Protocol Variables: VAR — Array of 10 values (VAR[0] through VAR[9])

Math: random, noise, map, constrain, lerp, dist, mag, norm

Trig: sin, cos, tan, asin, acos, atan, atan2, radians, degrees

Constants: PI, TWO_PI, HALF_PI, QUARTER_PI, width, height, frameCount


Video Encoding

Loop Mode requires server-side video encoding. The SDK calls:

POST /api/encode-loop

Ensure your server has this endpoint available (NexArt provides this).


Files

sdk/codemode/
├── index.ts         # Main export
├── engine.ts        # createEngine entry point
├── types.ts         # TypeScript types
├── static-engine.ts # Static mode implementation
├── loop-engine.ts   # Loop mode implementation
├── p5-runtime.ts    # p5.js-like runtime
└── README.md        # This file

License

MIT License

Copyright (c) 2024 NexArt


External Builders

This SDK is designed for use by:

  • NexArt App: The main generative art platform
  • ByX: Curated collection system
  • External Builders: Any platform consuming NexArt Code Mode

Integration Example

import { executeCodeMode } from '@nexart/codemode-sdk';

// Execute with explicit VAR values
const result = await executeCodeMode({
  source: artistCode,
  width: 1950,
  height: 2400,
  seed: 12345,
  vars: [50, 75, 25, 0, 0, 0, 0, 0, 0, 0],  // Exactly 10 values
  mode: 'static'
});

// Result includes full protocol metadata for verification
const { image, metadata } = result;
console.log(metadata.protocolVersion); // '1.0.0'
console.log(metadata.deterministic);   // true

Error Handling

All protocol violations throw descriptive errors:

try {
  await executeCodeMode({ ... });
} catch (error) {
  // "[Code Mode Protocol Error] VAR array must have exactly 10 elements, got 5"
  // "[Code Mode Protocol Error] Forbidden pattern: Math.random()"
  console.error(error.message);
}

Frozen Execution Guarantees — v1.0.0

The following guarantees are LOCKED and will not change in v1.x:

| Guarantee | Description | |-----------|-------------| | Determinism | Same code + same seed + same VARs = identical output | | Static Mode | setup() only, single PNG output | | Loop Mode | Frame-authoritative, draw() per frame, MP4 output | | Time Semantics | t ∈ [0,1), frameCount ∈ [0,totalFrames), time in seconds | | Random | Seeded Mulberry32 PRNG via random() | | Noise | Seeded Perlin noise via noise() | | Canvas | Pre-initialized, no createCanvas() | | VAR | Exactly 10 read-only protocol variables | | Forbidden Patterns | 13 patterns rejected (see above) |


Future Work (Phase 2+)

  • GSL v1 SDK (protocol layer) — separate package
  • Extended p5.js compatibility
  • WebGL rendering support
  • GIF output option