A high-performance, zero-persistence room simulator web application built to serve as a reference implementation for secure, scalable image processing in modern web environments.
Built with Next.js 16 (App Router), TypeScript, React-Konva, Sharp 0.35, BullMQ / DragonflyDB, and Drizzle ORM (Postgres/SQLite).
This application allows users to upload painting/artwork images, interactively position and scale them inside real interior room wall cutouts, and generate high-resolution composite artwork previews.
Live Demo: https://art-on-the-wall.netlify.app/
This project demonstrates advanced patterns for handling media processing safely in serverless and edge environments.
- Zero-Persistence Image Processing (RAM-only): Uploaded user images pass strictly through Node.js process memory as streams/buffers. User content is never written to
/tmp, disk, or database storage. Processed results are served directly from RAM and immediately reclaimed by GC (60-second TTL). - Advanced Sharp Compositing: Utilizes Sharp 0.35's 2-step compositing pipeline (
dest-overblend modes) for high-performance, pixel-perfect multi-layer merges (artwork behind transparent room cutouts). - Dual Database Architecture (Drizzle ORM): Uses Netlify Database (managed Postgres) for production deployments, while seamlessly falling back to a local SQLite (
.data/local.sqlite) instance usingbetter-sqlite3during local development. No Docker or manual Postgres setup required. - BullMQ + DragonflyDB Queue Engine: Background processing queue. Tasks carry only lightweight metadata (
jobId,userId,placement), keeping DragonflyDB RAM usage minimal. Includes a robust local standalone fallback for development without Redis. - Automated Static Wall Asset Scanner: A custom CLI script (
npm run scan-assets) automatically detects transparent alpha cutouts or dark bounding boxes on wall PNGs, applies an inwardbleedMarginPxto avoid edge artifacts, and generates precise*.png.config.jsonspatial specifications. - Optimized Assets: Wall thumbnails are dynamically resized, compressed, and served as WebP on the fly via Next.js native Image Optimization to guarantee blazing fast UI loads.
- 3-Layer React-Konva Canvas:
- Bottom Layer: User artwork + interactive Transformer (drag, scale, aspect ratio lock).
- Middle Layer: Shadow container & frame group for realistic depth.
- Top Layer: Room PNG wall background (
pointer-events: none) for automatic edge occlusion.
- Real-Time Progress Streaming: Server-Sent Events (SSE) endpoint pushes live progress % and ETA directly to the client UI.
This repository is designed as a secure reference project and adheres to strict security guidelines:
- Strict CSP & Security Headers: Enforces a robust
Content-Security-Policy(production), along withX-Frame-Options: DENY,X-Content-Type-Options: nosniff,Strict-Transport-Security,Referrer-Policy, andPermissions-Policy(disabling camera, mic, geolocation). - Zero Disk Footprint: User artwork exists exclusively in
BufferStoreRAM maps with automatic 60-second TTL purge. No leftover files on disk. - Session Throttling & Ownership: Users are limited to 1 concurrent job to respect server RAM budgets. Job endpoints strictly verify that the requesting session owns the job before serving any data.
- Byte-Level Image Validation: Uploaded files are validated against actual byte-level magic numbers via
sharp.metadata(). Client-supplied MIME types and extensions are explicitly distrusted. Only PNG, JPEG, WebP, and AVIF are accepted. - Input Bounds Clamping: File size is capped at 25 MB. Pixel count is capped at 200 megapixels. Scale and placement values from the canvas are mathematically clamped server-side to prevent memory exhaustion attacks.
- Rate Limiting: IP-based rate limiting (10 requests per 60 seconds) is enforced on the upload endpoint to mitigate DoS.
- No Credentials in Repository: Clean
.gitignoreexcludes.env,*.db*,/tmp, internal docs, build outputs, or local logs. - Sanitized Error Handling: Internal error paths and stack traces are sanitized before being written to the database or streamed to the client (mitigates internal path/version disclosure via SSE).
To report a security vulnerability, please see SECURITY.md.
- Node.js: v20.x or higher LTS
- Package Manager:
npm - Framework: Next.js 16+ (App Router) & React 19+
- Image Processing:
sharp(v0.35.x) - Canvas Engine:
konva&react-konva - Database: Netlify Database (managed Postgres) with Drizzle ORM
- Queue System:
bullmqwithioredis(DragonflyDB / Redis compatible) - Testing:
vitest
git clone https://github.com/arth2o/art-on-wall-simulator.git
cd art-on-wall-simulator
npm installCopy the example environment configuration file:
cp .env.example .envDefault configuration variables in .env:
PORT=3000
NODE_ENV=development
MAX_WORKER_MEMORY_MB=1024
GLOBAL_CONCURRENCY_LIMIT=12
# Optional DragonflyDB / Redis Connection (Falls back to standalone mode if offline)
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
NETLIFY_DB_URL=<your-netlify-postgres-connection-string>The asset scanner analyzes room wall PNGs in assets/walls/ and generates bounding box JSON configurations.
Note: This script runs automatically via NPM hooks when you start the dev server (npm run dev) or build for production (npm run build).
If you want to run it manually:
npm run scan-assetsnpm run devOpen http://localhost:3000 in your browser.
Run the Vitest test suite to verify Postgres connectivity, in-memory buffer store TTL cleanup, image processing pipelines, and zero-persistence security rules:
npm testThis project is optimized for deployment on Netlify, taking advantage of Netlify Database (Postgres) and Edge Functions.
npm run buildnpm run startMIT License. Open source and ready for public sharing as a reference implementation.
