Skip to content
/ stims Public

This project is a library of interactive webtoys designed to provide neurodiverse individuals with engaging and stimulating experiences. Each webtoy in the collection uses sound, visuals, and interactivity to create dynamic environments that can be customized and explored in a playful way

License

Notifications You must be signed in to change notification settings

zz-plant/stims

Stim Webtoys Library

Welcome to the Stim Webtoys Library, hosted at no.toil.fyi. This is a collection of interactive web-based toys designed to provide some fun sensory stimulation. They’re built with Three.js, WebGL, and live audio interaction for anyone who enjoys engaging, responsive visuals. These are great for casual play, or as a form of sensory exploration, especially for neurodiverse folks.

For setup, testing, and contribution guidelines, see CONTRIBUTING.md. If you're building or updating toys, the developer docs in docs/ cover common workflows and patterns. If you’re using the Model Context Protocol server in scripts/mcp-server.ts, see the dedicated guide in docs/MCP_SERVER.md.

Looking for release notes? Check out the CHANGELOG to see what’s new, what changed, and what’s coming next.

Documentation map

Use these entry points to find the right docs quickly:

If you add new scripts, toys, or deployment options, update the relevant doc above so the workflows stay discoverable.

When to update docs

Change type Docs to touch
New toy or renamed slug docs/TOY_DEVELOPMENT.md, docs/TOY_SCRIPT_INDEX.md, docs/toys.md
New script or workflow change docs/DEVELOPMENT.md
Hosting or CI change docs/DEPLOYMENT.md, docs/ARCHITECTURE.md (if it alters runtime/data flow)
MCP server updates docs/MCP_SERVER.md

Quick Start

  1. Clone the repo and cd into it.
  2. Choose your runtime (the repo records bun@1.2.14 in package.json via packageManager):
    • Bun 1.2+: install from bun.sh for the fastest install/test cycle and the supported workflow.
  3. Install dependencies with bun install. The repository tracks bun.lock for reproducible installs—use bun install --frozen-lockfile to respect it.
  4. Start the dev server with bun run dev, then open http://localhost:5173 in your browser. The dev server already binds to all interfaces for easy forwarding and mobile checks; bun run dev:host remains available as an explicit alternative.

See the Deployment Guide for build, preview, static hosting, and Cloudflare Worker instructions. That playbook also covers PR preview validation and multi-entry-point checks before merging.

Getting Started

What You’ll Need

  • A Modern Web Browser: Anything that supports WebGL should work (think Chrome, Firefox, Edge).
  • Microphone Access: A lot of these toys respond to sound, so you’ll want to enable that.
  • Touch Devices: Some toys are enhanced by touch, but that’s optional.

How to Play

Head to no.toil.fyi and jump right in. The toys respond to sound, touch, and other inputs to create a chill or stimulating experience. If you’d rather play locally, follow the steps in Local Setup to run the dev server and open the toys at http://localhost:5173.

Repository Layout

This project is organized so you can find the visuals, core utilities, and shared assets quickly:

  • assets/js/toys/: Individual toy implementations such as cube-wave.ts, spiral-burst.ts, and other sound-reactive scenes.
  • assets/js/core/: Rendering and input helpers used by multiple toys (for example, renderer initialization and audio analyzers).
  • assets/js/utils/: Small utility modules that support the core helpers and toys.
  • assets/css/: Shared styling for the various HTML entry points.
  • assets/data/: Static data files consumed by the toys.
  • tests/: Bun specs that validate core behaviors.
  • toy.html, brand.html, seary.html, and other HTML files: Entry points that load specific toys or collections of toys.

If you add a new toy, place the implementation in assets/js/toys/, register it in assets/js/toys-data.js, and make sure there’s an entry point (often toy.html?toy=<slug>) that can load it.

Toys in the Collection

Toy Description
3D Toy A twisting 3D tunnel that responds to sound.
Aurora Painter Paint flowing aurora ribbons that react to your microphone in layered waves.
Star Guitar Visualizer Visuals inspired by an iconic music video, synced to your music.
Pottery Wheel Sculptor Spin and shape a 3D clay vessel with smoothing, carving, and pinching tools.
Defrag Visualizer A nostalgic, sound-reactive visualizer evoking old defragmentation screens.
Evolutionary Weirdcore Watch surreal landscapes evolve with fractals and glitches that react to music.
Geometry Visualizer Push shifting geometric forms directly from live mic input with responsive controls.
Halo Visualizer Layered halos, particles, and shapes that respond to your music.
Multi-Capability Visualizer Shapes and lights move with both sound and device motion. (Requires WebGPU.)
Synesthetic Visualizer Blend audio and visuals into linked patterns.
Pattern Recognition Visualizer See patterns form dynamically in response to sound.
Terminal Word Grid A retro green text grid that pulses to audio and surfaces fresh words as you play.
SVG + Three.js Visualizer A hybrid visualizer blending 2D and 3D elements, reacting in real time.
Spectrograph A spectrograph that moves gently with your audio.
Interactive Word Cloud Speak and watch the word cloud react and shift with your voice.
Grid Visualizer Swap between cube waves and bouncing spheres without stopping the music.
Bubble Harmonics Translucent, audio-inflated bubbles that split into harmonics on high frequencies.
Cosmic Particles Jump between orbiting swirls and nebula fly-throughs with a single toggle.
Audio Light Show Swap shader styles and color palettes while lights ripple with your microphone input.
Spiral Burst Colorful spirals rotate and expand with every beat.
Rainbow Tunnel Fly through colorful rings that spin to your music.
Star Field A field of shimmering stars reacts to the beat.
Fractal Kite Garden Grow branching kite fractals that sway with mids and shimmer with crisp highs.
Tactile Sand Table Heightfield sand ripples that respond to bass, mids, and device tilt.
Bioluminescent Tidepools Sketch glowing currents that bloom with high-frequency sparkle from your music.

