npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

uisfx

v0.4.0

Published

Open-source semantic UI sound effects for web, mobile, SaaS, and games.

Readme

UI SFX: open-source interface sound effects

A zero-dependency semantic sound system for web apps, mobile apps, SaaS, education, media, and games. Call success once, then change the whole product's sonic personality without changing its logic.

Install

npm install uisfx

Want a coding agent to implement it across an existing product? Use the copy-ready implementation prompt or the complete agent integration guide. Machine-readable cue and pack documentation starts at /llms.txt.

Try it in 30 seconds

import { createUISFX } from 'uisfx'

const ui = createUISFX({
  pack: 'minimal',
  volume: 0.7,
  preferences: { key: 'my-product:sound' },
})

// Call from the first trusted pointer or keyboard action.
await ui.unlock()

saveButton.addEventListener('click', async () => {
  const processing = ui.play('processing')

  try {
    await saveChanges()
    processing?.stop()
    ui.play('success')
  } catch {
    processing?.stop()
    ui.play('error')
  }
})

The AudioContext is created lazily. Sounds are synthesized and cached locally from deterministic recipes, so the runtime fetches no audio files. The player bounds polyphony, deduplicates loops, rate-limits frequent cues, and restarts repeated outcomes instead of layering them.

What ships

  • 78 semantic cues across 13 interaction categories
  • 12 interchangeable sound packs
  • 936 portable sounds in both MP3 and Ogg
  • 72 brief one-shots and 6 seamless state loops
  • Dry, event-bound textures with clean silent tails
  • A 12.0 kB compressed Web Audio runtime
  • Zero runtime dependencies
  • MIT code and CC0 audio

One API, twelve sonic personalities

Every pack implements every cue. Product logic stays stable while the sound design changes instantly.

ui.play('complete')

ui.setPack('arcade')
ui.play('complete') // Same meaning, entirely different feel.

An active loop moves to the new pack automatically and keeps the same stoppable handle.

| 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 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 |

Hear every pack on the interactive website →

Common UI patterns

Discrete outcomes

Use one-shots for meaningful state changes, not decoration.

ui.play('toggle-on')
ui.play('add-to-cart')
ui.play('purchase')
ui.play('level-up')

Long-running states

Loop cues continue until the visible interface state resolves. Always stop them on success, failure, or cancellation.

const recording = ui.play('recording')

// When recording ends:
recording?.stop()
ui.play('complete')

The six built-in loops are loading, processing, recording, connecting, scanning, and streaming.

Packs, volume, and mute preferences

ui.setPack('studio')
ui.setVolume(0.5)
ui.setEnabled(userPreferences.soundEnabled)

ui.stopAll()
await ui.destroy()

Pass preferences: {} to persist pack, volume, and enabled state in localStorage. Supply a storage adapter for React Native, Electron, tests, or another persistence layer.

Playback policy and preload

The default policy allows eight concurrent voices, reuses duplicate loops, restarts duplicate one-shots, and applies short cooldowns to high-frequency cues. Override deliberately when an interaction needs real overlap.

ui.play('reaction', { retrigger: 'overlap' })
ui.play('hover', { cooldownMs: 0 })

const controller = new AbortController()
await ui.preload(['hover', 'select', 'success'], { signal: controller.signal })
controller.abort()

Preload yields between cues so it does not synthesize an entire pack in one browser task.

Add sound with HTML

Use declarative bindings when data attributes fit your app better than event handlers.

import { bindUISFX } from 'uisfx'

const { player, unbind } = bindUISFX(document, { pack: 'soft' })

// Later, when the view is destroyed:
unbind()
await player.destroy()
<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 changes</button>

Touch pointers automatically skip hover sounds.

Use the audio files anywhere

The package includes every sound as MP3 and Ogg for native apps, games, video, and environments without Web Audio.

import successUrl from 'uisfx/sounds/soft/success.mp3?url'

const success = new Audio(successUrl)
await success.play()

Asset paths follow sounds/{pack}/{cue}.{mp3|ogg}. The uisfx/manifest export describes each path, size, rendered duration, channel count, loop flag, default volume, cue, category, and pack.

API at a glance

| API | Purpose | | --- | --- | | createUISFX(options) | Create a player with preferences, a pack, volume, enabled state, voice limit, cooldown, or custom AudioContext | | player.unlock() | Resume Web Audio from a trusted pointer or keyboard action | | player.play(cue, options) | Play a typed semantic cue and receive stop() plus an ended promise | | player.preload(cues?, options?) | Cooperatively render selected cues with optional cancellation | | player.setPack(pack) | Change personality and migrate active loops without changing their handles | | player.setVolume(value) | Set master volume between 0 and 1 | | player.setEnabled(value) | Persist the sound preference and stop active audio when disabled | | bindUISFX(root?, options?) | Wire semantic cues to HTML data attributes | | cueNames, packNames | Build typed selectors, settings, and sound browsers |

TypeScript exports CueName, PackName, UISFXPlayer, PlayingSFX, and the complete CUES, PACKS, and CATEGORIES catalogs.

Accessibility

Sound should reinforce visible feedback, never replace it.

  • Give people a persistent mute setting and respect 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 frequent notifications and stop loops with their visible state.

Documentation and license

The TypeScript code is MIT licensed. The generated audio library is dedicated to the public domain under CC0 1.0.