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/cli

v0.11.0

Published

NexArt CLI — Code Mode and AI execution certification

Downloads

731

Readme

@nexart/cli v0.10.0

Command-line interface for NexArt — run, replay, and verify deterministic generative art, plus AI execution certification commands.

protocolVersion: 1.2.0 vs 1.3.0

Verified records carry a protocolVersion that selects how their bytes are canonicalised before hashing — ai verify surfaces it in both human-readable and --json output (cli.protocolVersion).

  • 1.2.0 (legacy, default): the original NexArt canonicalisation (nexart-v1), fully supported and frozen.
  • 1.3.0 (stranger-verifiable): RFC 8785 (JSON Canonicalization Scheme, jcs-v1). Required for independent / external verification by a third party who does not run our exact code.

A record with an unknown or unsupported protocolVersion fails closed (verify code SCHEMA_ERROR, reason code SCHEMA_VERSION_UNSUPPORTED, exit 1) — it is never mis-verified. The CLI adds no fallback or default.

Legacy 1.2.0 records are fully supported. Early 1.2.0 records that serialize snapshot.parameters as null (the canonical form was an empty object {}) verify correctly — ai verify reports VERIFIED (exit 0). This is handled in the SDK without any change to canonicalization or the certificateHash. 1.3.0 remains strict: a null parameters value on a 1.3.0 record fails closed.

Installation

# Global install (recommended)
npm install -g @nexart/cli

# After global install, use the `nexart` command directly:
nexart run sketch.js --seed 12345

Quickstart: Run an Example

The SDK includes example sketches in the examples/ folder:

# 1. Set up authentication
export NEXART_RENDERER_ENDPOINT=https://nexart-canonical-renderer-production.up.railway.app
export NEXART_API_KEY=nx_live_your_key_here

# 2. Run the main example sketch (outputs to current directory)
npx @nexart/cli run ./examples/sketch.js --seed 12345 --include-code --out ./out.png
# Creates: ./out.png and ./out.snapshot.json

# 3. Verify the output is deterministic
npx @nexart/cli verify ./out.snapshot.json
# Output: [nexart] Result: PASS

Output Files

When you run with --out ./out.png, the CLI creates:

  • ./out.png — The rendered PNG image
  • ./out.snapshot.json — Snapshot for replay/verify

Example Sketches

| File | Description | |------|-------------| | examples/sketch.js | Main example — VAR controls + random palette, protocol-safe | | examples/sketch-minimal.js | Simple shapes, no randomness — identical output every run | | examples/sketch-vars.js | Uses VAR + random() — demonstrates determinism with same seed |

Canonical Size

The canonical renderer enforces a fixed canvas size:

| Property | Value | |----------|-------| | Width | 1950 | | Height | 2400 |

Important: Do not pass custom --width or --height to the canonical renderer endpoint. The canonical size is enforced server-side for consistent, verifiable output.

# Correct: use default canonical size
nexart run sketch.js --seed 12345

# Avoid: custom sizes may be rejected by canonical renderer
# nexart run sketch.js --width 800 --height 600  # NOT recommended

Quick Start (npx)

Run without installing globally:

# Using npx (no install required)
npx @nexart/cli run sketch.js --seed 12345
npx @nexart/cli verify out.snapshot.json
npx @nexart/cli replay out.snapshot.json --out replay.png

Overview

The CLI has two command groups:

Code Mode commands — render generative art sketches, create verifiable snapshots, replay and verify them.

AI certification commands — create, certify, and verify tamper-evident Canonical Execution Records (CERs) for AI operations via the NexArt node API. Also includes local verification of project bundles (cer.project.bundle.v1) with nexart ai project-verify.

Authentication

Remote rendering requires an API key for metered access.

Setup

# Set environment variables
export NEXART_RENDERER_ENDPOINT=https://nexart-canonical-renderer-production.up.railway.app
export NEXART_API_KEY=nx_live_your_key_here

# Run with authentication
npx @nexart/cli run sketch.js --seed 12345 --include-code --out out.png

API Key Options

# Via environment variable (recommended)
export NEXART_API_KEY=nx_live_...
nexart run sketch.js --seed 12345

# Via CLI flag
nexart run sketch.js --seed 12345 --api-key nx_live_...

Error Messages

If authentication fails:

[nexart] Error: Missing API key for remote rendering.
[nexart] Set NEXART_API_KEY environment variable or pass --api-key.
[nexart] Get your API key at: https://nexart.art/dashboard/api