What’s in the Pipeline

Compatibility + onboarding

  • Issue: Some users with older or unsupported browsers/devices run into WebGL or WebGPU gating with unclear recovery steps.
  • Fix: Add a richer compatibility preflight with clear next steps, plus a “why this won’t run here” state that links to supported browsers and fallback toys. Include a no-mic path in the primary CTA flow so first-time users always see a successful start option.

Performance + quality controls

  • Issue: Heavier toys can stutter on mid-tier devices, which breaks the intended sensory flow.
  • Fix: Add a quality control panel (pixel ratio cap, particle density presets, and a “low motion” mode) that persists per device and defaults to a safe mid-tier profile. Provide a short “performance profile” explanation so users understand what each preset changes.

If you want to reduce GPU load on high-DPI screens without degrading visuals too much, pass a maxPixelRatio option to initRenderer (defaults to 2). This caps the renderer to Math.min(window.devicePixelRatio, maxPixelRatio), so setting maxPixelRatio to 1.5 or 1 can significantly cut per-frame work while retaining clarity.

Audio permission clarity

  • Issue: Users who deny mic access often get stuck or miss the demo audio escape hatch.
  • Fix: Expand the status copy and inline guidance so the demo audio path is always visible, clearly recommended when mic access is blocked, and explains how to re-enable permissions.

Mobile touch + gesture polish

  • Issue: Touch interactions feel inconsistent across devices, especially for multi-touch toys.
  • Fix: Improve touch handling, add clearer gesture hints, and confirm touch targets meet the minimum size for reliable taps. Add explicit “tap to start” feedback within 100ms so touch users see immediate response.

Local Setup

To play with the toys locally you’ll need to run them from a local web server. Opening the HTML files directly won’t work because the TypeScript modules and JSON fetches can’t load over file://. Here’s the quick setup:

  1. Clone the repository:

    git clone https://github.com/zz-plant/stims.git
    cd stims
  2. Use Bun 1.2+ (recorded in package.json).

  3. Install dependencies (Bun is required and the only locked flow):

    bun install

    The repository tracks bun.lock; pin installs with bun install --frozen-lockfile.

    Bun does not automatically run prepare scripts, so the repo includes a postinstall hook that installs Husky when npm_config_user_agent starts with bun. If that step fails for any reason, fall back to bun x husky install.

  4. Start the development server:

    bun run dev

Open http://localhost:5173 in your browser.

To serve a static build instead of the dev server, run:

bun run build
bun run preview

bun run serve:dist
# or use Python as a fallback
python3 -m http.server dist

The preview server hosts the contents of dist/ on port 4173 using Vite's --host flag, so you can load the build from other devices on your LAN if needed.

All JavaScript dependencies are installed via Bun and bundled locally with Vite, so everything works offline without hitting a CDN.

Troubleshooting

Microphone permissions

  • If the browser denied microphone access, re-allow it via the address bar/site settings and click the start button again. Hard-refreshing the page will re-trigger the prompt on most browsers.
  • Switch to demo audio if you keep seeing timeouts or “blocked” errors—the UI exposes a fallback button for a pre-mixed track so you can keep exploring without mic input.
  • Use the YouTube audio option on toy.html to paste a video link and capture tab audio when you want a shared playback source instead of live mic input.
  • For deeper debugging (including timeouts and permission-state checks), see the microphone flow helper in assets/js/core/microphone-flow.ts.

WebGPU gating

  • A WebGPU fallback warning means the browser lacked a compatible adapter or device at startup; toys will fall back to WebGL when possible.
  • To force a retry (for example, after toggling a browser flag or switching GPUs), refresh the page—WebGPU detection resets and will attempt the adapter/device handshake again.
  • WebGPU-only toys (like multi) won’t run without WebGPU; expect them to stay idle or prompt you to pick another toy until the capability probe succeeds. The renderer capability probe and fallback reasons live in assets/js/core/renderer-capabilities.ts if you need to trace the gating logic.

