# Roadmap · zvuk

zvuk v1.14.1 · MIT · https://zvuk.schmooky.dev/roadmap/

What's next in zvuk. Public, prioritised, sized.

Public roadmap

# What's next

An honest punch list of what would make zvuk better, ordered by impact. No promises on dates. This is intent, not a release schedule. PRs welcome on anything sized small.

Status

Shipped in v1.14.1

Runtime + lazy AudioContext, mixer + buses + click-free fades, FX chain (compressor / filter / reverb / ducker / pitch-preserving stretch), spatializer (2D + 3D), parameters, snapshots, concurrency policies, codec ladder, voice jitter, scheduler.

Not on this roadmap

Framework adapters (React/Vue/Svelte). Visual node-graph editor. WASM DSP. Native bridge for React Native or Electron-specific paths. HRTF spatializer beyond stock PannerNode HRTF. These remain out-of-scope for the foreseeable.

v1.1 → v1.12

## Recently shipped

Roughly one feature per minor release. Most recent first.

1.  ✓ Snapshot blend (v1.12)
    
    engine.blendSnapshots(a, b, t) snaps the mix to a linear interpolation between two captured snapshots. Wire it through a Parameter and you get continuous "calm ↔ combat" or "menu ↔ game" mix automation driven by one knob. The Wwise primitive the roadmap pointed at.
    
    [related: /concepts/snapshot/](/concepts/snapshot/)
    
    medium
    
2.  ✓ Music source — stinger → loop → outro (v1.8)
    
    engine.loadMusic(name, { intro, loop, outro }) + MusicVoice.skipToOutro({ at: "loop-end" | "now" }). The pattern every casino slot, action game, and rhythm game uses for combat/win/menu music. Click-free at the loop boundary via loopCrossfade.
    
    [related: /concepts/music/](/concepts/music/)
    
    large
    
3.  ✓ voice.level() + bus.meter() — live amplitude readouts (v1.7)
    
    Lazy AnalyserNode taps. Drove rhythm-metronome example, mixer dashboards, and the real "quietest" voice-stealing strategy.
    
    [related: /concepts/bus/](/concepts/bus/)
    
    medium
    
4.  ✓ engine.preload(items, { signal, concurrency, onProgress }) (v1.6)
    
    First-class bulk loader for loading screens. Per-item progress, concurrency cap, aggregated PreloadError.
    
    [related: /guides/loading/#first-class-preloader-engine-preload](/guides/loading/#first-class-preloader-engine-preload)
    
    medium
    
5.  ✓ loopCrossfade play option (v1.5)
    
    Off-by-default equal-power crossfade at the loop boundary so non-zero-crossing music regions don't click.
    
    [related: /concepts/voice/#loop-crossfade-off-by-default](/concepts/voice/#loop-crossfade-off-by-default)
    
    medium
    
6.  ✓ Audit cleanups (v1.4)
    
    Real Filter bypass, dead BankNotLoadedError removed, honest 'quietest' fallback warning until per-voice metering shipped in v1.7.
    
    small
    
7.  ✓ createEngine({ resolveAsset }) hook (v1.3)
    
    Adopt buffers from Pixi Assets.cache, IndexedDB, or any external asset system without zvuk depending on it.
    
    [related: /guides/asset-resolution/](/guides/asset-resolution/)
    
    medium
    
8.  ✓ tickSource injection + autoPauseOnHidden (v1.2)
    
    Wire the scheduler into a host's render loop (Pixi/GSAP) instead of setTimeout, and opt out of visibility-pause for music players.
    
    [related: /guides/runtime-timing/](/guides/runtime-timing/)
    
    medium
    
9.  ✓ Click-free voice.stop() (v1.1)
    
    Tiny gain ramp before source.stop() suppresses the click that fires when buffers are cut mid-waveform.
    
    small
    

v1.0.0

## First stable release

The headline change was a unit normalization across the public API.

1.  ✓ Normalize all time-valued options to seconds
    
    Fades, crossfades, snapshot apply, Ducker/Sidechain attack/release — all in seconds now. Field renames: ms → duration, fadeMs → fade. Aligns with Web Audio (currentTime, AudioParam scheduling) and removes the \*1000/÷1000 bug class. Breaking; migration table in CHANGELOG.
    
    [related: /changelog/#v1.0.0](/changelog/#v1.0.0)
    
    medium
    

Shipped

## Roadmap tier sweep

A roadmap-tier sweep covering every actionable item from Tiers 1 through 4, end to end. Framework adapters remain out of scope.

1.  ✓ Bus sends / aux
    
    engine.bus(src).send(engine.bus(dest), { amount }) routes a copy of one bus into another (e.g. a verb-only bus).
    
    [related: /concepts/bus/](/concepts/bus/)
    
    medium
    
2.  ✓ Solo + busGroup
    
    bus.solo() mutes everyone else; engine.busGroup(name, \[...buses\]) addresses several buses at once.
    
    [related: /concepts/bus/](/concepts/bus/)
    
    small
    
3.  ✓ engine.masterMeter()
    
    Live RMS + peak on the master output — same shape as bus.meter() / voice.level().
    
    small
    
4.  ✓ Spatializer distance config
    
    refDistance / maxDistance / rolloffFactor / distanceModel per voice, tunable live via the Spatializer set\* methods.
    
    [related: /concepts/spatializer/](/concepts/spatializer/)
    
    medium
    
5.  ✓ Variants helper
    
    engine.loadVariants(name, urls) + engine.variants(name).play() with random / no-repeat / shuffle-bag strategies.
    
    small
    
6.  ✓ play({ fadeIn })
    
    Fade a voice up from 0 over fadeIn seconds at start — the dual of the click-free stop fade.
    
    [related: /concepts/voice/](/concepts/voice/)
    
    small
    
7.  ✓ engine.unloadSound(name, { evictBuffer })
    
    Drop a sound and evict its decoded buffer from the LRU — for hot-swapping themes.
    
    small
    
8.  ✓ Branded bus / sound names
    
    createEngine({ buses }) infers the bus-name union so engine.bus("typo") fails at compile time.
    
    medium
    
9.  ✓ createEngine({ latencyHint })
    
    Maps to AudioContext latencyHint — 'interactive' for reactive game audio, 'playback' for music players.
    
    small
    
10.  ✓ Live spatializer control on Voice
     
     voice.spatializer.setPan / setPosition during playback.
     
     [related: /concepts/spatializer/](/concepts/spatializer/)
     
     small
     
11.  ✓ Voice pause / resume
     
     voice.pause() / resume() with offset retention.
     
     [related: /concepts/voice/](/concepts/voice/)
     
     small
     
12.  ✓ Live voice.playbackRate setter
     
     voice.setPlaybackRate(rate, { duration, curve }) with optional ramp.
     
     [related: /concepts/voice/](/concepts/voice/)
     
     small
     
13.  ✓ Audio sprites
     
     engine.loadSprite(name, url, regions) → engine.sprite(name).play(region).
     
     medium
     
14.  ✓ Stream source
     
     engine.loadStream(name, url) — HTMLAudioElement + MediaElementAudioSource for long media.
     
     medium
     
15.  ✓ Loudness normalization on load
     
     loadSound(..., { normalize: true }) — RMS target with peak ceiling.
     
     medium
     
16.  ✓ Better error messages
     
     BusNotFoundError("sxf"; did you mean "sfx").
     
     [related: /concepts/engine/](/concepts/engine/)
     
     small
     
17.  ✓ Realtime stretch via AudioWorklet
     
     ensureStretchWorklet(ctx) + createStretchWorkletNode(ctx) with live \`stretch\` AudioParam.
     
     [related: /fx/pitch/](/fx/pitch/)
     
     large
     
18.  ✓ Master limiter
     
     master.limiter config wires a fast-attack DynamicsCompressor on master out.
     
     [related: /concepts/mixer/](/concepts/mixer/)
     
     small
     
19.  ✓ Crossfade helper
     
     engine.crossfade(from, to, { duration, curve }) — equal-power by default.
     
     small
     
20.  ✓ Examples directory
     
     Vanilla deployable apps under /examples/ (slot-machine, match-3, fps-footsteps).
     
     large
     
21.  ✓ npx zvuk transcode
     
     ffmpeg ladder (webm/opus + m4a/aac) packaged as a CLI.
     
     [related: /guides/asset-formats/](/guides/asset-formats/)
     
     small
     
22.  ✓ npx zvuk gen bank.json
     
     Typed sound-name module emitted from a manifest.
     
     medium
     
23.  ✓ Bench suite
     
     vitest bench/ for voice spawn, decode + cache, fade drift.
     
     medium
     
24.  ✓ Auto-generated /api/ from TypeDoc
     
     TypeDoc JSON → Astro pages, regenerated each build.
     
     medium
     
25.  ✓ Pagefind search
     
     ⌘K modal indexed at build time.
     
     small
     
26.  ✓ Auto changelog page
     
     /changelog/ built from .changeset/\*.md.
     
     small
     
27.  ✓ OG images
     
     Per-page social cards via astro-og-canvas.
     
     small
     

Tier 3

## For "library people adopt"

Not just "library that works."

1.  Per-voice FX
    
    FX inserts are bus-level today. No way to put a flanger on one voice without dedicating a bus to it.
    
    large
    

Tier 4

## Polish

Can wait, but on the list.

1.  engine.recordOutput()
    
    Capture the master to a Blob via MediaStreamDestination. Casino "show-mode" replays — niche but specific.
    
    medium
    
2.  Android focus / interruption tracking
    
    iOS 'interrupted' state is handled. Android focus loss is similar and we currently lean on visibilitychange only.
    
    medium
    

Contribute

### Pick one and PR it

Items sized small are usually a single file plus a test. Items sized medium typically touch 2–4 files. Items sized large are worth opening an issue first to align on shape.

[Open an issue](https://github.com/schmooky/zvuk/issues/new)