Commands

run

Execute a sketch and create a snapshot:

# With remote renderer (default, requires API key for remote endpoints)
nexart run sketch.js --seed 12345 --out render.png

# With code embedded for standalone verify/replay
nexart run sketch.js --seed 12345 --include-code

# Local deterministic mode (no auth required; requires the optional `canvas` dependency)
nexart run sketch.js --renderer local --include-code

Deterministic Replay (local renderer). With --renderer local, the CLI renders the sketch using the same canonical CodeMode render core as the SDK and hashes the encoded PNG bytes — the identical outputHash definition used by the remote renderer. For controlled CodeMode / canonical render snapshots this is byte-reproducible within the same runtime and render libraries (Node version, platform/arch, and canvas native libs). To make that reproducibility checkable, local snapshots additionally embed an optional, additive environment fingerprint (see below). Reproducibility across different environments is not guaranteed; replay/verify will warn when the environment differs. The local renderer requires the optional canvas package and its native libraries — if they are missing, local rendering fails with a clear, actionable error (never a silent placeholder).

Options: | Flag | Default | Description | |------|---------|-------------| | --out, -o | out.png | Output PNG path | | --seed, -s | random | PRNG seed | | --vars, -v | 0,0,0,0,0,0,0,0,0,0 | VAR values (comma-separated) | | --width, -w | 1950 | Canvas width (use default for canonical) | | --height | 2400 | Canvas height (use default for canonical) | | --renderer | remote | remote or local | | --endpoint | env/localhost:5000 | Remote renderer URL | | --api-key | env | API key for authentication | | --include-code | false | Embed code in snapshot | | --runtime-hash | auto | Override runtime hash |

Outputs:

  • render.png — The rendered image
  • render.snapshot.json — Snapshot for replay/verify

Snapshot environment field (additive, optional). Snapshots produced with --renderer local include an environment object describing the render environment (cliVersion, sdkVersion, protocolVersion, node, platform, arch, canvas). It is descriptive metadata only — it is never hashed and never affects pass/fail. It exists so replay/verify can warn when the replay environment differs from the capture environment. Legacy snapshots (and remote-rendered snapshots) omit this field and continue to verify and replay exactly as before.

verify

Check that a snapshot produces the expected output:

# Verify against the canonical remote renderer (default)
nexart verify render.snapshot.json

# Verify locally with the deterministic CodeMode renderer (requires `canvas`)
nexart verify render.snapshot.json --renderer local

# With external code file
nexart verify render.snapshot.json --code sketch.js

The local path performs a real render (no placeholder) — a missing canvas dependency fails clearly rather than producing a false pass.

Exit codes:

  • 0 — PASS (hashes match)
  • 1 — FAIL (hashes differ or error)

replay

Re-execute from a snapshot, compare the result against the snapshot, and report PASS/FAIL:

# Deterministic local replay with PASS/FAIL evidence
nexart replay render.snapshot.json --renderer local --out replay.png \
  --evidence replay.evidence.json

# With external code file
nexart replay render.snapshot.json --code sketch.js --out replay.png

replay recomputes the output hash and compares it to the snapshot's outputHash, and independently checks that the replayed code matches the snapshot's codeHash. The overall result is PASS only when both match.

Options: | Flag | Default | Description | |------|---------|-------------| | --out, -o | replay.png | Output PNG path | | --code, -c | — | Code file (if not embedded in snapshot) | | --renderer | remote | remote or local (deterministic CodeMode renderer) | | --endpoint | env/localhost:5000 | Remote renderer URL | | --evidence | — | Write a JSON replay-evidence file (PASS/FAIL + hash comparison) | | --api-key | env | API key for authentication |

Exit codes:

  • 0 — PASS (output and code match the snapshot)
  • 1 — FAIL (output or code differs, or render error)

When --evidence <file> is given, replay writes a codemode.replay.evidence.v1 JSON document recording the PASS/FAIL result, the expected vs. actual outputHash and codeHash, the renderer used, and the snapshot vs. current environment fingerprints (with any differing fields).


AI Certification Commands (nexart ai)

These commands interact with the NexArt node API to manage Canonical Execution Records (CERs) for AI operations. CERs are tamper-evident bundles that cryptographically certify an AI execution (input, output, model, parameters).

Environment Variables

| Variable | Description | |----------|-------------| | NEXART_NODE_ENDPOINT | NexArt node API URL (default: https://node.nexart.art) | | NEXART_API_KEY | Shared API key for authenticated requests |

nexart ai create

Create a CER bundle from an AI execution record.

# From file
nexart ai create execution.json

# From stdin
cat execution.json | nexart ai create

# With explicit endpoint and API key
nexart ai create execution.json \
  --endpoint https://node.nexart.art \
  --api-key nx_live_...

# Save to file
nexart ai create execution.json --out cer.json

Input format (JSON file or stdin):

{
  "executionId": "exec-001",
  "provider": "openai",
  "model": "gpt-4o",
  "input": "What is 2+2?",
  "output": "4",
  "parameters": { "temperature": 0 }
}

Output: CER bundle JSON printed to stdout (or saved via --out).

Options: | Flag | Default | Description | |------|---------|-------------| | --endpoint | env/https://node.nexart.art | NexArt node URL | | --api-key | env | API key | | --out | stdout | Save bundle to file | | --signals-file | (none) | Path to a JSON array of context signals to attach |

Exit codes:

  • 0 — Success
  • 1 — API error or missing input

nexart ai certify

Certify an AI execution and receive an attested CER bundle. The node API signs the bundle and attaches an attestation.

# From file
nexart ai certify execution.json

# From stdin
cat execution.json | nexart ai certify

# JSON output (machine-readable)
nexart ai certify execution.json --json

# Save output
nexart ai certify execution.json --out certified.json

Default output:

[nexart] CER certified successfully
bundleType : cer.ai.execution.v1
hash       : sha256:a1b2c3...
attestation: present

JSON output (--json):

{
  "ok": true,
  "bundleType": "cer.ai.execution.v1",
  "certificateHash": "sha256:a1b2c3...",
  "hasAttestation": true,
  "bundle": { ... }
}

Options: | Flag | Default | Description | |------|---------|-------------| | --endpoint | env/https://node.nexart.art | NexArt node URL | | --api-key | env | API key | | --out | stdout | Save bundle to file | | --json | false | Machine-readable JSON output | | --signals-file | (none) | Path to a JSON array of context signals to attach |

Exit codes:

  • 0 — Certified successfully
  • 1 — API error (e.g. 401 Unauthorized), missing input, or invalid response

nexart ai seal (v0.8.0+)

Create a Certified Execution Record locally — no node required. Produces an integrity-only bundle suitable for offline workflows, CI, pre-certification, or piping straight into nexart ai verify. All snapshot construction, canonicalization, and certificate hashing is delegated to createSnapshot() + sealCer() from @nexart/ai-execution — the canonical source of truth.

# Seal from file
nexart ai seal execution.json

# Seal from stdin
cat execution.json | nexart ai seal

# Seal then verify in a pipe (--quiet keeps the pipe clean)
cat execution.json | nexart ai seal --quiet | nexart ai verify

# Save sealed bundle to file
nexart ai seal execution.json --out cer.json

Default output (stdout — bundle JSON):

{
  "bundleType": "cer.ai.execution.v1",
  "certificateHash": "sha256:...",
  "createdAt": "2026-04-30T12:00:00.000Z",
  "version": "0.1",
  "snapshot": { ... }
}

Status banner (stderr):

[nexart] Local CER created
[nexart] State: Sealed (integrity only)
[nexart] No node attestation present
[nexart] This record is not certified — use `nexart ai certify` to attest via a node
[nexart] certificateHash: sha256:...

Options: | Flag | Default | Description | |------|---------|-------------| | --out / -o | stdout | Save sealed CER bundle to this file | | --quiet / -q | false | Suppress the stderr banner (clean pipe output) |

Sealed vs Certified:

  • Sealed (ai seal): integrity only. No node receipt, no signature, no envelope. Verifies as VERIFIED with Receipt and Envelope reported as SKIPPED — that is correct, not a failure.
  • Certified (ai certify): integrity + node attestation receipt + signature. Requires a node and an API key.

Exit codes:

  • 0 — Sealed successfully
  • 1 — Missing required fields, invalid input JSON, or stdin error

nexart ai verify

Verify a CER bundle or CER package locally. No network call. All verification logic — bundleType discriminant, package detection / inner-CER unwrap, canonicalization, hash recomputation, and 3-layer status (Integrity / Receipt / Envelope) — is delegated to verifyAiCerBundleDetailed() from @nexart/ai-execution. The CLI owns input routing and output formatting only. Fully compatible with v0.11.0+ CERs that include context.signals, v0.6.0+ CER packages, and v0.8.0+ locally-sealed bundles from nexart ai seal.

# Verify a raw CER bundle from file
nexart ai verify cer.json

# Verify a CER package (inner bundle verified; envelope fields are not verified)
nexart ai verify cer-package.json

# From stdin
cat cer.json | nexart ai verify

# JSON output
nexart ai verify cer.json --json

Default output (PASS — raw bundle):

Verification result: VERIFIED
bundleIntegrity: PASS
nodeSignature: SKIPPED
receiptConsistency: SKIPPED

Default output (PASS — CER package):

Input type: CER package
Verification result: VERIFIED
bundleIntegrity: PASS
nodeSignature: SKIPPED
receiptConsistency: SKIPPED
Note: Verified inner CER bundle only. Package-level receipt/signature/envelope not verified by this command.

Default output (FAIL):

Verification result: FAILED
bundleIntegrity: FAIL
[nexart] Expected hash: sha256:a1b2c3...
[nexart] Computed hash: sha256:d4e5f6...

JSON output (--json) — raw bundle:

{
  "status": "VERIFIED",
  "checks": {
    "bundleIntegrity": "PASS",
    "nodeSignature": "SKIPPED",
    "receiptConsistency": "SKIPPED"
  },
  "reasonCodes": [],
  "certificateHash": "sha256:a1b2c3...",
  "bundleType": "cer.ai.execution.v1",
  "verifiedAt": "2026-04-30T12:00:00.000Z",
  "verifier": "@nexart/ai-execution",
  "cli": {
    "version": "0.9.0",
    "sdkVersion": "0.16.1",
    "inputType": "bundle"
  }
}

JSON output (--json) — CER package:

{
  "status": "VERIFIED",
  "checks": {
    "bundleIntegrity": "PASS",
    "nodeSignature": "SKIPPED",
    "receiptConsistency": "SKIPPED"
  },
  "reasonCodes": [],
  "certificateHash": "sha256:a1b2c3...",
  "bundleType": "cer.ai.execution.v1",
  "verifiedAt": "2026-04-30T12:00:00.000Z",
  "verifier": "@nexart/ai-execution",
  "cli": {
    "version": "0.9.0",
    "sdkVersion": "0.16.1",
    "inputType": "package",
    "verifiedInnerCer": true,
    "packageTrustLayersVerified": false
  }
}

The top-level fields (status, checks, reasonCodes, certificateHash, bundleType, verifiedAt, verifier) are the SDK's CerVerificationResult verbatim. The additive cli envelope carries CLI-only metadata (version, sdkVersion, inputType, and package-specific flags when applicable).

Enterprise trust layers (--anchors, --timestamps): these flags opt in to the non-evidentiary secondary-proof layers. They are reported separately and never change the base verification result or the exit code — they cannot turn a VERIFIED bundle into FAILED or vice-versa.

# Report anchor status (VALID / INVALID / NOT PRESENT)
nexart ai verify cer.json --anchors

# Report anchor + trusted timestamp status with a trust summary
nexart ai verify cer.json --anchors --timestamps

When enabled, the human-readable output adds a Layers: block (Anchoring / Timestamp lines) and a Trust summary block (Signature / Anchors / Timestamp / Protocol Version); the JSON output adds top-level anchorStatus and timestampStatus objects ({ checked, valid, errors? }).

Options: | Flag | Default | Description | |------|---------|-------------| | --json | false | Machine-readable JSON output | | --anchors | false | Verify and report anchor status (non-evidentiary; does not affect exit code) | | --timestamps | false | Verify and report trusted-timestamp status + trust summary (non-evidentiary) |

Exit codes:

  • 0 — PASS (inner bundle hash matches)
  • 1 — FAIL (hash mismatch, invalid bundle, or unsupported format)

nexart ai attach-anchor

Attach an external anchor (transparency log / TSA / blockchain) to a CER bundle. This is an append-only, non-evidentiary operation — it does not re-hash or re-sign the bundle.

# Attach an anchor and verify it in one pipe
nexart ai attach-anchor cer.json anchor.json | nexart ai verify --anchors

nexart export-verification

Produce a self-contained verification package that a third party can verify offline, without the NexArt node or this SDK. It is read-only — nothing is re-hashed or re-signed.

# Print a verification package to stdout
nexart export-verification cer.json

# Resolve the signing public key from a node-keys document and save the package
nexart export-verification cer.json --node-keys keys.json --out pkg.json

# From stdin
cat cer.json | nexart export-verification

The package contains { bundle, publicKey, verificationInstructions }, where verificationInstructions lists the protocolVersion, canonicalMode, certificateHash, signatureAlgorithm, the present layer flags, and ordered verification steps.

Options: | Flag | Default | Description | |------|---------|-------------| | --out, -o | — | Save the package to this file (otherwise printed to stdout) | | --node-keys | — | Path to a NodeKeysDocument JSON to resolve the signing public key | | --public-key | — | Provide the public key directly (takes precedence over --node-keys) |


nexart ai project-verify (v0.7.0+)

Verify a project bundle (cer.project.bundle.v1) locally. No network required. Delegates all verification logic to verifyProjectBundle() from @nexart/ai-execution — the canonical source of truth for project bundle semantics. The CLI provides the command surface and output formatting.

# From file
nexart ai project-verify project-bundle.json

# From stdin
cat project-bundle.json | nexart ai project-verify

# Machine-readable JSON output
nexart ai project-verify project-bundle.json --json

Checks performed (in order, via @nexart/ai-execution):

  1. bundleType discriminant: must be cer.project.bundle.v1
  2. Required fields: version, protocolVersion, projectBundleId, projectTitle, startedAt, completedAt, integrity block shape
  3. stepRegistry is a non-empty array
  4. embeddedBundles is a plain object keyed by stepId
  5. totalSteps must equal stepRegistry.length
  6. Per-step: embedded bundle exists; executionId and certificateHash match the registry entry; inner CER certificateHash is independently valid
  7. integrity.projectHash is recomputed from all material project metadata and compared to the declared value

Default output (PASS):

Verification result: VERIFIED
bundleType: cer.project.bundle.v1
projectBundleId: proj-abc123
projectTitle: My Project
totalSteps: 3
passedSteps: 3
failedSteps: 0
projectHashIntegrity: PASS
stepIntegrity: PASS

Default output (FAIL):

Verification result: FAILED
bundleType: cer.project.bundle.v1
projectBundleId: proj-abc123
projectTitle: My Project
totalSteps: 3
passedSteps: 2
failedSteps: 1
projectHashIntegrity: FAIL
stepIntegrity: FAIL
[nexart] Error: integrity.projectHash mismatch: expected sha256:..., got sha256:...

JSON output (--json):

{
  "status": "VERIFIED",
  "bundleType": "cer.project.bundle.v1",
  "projectBundleId": "proj-abc123",
  "projectTitle": "My Project",
  "totalSteps": 3,
  "passedSteps": 3,
  "failedSteps": 0,
  "projectHashValid": true,
  "checks": {
    "structuralValid": true,
    "projectHashIntegrity": "PASS",
    "stepIntegrity": "PASS"
  },
  "steps": [
    {
      "stepId": "step-001",
      "sequence": 0,
      "executionId": "exec-abc",
      "certificateHash": "sha256:...",
      "ok": true,
      "errors": []
    }
  ],
  "errors": [],
  "verifiedAt": "2026-04-06T12:00:00.000Z",
  "verifier": "@nexart/cli"
}

Options: | Flag | Default | Description | |------|---------|-------------| | --json | false | Machine-readable JSON output |

Exit codes:

  • 0 — VERIFIED (all checks pass)
  • 1 — FAILED (any structural, step, or hash error)

Context Signals (v0.5.0+)

Context signals attach upstream evidence — CI approvals, webhook events, human-review records — to a CER. They are included in the context.signals array and are tamper-evident: the certificateHash covers the full context block, so any post-creation modification to signals is detected by nexart ai verify.

Preparing a signals file

A signals file is a plain JSON array of signal objects:

[
  {
    "type": "approval",
    "source": "github-actions",
    "step": 0,
    "timestamp": "2026-03-15T12:00:00.000Z",
    "actor": "alice",
    "status": "ok",
    "payload": { "pr": 42 }
  }
]

Attaching signals when creating / certifying

# Create CER with signals
nexart ai create execution.json --signals-file signals.json --out cer.json

# Certify with signals
nexart ai certify execution.json --signals-file signals.json

The CLI reads the JSON array from --signals-file, merges it into the request body as { signals: [...] }, and sends it to the node API. The node then embeds the signals in the CER under context.signals and includes them in the certificateHash.

Verifying a signals-containing CER

No extra flags are needed — nexart ai verify handles both plain CERs and CERs with context.signals:

nexart ai verify cer.json
# Verification result: VERIFIED
# bundleIntegrity: PASS

If any signal field is altered after creation, the hash will mismatch and verification fails:

# (tampered context.signals)
nexart ai verify tampered-cer.json
# Verification result: FAILED
# bundleIntegrity: FAIL

CER Packages (v0.6.0+)

A CER package is an envelope object that wraps a raw CER bundle with optional metadata layers — receipt, signature, and custom envelope fields:

{
  "cer": {
    "bundleType": "cer.ai.execution.v1",
    "certificateHash": "sha256:...",
    "version": "1.0.0",
    "createdAt": "...",
    "snapshot": { ... }
  },
  "receipt": { ... },
  "signature": "base64url-sig=="
}

nexart ai verify automatically detects the format:

  • Raw bundle — input has bundleType === 'cer.ai.execution.v1' at the top level. Behavior is identical to pre-v0.6.0.
  • CER package — input has a cer field whose inner bundleType === 'cer.ai.execution.v1'. The CLI verifies only the inner bundle; receipt, signature, and other envelope fields are not verified.

Detection is transparent — no flags are needed. Both formats use the same nexart ai verify command.

What IS verified (inner bundle)

  • certificateHash is recomputed from the protected set (bundleType, version, createdAt, snapshot) and the optional context block (signals). A mismatch reports BUNDLE_HASH_MISMATCH.

What is NOT verified (package envelope)

  • receipt fields (attestationId, nodeRuntimeHash, etc.)
  • signature (cryptographic envelope signature)
  • Custom envelope fields

Full package trust verification (receipt + envelope signature) is planned for a future release.


Remote Renderer

The CLI calls a canonical Node.js renderer endpoint for real PNG generation.

Endpoint Configuration

# Via environment variable
export NEXART_RENDERER_ENDPOINT=https://nexart-canonical-renderer-production.up.railway.app
export NEXART_API_KEY=nx_live_...

# Via CLI flags
nexart run sketch.js --endpoint https://render.nexart.io --api-key nx_live_...

Expected API

POST /api/render
Content-Type: application/json
Authorization: Bearer <api_key>

{
  "code": "...",
  "seed": 12345,
  "VAR": [0,0,0,0,0,0,0,0,0,0],
  "width": 1950,
  "height": 2400,
  "protocolVersion": "1.2.0"
}

Response: image/png (binary)
Headers:
  X-Runtime-Hash: <hash>

Equivalent curl

curl -X POST https://nexart-canonical-renderer-production.up.railway.app/api/render \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer nx_live_..." \
  -d '{"code":"createCanvas(1950,2400);\nbackground(0);\n","seed":12345,"VAR":[0,0,0,0,0,0,0,0,0,0],"width":1950,"height":2400,"protocolVersion":"1.2.0"}' \
  --output render.png

Snapshot Format (v1)

{
  "protocol": "nexart",
  "protocolVersion": "1.2.0",
  "runtime": "canonical",
  "runtimeHash": "<sha256>",
  "codeHash": "<sha256>",
  "seed": 12345,
  "VAR": [0,0,0,0,0,0,0,0,0,0],
  "canvas": { "width": 1950, "height": 2400 },
  "outputHash": "<sha256>",
  "createdAt": "2026-01-25T...",
  "code": "..." // optional, if --include-code
}

Hash definitions:

  • outputHash = SHA-256 of PNG bytes
  • codeHash = SHA-256 of normalized code
  • runtimeHash = From renderer or SHA-256 of SDK version

Renderer Modes

| Mode | Description | |------|-------------| | --renderer remote | Default. Calls canonical renderer with auth, produces real PNG output. | | --renderer local | NOT implemented yet. Outputs a 1x1 placeholder image only. No auth required. |

# Remote (default) — real PNG output, requires API key for remote endpoints
nexart run sketch.js --seed 12345

# Local — NOT implemented, placeholder only, no auth
nexart run sketch.js --renderer local

Real local/offline rendering is planned for a future release.

Environment Variables

| Variable | Description | |----------|-------------| | NEXART_RENDERER_ENDPOINT | Remote renderer URL (default: http://localhost:5000) | | NEXART_NODE_ENDPOINT | NexArt node API URL (default: https://node.nexart.art) | | NEXART_API_KEY | API key for authenticated requests |

License

MIT — Free for all use including commercial.

See Core vs Edges for the NexArt business model.