Dev-server hosting

  • Use bun run dev:host to bind the dev server to your LAN interface for mobile/device testing; the script mirrors the default dev command but with explicit hosting.
  • Check the served port in the terminal output (Vite defaults to 5173; preview uses 4173). Connect from other devices via http://<your-ip>:<port>.
  • Avoid loading toys over file://; the modules and JSON fetches require an HTTP server, so always use the dev server, preview server, or another static host.

Helpful Scripts (Bun-first)

  • bun run dev: Start the Vite development server for local exploration.
  • bun run dev:host: Start the Vite dev server bound to your LAN interface for quick mobile/device testing.
  • bun run build: Produce a production build in dist/.
  • bun run preview: Serve the production build locally (Vite preview with --host for LAN testing) to validate the output before deploying.
  • bun run test: Run the Bun-native test suite with the required --preload=./tests/setup.ts and --importmap=./tests/importmap.json flags applied. These load happy-dom globals and a Three.js stub so specs run headlessly.
  • bun run test:watch: Keep the Bun test runner active while you iterate on specs.
  • bun run lint: Check code quality with Biome.
  • bun run lint:fix: Apply Biome auto-fixes and formatting.
  • bun run format: Format files with Biome.
  • bun run format:check: Validate formatting with Biome.
  • bun run typecheck: Run TypeScript’s type checker without emitting files.
  • bun run typecheck:watch: Keep TypeScript checking in watch mode without emitting files.
  • bun run check: Run lint, typecheck, and tests in one go (handy before opening a PR).
  • bun run check:quick: Run lint and typecheck only (fast guardrail during iteration).
  • bun run scripts/scaffold-toy.ts: Interactive (or flag-driven) scaffolder that prompts for a slug/title/type, creates a starter module from docs/TOY_DEVELOPMENT.md, appends metadata to assets/js/toys-data.js, updates docs/TOY_SCRIPT_INDEX.md, and can optionally drop a minimal Bun spec. Pass flags such as --slug ripple-orb --title "Ripple Orb" --type module --with-test for non-interactive runs.
  • bun run serve:dist: Serve the dist/ build with Bun (preferred for local production previews).

Code of Conduct and Contributions

Please review our Code of Conduct before participating in the project. By contributing, you agree to uphold these community standards. A full contributing guide will live alongside the Code of Conduct so expectations are always clear.

Running Tests

This project uses the Bun test runner for its suite. To install dependencies and run the tests:

  1. Install dependencies:

    bun install
  2. Run the tests (via the script so required flags are applied):

    bun run test

    This script pins --preload=./tests/setup.ts and --importmap=./tests/importmap.json to load happy-dom globals and a Three.js stub for headless execution.

For quick iteration, use the watch mode:

bun run test:watch

Linting and Formatting

Before committing, run bun run lint to check code style and bun run format to automatically format your files with Biome. This keeps the project consistent.

Cloudflare Pages (Bun) build & deploy

Cloudflare Pages can build this project with Bun using the wrangler.toml in the repo root. Key settings:

  • Project name: stims (top-level name in wrangler.toml)
  • Build output directory: dist/ (set via pages_build_output_dir in wrangler.toml)
  • Build command: bun run build (set in the Pages UI under Settings → Builds & deployments → Build command; Pages rejects a [build] table in wrangler.toml)
  • Cloudflare Pages automatically detects the Bun version from the repo’s .bun-version file. As a fallback, you can set the BUN_VERSION environment variable (for example, BUN_VERSION=1.2.14) in your Pages project to ensure the hosted runtime matches local installs.
  • Enable Pages’ Bun runtime so the build runs under Bun instead of Node.
  • The compatibility_date in wrangler.toml keeps Pages aligned with the Cloudflare Workers API version.
  • Do not add a [pages] table in wrangler.toml; Cloudflare Pages expects project linkage to be configured in the dashboard.
  • If you prefer to omit the build command in the Pages UI, keep CF_PAGES=1 in the environment; scripts/postinstall.mjs will run bun run build during install to populate dist/ automatically. The script still only installs Husky when the installer is Bun, matching local behavior.

To verify the preview locally, run bun run build and inspect the generated dist/ folder; it matches the assets Pages will serve when the Bun runtime is enabled and the build output directory is dist/.

Contributing

If you run into a problem or want to propose an improvement, please use the GitHub issue templates so we get the details we need:

  • Bug reports: include clear reproduction steps, your environment, and what you expected to happen.
  • Feature requests: describe the problem you’re trying to solve, the behavior you’d like, and any alternatives you considered.

When opening a pull request, fill out the PR template with a summary of the change and the tests you ran. Check the lint and test boxes only if you executed those commands.


License

This project is released under the Unlicense, so you’re free to copy, modify, sell, and distribute it however you like. Do whatever you want with it—there are no restrictions.

Feel free to add more toys, tweak the visuals, or contribute in any way.

About

This project is a library of interactive webtoys designed to provide neurodiverse individuals with engaging and stimulating experiences. Each webtoy in the collection uses sound, visuals, and interactivity to create dynamic environments that can be customized and explored in a playful way

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •