Open-source interface sound effects for every product state.
UI SFX is a tiny semantic sound system for web apps, mobile apps, SaaS, education, media, and games. Call success, drop, or level-up once, then switch the whole product between twelve coherent sonic personalities without changing interaction code.
Preview every sound, cue, and sonic personality at uisfx.com →
- 78 semantic cues across 13 interaction categories
- 12 complete sound packs
- 936 original sounds in both MP3 and Ogg
- 72 brief one-shots and 6 seamless state loops
- 5.18 MB for every MP3 or 3.82 MB for every higher-fidelity Ogg
- Dry event-bound textures, clean silent tails, and automated similarity checks
- 12.0 kB compressed Web Audio runtime with zero dependencies
- MIT code, CC0 audio, and CC0 sound-pack art
npm install uisfxWant a coding agent to wire the whole product? Copy the production-ready implementation prompt or give it the agent integration guide. The prompt covers semantic cue mapping, loop cleanup, autoplay constraints, mute preferences, accessibility, and verification.
import { createUISFX } from 'uisfx'
const ui = createUISFX({ pack: 'minimal', preferences: {} })
// Call from the first trusted pointer or keyboard action.
await ui.unlock()
saveButton.addEventListener('click', () => {
ui.play('success')
})
// Loops continue until their interface state resolves.
const processing = ui.play('processing')
processing?.stop()
// Change personality without changing product logic.
ui.setPack('arcade')The player defaults to eight voices, deduplicates loops, restarts repeated outcomes, rate-limits high-frequency cues, and moves active loops into a newly selected pack without invalidating their handles.
UI SFX creates its AudioContext lazily. Call unlock() from the first trusted interaction, then it synthesizes deterministic recipes locally and caches rendered buffers without fetching audio files.
| Pack | Character | Good fit |
|---|---|---|
minimal |
Dry, precise, almost invisible | Productivity, SaaS, system UI |
soft |
Rounded, warm, reassuring | Mobile, wellness, friendly SaaS |
glass |
Bright, crystalline, premium | Media, finance, luxury products |
arcade |
Chunky pixels and cheerful voltage | Games, streaks, gamified learning |
mechanical |
Switches, relays, firm detents | Devtools, hardware, industrial UI |
organic |
Wood, water, breath, small stones | Education, kids, calm games |
dreamy |
Airy blooms and slow sparkle | Creative tools, wellness, ambient apps |
scifi |
Clean holographic pings and restrained digital shimmer | AI tools, spatial UI, futuristic games |
rubber |
Tactile elastic taps with a quick friendly rebound | Kids, playful mobile, casual games |
cinematic |
Deep impacts and polished tails | Premium media and dramatic moments |
studio |
Tactile editing precision with warm restraint | Film, audio, and AI creative tools |
zen |
Paper folds, soft brush, warm wood, and quiet chimes | Calm tools, wellness, reading, and focus |
Every pack implements every cue. The complete semantic contract lives in the taxonomy.
Use one-shots for discrete outcomes such as a selection, drop, purchase, success, warning, or error. UI SFX ships 72 of them, each short enough to preserve momentum.
Use loops for visible ongoing states. The six loop cues are loading, processing, recording, connecting, scanning, and streaming. Stop them as soon as the state succeeds, fails, or is cancelled.
const recording = ui.play('recording')
stopButton.addEventListener('click', () => {
recording?.stop()
ui.play('complete')
})import { bindUISFX } from 'uisfx'
const { player, unbind } = bindUISFX()<a data-uisfx-hover="hover">Documentation</a>
<button data-uisfx-press="press" data-uisfx-release="release">Hold me</button>
<button data-uisfx="success" data-uisfx-pack="soft">Save</button>Call unbind() when a client-rendered view is destroyed.
The package includes sounds/{pack}/{cue}.mp3 and sounds/{pack}/{cue}.ogg for React Native, Swift, Kotlin, Unity, Godot, video, and any environment without Web Audio.
import successUrl from 'uisfx/sounds/soft/success.mp3?url'
const success = new Audio(successUrl)
await success.play()The uisfx/manifest export describes each exact path, byte size, rendered duration, channel count, loop flag, default volume, cue, category, and pack.
Sound should reinforce visible feedback, never replace it.
- Give people a persistent mute setting and respect their device volume.
- Never make audio the only distinction between success, warning, and error.
- Keep hover feedback quiet or disable it in dense interfaces.
- Start audio only after an explicit interaction.
- Debounce high-frequency notifications and stop loops with their visible state.
ui.setEnabled(false)
ui.setVolume(0.5)
ui.stopAll()preferences: {} stores pack, volume, and enabled state in localStorage. A custom storage adapter supports native shells and application preference stores. preload() yields between cues and accepts an AbortSignal, so preparing sounds does not monopolize one browser task.
The checked-in sound files are reproducible from deterministic synthesis recipes.
npm install
npm run generate
npm run checkNode 22.20 or later, Chrome or Chromium, and ffmpeg are required. The full quality gate regenerates every file, typechecks, tests, builds the package and showcase, and validates audio size, decoded peaks, tail silence, loop timing, seam continuity, pairwise similarity, runtime size, browser unlocking, cooperative preload, and preference restoration. Recipe changes also follow the listening conformance protocol.
Names such as soft-pop-03.mp3 make every product invent its own meaning. UI SFX separates intent from timbre:
product event -> semantic cue -> sound pack -> recipe or asset
upload done complete glass complete.ogg
lesson done complete arcade complete.ogg
The product event stays stable while the sound system evolves independently.
UI SFX stays free, open, and maintained thanks to its sponsors. Sponsor UI SFX on GitHub.
Become the first Premier Sponsor.
Become the first Sponsor.
Issues and focused pull requests are welcome. Read CONTRIBUTING.md before changing the taxonomy or synthesis recipes; a new cue must work in all twelve packs and keep a visible or haptic counterpart.
The TypeScript code is MIT licensed. The procedurally generated audio library is dedicated to the public domain under CC0 1.0, as are the sound-pack illustrations.