Personal creative coding environment for NexArt art piece development with Canvas2D, combining the power of Next.js, TypeScript, and the NexArt Protocol.
Ensure You Have The Following Installed:
-
Node.js ^22.x (package set to '22.x')
-
pnpm ^10.x or (package set to '10.26.2')
-
IF NEEDED RUN:
npm install -g pnpm
OR
corepack enable corepack use [email protected]
-
-
Git
Clone The Repository
git clone https://github.com/bedlam520dev/nexart-design-studio.gitNavigate To Project Directory
cd nexart-design-studioInstall Dependencies
pnpm installGenerate NexArt Capabilities Reference File
pnpm capabilitiesStart Development Server
pnpm dev- Navigate to 'http://localhost:3000/runner.html' to see your art!
Build For Production
pnpm buildStart Production Server
pnpm startType Check → '_devlogs/typecheck-*.log'
pnpm check-typesLint Code → '_devlogs/lint-*.log'
pnpm lintFix Lint Issues → '_devlogs/lint-fix-*.log'
pnpm lint:fixFormat Code → '_devlogs/format-*.log'
pnpm formatCheck Formatting → '_devlogs/format-check-*.log'
pnpm format:checkRuns All Checks With Logs
pnpm validateExport Sketch To NexArt Compliant Snippet
pnpm export:nexart src/art/pieces/[name]/sketch.tssrc/
art/
pieces/ # Individual art pieces
flowing-particles/
sketch.ts # Development sketch
nexart-export.md # NexArt deployment code
generative-waves/
nexart-template/ # Clean template for new pieces
lib/
canvas.ts # Canvas utilities
colors.ts # Color manipulation (chroma-js)
noise.ts # Noise functions (simplex-noise)
math.ts # Math helpers
nexart-capabilities.ts # Auto-generated NexArt reference
types.ts # TypeScript types
components/ # React components (when ready)
app/ # Next.js app (future frontend)
scripts/
export-nexart.ts # Export sketch to NexArt format
generate-capabilities.ts # Generate capability reference
public/
runner.html # Standalone art runner
Copy The Template
cp -r src/art/pieces/nexart-template src/art/pieces/[name]Edit Your Sketch
/* src/art/pieces/[name]/sketch.ts */
import type { NexArtSketch } from '@/art/types';
export const metadata = {
title: '{Art Title [name]}',
author: '{Author Name}',
date: new Date().toISOString(),
description: '{Description Of Art Piece}',
genre: '{NexArt Specific Genre Of Art Piece **STRICT**},
};
// Required: runs once on start (for ALL art)
const setup = (canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D) => {
// Initialize canvas, set background, create initial state
// Store state on canvas object: (canvas as any).__myState = {}
};
// Optional: runs every frame (for animated art)
const draw = (canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, frame: number) => {
// Your animation logic here
// All calculations inline - NO helper functions
// All state from setup or declared here - NO global variables
};
export const sketch: NexArtSketch = { setup, draw };Edit 'public/runner.html' at line 24:
const { sketch } = await import('/src/art/pieces/[name]/sketch.ts');Then View At 'http://localhost:3000/runner.html'
CRITICAL: NexArt has STRICT requirements:
✅ Allowed:
- setup() function (optional)
- draw() function (required)
- All logic inline in these functions
- Math, canvas 2D API, basic JS
❌ NOT Allowed:
- Helper functions
- Global variables
- External libraries in deployment
- let/const outside functions
Export Your Sketch (EXAMPLE)
pnpm export:nexart src/art/pieces/generative-waves/sketch.tsOutput example (src/art/pieces/generative-waves/nexart-export.md):
TITLE: Generative Waves
// GENRE: TEMPORAL ACCUMULATION
function setup() {
const width = canvas.width / (window.devicePixelRatio || 1);
const height = canvas.height / (window.devicePixelRatio || 1);
ctx.fillStyle = '#0a0e27';
ctx.fillRect(0, 0, width, height);
}
function draw() {
const width = canvas.width / (window.devicePixelRatio || 1);
const height = canvas.height / (window.devicePixelRatio || 1);
const centerX = width / 2;
const centerY = height / 2;
ctx.fillStyle = 'rgba(10, 14, 39, 0.1)';
ctx.fillRect(0, 0, width, height);
const waveCount = 8;
const resolution = 200;
const amplitude = 80;
const frequency = 0.005;
const noiseInfluence = 0.3;
const colors = ['#023e8a', '#0077b6', '#00b4d8'];
for (let w = 0; w < waveCount; w++) {
const colorIndex = Math.floor((w / waveCount) * colors.length);
ctx.strokeStyle = colors[Math.min(colorIndex, colors.length - 1)];
ctx.lineWidth = 2;
ctx.beginPath();
const yOffset = ((w / waveCount) - 0.5) * height * 0.6;
for (let i = 0; i <= resolution; i++) {
const x = (i / resolution) * width;
const t = frame * 0.01 + w * 0.5;
let y = Math.sin(x * frequency + t) * amplitude;
const noiseValue = Math.sin(x * 0.002 * 10 + t * 0.1) * Math.cos(w * 5);
y += noiseValue * amplitude * noiseInfluence;
y += centerY + yOffset;
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
}
}
The '@nexart/ui-renderer' package provides a declarative system for creating art.
Edit 'public/runner.html' and set 'useUIRenderer = true':
import { createSystem, previewSystem } from '@nexart/ui-renderer';
const system = createSystem({
seed: 29445825,
background: { color: 'blue', texture: 'noise' },
elements: [
{ type: 'waves', axis: 'x', amplitude: 0.4, frequency: 0.7 },
{ type: 'dots', distribution: 'radial', count: 400 },
],
motion: { source: 'time', speed: 0.2 },
});
previewSystem(system, canvas, { mode: 'loop' }).start();Run The Capabilities Generator To Get All Available Capabilities:
pnpm tsx scripts/generate-capabilities.tsOR
pnpm capabilitiesThis creates:
- 'src/art/lib/nexart-capabilities.ts' - TypeScript types & helpers
- 'docs/nexart-reference.md' - Human-readable reference
Canvas (src/art/lib/canvas.ts)
import { setupCanvas, clear, centerCanvas, saveFrame } from '@/art/lib/canvas';
const ctx = setupCanvas(canvas);
clear(ctx, '#000000');
const { x, y, width, height } = centerCanvas(ctx);
saveFrame(canvas, 'my-art-frame');Colors (src/art/lib/colors.ts)
import {
palette,
interpolateColor,
colorScale,
withAlpha,
} from '@/art/lib/colors';
const color = palette.neon[0];
const mixed = interpolateColor('#ff0000', '#0000ff', 0.5);
const scale = colorScale(['#000', '#fff'], 10);
const transparent = withAlpha('#ff0000', 0.5);Noise (src/art/lib/noise.ts)
import { noise, fbm, turbulence } from '@/art/lib/noise';
const value = noise.get2D(x * 0.01, y * 0.01);
const fractal = fbm(x, y, 4, 0.5);
const turb = turbulence(x, y, 64);
Math(src / art / lib / math.ts);
import { lerp, map, clamp, dist, randomRange } from '@/art/lib/math';
const interpolated = lerp(0, 100, 0.5); // 50
const mapped = map(50, 0, 100, -1, 1); // 0
const clamped = clamp(150, 0, 100); // 100
const distance = dist(0, 0, 3, 4); // 5
const random = randomRange(10, 20);Capabilities (src/lib/nexart-capabilities.ts)
AUTO-GENERATED WHEN 'pnpm capabilities' IS RAN
Create Sketch In 'src/art/pieces/[name]/sketch.ts'
- Use helper libraries during development
- Test in runner.html
- Export to NexArt format when ready
- Deploy exported code to NexArt Platform
Start Dev Server
pnpm devEdit Sketch File
Refresh Browser To See Changes
Use Cmd/Ctrl+S To Save Frame (If Implemented In Sketch)
Prettier (prettier.config.mjs)
- Auto-sorts Tailwind classes
- Enforces consistent formatting
- Configured for minimal noise
ESLint (eslint.config.mjs)
- Next.js + TypeScript rules
- React hooks linting
- Import organization
- Accessibility checks
TypeScript (tsconfig.json)
- Strict mode enabled
- Path aliases (@/_ → src/_)
- Next.js optimization
✅ Do:
- Focus on one sketch at a time
- Use the template for consistency
- Let Prettier handle formatting
- Test frequently in runner.html
- Export early, export often
❌ Avoid:
- Over-engineering during creative flow
- Premature optimization
- Too many files open at once
- Skipping the export step
This project uses:
- NexArt Code Mode SDK - Overall design standards and creation excellence
- NexArt UI Renderer - UI Component SDK to effectively develop amazing art
- pnpm - Fast, efficient package manager
- Next.js 16 - React framework
- TypeScript - Type safety
- Tailwind CSS v4 - Utility-first CSS
- ESLint - Code quality
- Prettier - Code readability and consistency
NexArt Protocol - Protocol
NexArt Builders Guide - Builders
Code Mode Reference - Quick Reference
Execution Details - Code Mode Execution
NexArt Platform - NexArt App
NexArt Static Builder App - NexArt Static Builder App
NexArt Canonical SDK Source Code - Code Mode SDK Source Code
NexArt UI Renderer SDK Source Code - UI Renderer SDK Source Code
NexArt Platform Quick Start Guide - NexArt Quick Start Guide
NexArt Platform Frequently Asked Questions - NexArt FAQs
[ ] Next.js frontend for sketch gallery and visual design studio [ ] WYSIWYG style sketch editor with drag and drop effect blocks [ ] Live parameter controls for functions and effects [ ] Sketch versioning system for evolving art projects [ ] Automated deployment to NexArt directly from the studio UI [ ] Real-time collaboration features for co-op art design
MIT License - See LICENSE File
We Welcome And Will Consider All Contribution Requests - See CONTRIBUTING.md File
For Questions, Concerns, Or Otherwise Regarding This Project Contact BEDLAM520 Development At:
For Anything Specifically Regarding The NexArt Platform Or Protocol Contact NexArt Team At: