Overview
The toy manifest (assets/data/toys.json) is the authoritative source for all toy metadata in the Stims library. This JSON file defines which toys exist, how they’re displayed, and their runtime requirements.
Manifest Structure
The manifest is a JSON array of toy objects:toys.json
Required Fields
Unique kebab-case identifier for the toy.Used in URLs (
toy.html?toy=<slug>) and as a programmatic key.Must be unique across all toys in the manifest.Example: "pocket-pulse", "spiral-burst", "aurora-painter"Human-readable display name for the toy.Shown in the toy library grid and selection UI.Example:
"Pocket Pulse", "Spiral Burst", "Aurora Painter"Brief description of what the toy does.Displayed in the toy card and detail views. Keep to 1-2 sentences.Example:
"A mobile-optimized pulse field that responds to audio and touch gestures."Path to the toy’s TypeScript module relative to project root.Must export a
start function matching ToyStartFunction.Pattern: "assets/js/toys/<slug>.ts"Example: "assets/js/toys/pocket-pulse.ts"Toy loading strategy.
"module": Loaded dynamically via JavaScript import"page": Loaded via iframe or dedicated HTML page
"module".Lifecycle Fields
Current lifecycle stage of the toy.
prototype: Experimental, fast iteration expectedfeatured: Curated, polished, high priority (5-8 toys max)archived: Stable but not actively promoted
Sort order for featured toys (lower = higher priority).Required when
lifecycleStage is "featured".Example: 1 (highest priority), 7 (lowest featured priority)Capability Fields
Audio and input capabilities the toy supports.
Whether the toy requires WebGPU to run.If
true, toy will only load in WebGPU-capable browsers.Whether the toy can fall back to WebGL if WebGPU is unavailable.Only meaningful when
requiresWebGPU is true.Discovery Fields
Mood tags for filtering and discovery.Common values:
"energetic", "calming", "dreamy", "cosmic", "immersive", "playful", "serene", "focus"Example: ["uplifting", "focus", "minimal"]Descriptive tags for categorization.Example:
["mobile", "pulses", "touch"], ["spirals", "burst", "gestural"]List of notable controls or interactions the toy exposes.Helps users understand what they can adjust.Example:
First-Run Experience Fields
Short hint shown to first-time users.Guides users to the “wow moment” quickly (1-2 sentences).Example:
"Tap Starter first, then pinch/rotate once if you want to shape the flow."Recommended starter preset for first-time users.
The single control that delivers the biggest impact.Highlighted in onboarding flows.Example:
"Glow strength", "Beat sensitivity"Suggested capability for best experience.Example:
"demoAudio" (for toys that work better with audio than silence)Complete Example
Here’s a fully annotated toy entry:spiral-burst-example.json
Generated Artifacts
Two files are generated fromtoys.json:
assets/js/data/toy-manifest.ts
TypeScript module with typed toy data:
toy-manifest.ts
public/toys.json
Public JSON copy for external tools and API consumers:
Validation
Run validation checks before committing:- JSON schema validity
- Slug uniqueness
- Module paths exist
- Featured toys have
featuredRank - Generated files match source
- HTML entry points exist for
type: "page"
Adding a Toy to the Manifest
Schema Reference
Minimal valid toy entry:minimal-toy.json
maximal-toy.json
Best Practices
Keep descriptions concise
Keep descriptions concise
Aim for 1-2 sentences that capture the core experience. Avoid marketing fluff.Good:
"Fly through colorful rings that spin to your music."Avoid: "Experience an amazing journey through a stunning visual wonderland of incredible rainbow rings!"Use consistent mood/tag vocabulary
Use consistent mood/tag vocabulary
Review existing toys to reuse common moods and tags. This improves discoverability.Common moods:
energetic, calming, dreamy, cosmic, immersive, playful, serene, focusLimit featured toys
Limit featured toys
Keep
featuredRank entries to 5-8 toys maximum. Rotate regularly (every 4-6 weeks).Test first-run hints
Test first-run hints
Show your toy to someone unfamiliar and observe their behavior. Update
firstRunHint and wowControl based on real usage.Troubleshooting
Toy doesn't appear in library
Toy doesn't appear in library
- Verify entry exists in
assets/data/toys.json - Run
bun run generate:toysto regenerate manifest - Check
slugmatches URL parameter:toy.html?toy=<slug> - Ensure
modulepath is correct and file exists
Check:toys fails
Check:toys fails
- Read the error message carefully
- If “drift detected”, run
bun run generate:toysand commit generated files - If “invalid JSON”, validate JSON syntax (use JSON linter)
- If “missing module”, create the toy file or fix the
modulepath
Featured toy not showing at top
Featured toy not showing at top
- Verify
lifecycleStage: "featured" - Verify
featuredRankis set (lower = higher priority) - Check that library UI uses featured sorting
Next Steps
Toy Development
Build and register new toys
Toy Interface
TypeScript interfaces for toys
Testing Toys
Write tests for toy behavior
Toy Lifecycle
Understand runtime behavior