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

node-playsound

v0.3.0

Published

Play WAV, MP3, and FLAC files from Node.js on Windows, macOS, and Linux. Concurrent playback, seeking, and volume control with zero runtime dependencies.

Readme

node-playsound

npm version Build and verify License: CC0-1.0

Play local audio from Node.js with one import. TypeScript, ESM, and zero runtime npm dependencies. WAV, MP3, and FLAC decoding is bundled for Windows, macOS, and Linux—no external player, install-time compiler, or extra download.

Play your first sound

Requires Node.js 22 or newer and a working audio output.

npm install node-playsound

Save this as play.mjs, put sound.mp3 in your current directory, and run node play.mjs:

import { play } from 'node-playsound';

await play('./sound.mp3').finished;

play() returns a handle immediately; file validation and playback start asynchronously. Observe finished on every playback. It resolves to 'ended' or 'stopped', or rejects with an AudioError if playback fails.

Control a playback

import { play } from 'node-playsound';

const playback = play('./music.flac', { volume: 0.5 });
playback.volume = 0.2;
playback.seek(80); // Absolute seconds from the beginning.
await playback.finished;

Call await playback.stop() to stop early and wait for cleanup. A playback is one run of a file; seeking and volume affect only that run. Seeking is asynchronous, and seeking at or past the known duration ends playback. See the complete seeking contract.

Pause an individual playback with playback.pause() and continue with playback.resume(). Seeking while paused keeps it paused. To inspect progress, await playback.getTiming() returns { position, duration } in seconds, or null if playback has settled. Duration can also be null when unknown. Position means PCM consumed by the mixer, not what is currently audible. Pause and timing contracts explain acknowledgment, query failures, and resource ownership.

Play a sound more than once

import { sound } from 'node-playsound';

const notification = sound('./notification.wav', { volume: 0.3 });
await Promise.all([
  notification.play().finished,
  notification.play({ volume: 0.5 }).finished,
]);

The plays overlap and finish independently. A Sound retains a path and settings; it does not preload the file. Each call reopens it and creates a new playback. The audio engine is reused between nearby plays.

Own playback in an application

Use a Player when a service, window, worker, or test needs to stop all of its audio together:

import { Player } from 'node-playsound';

const audio = new Player();
try {
  await audio.play(new URL('./sound.mp3', import.meta.url)).finished;
} finally {
  await audio.close();
}

close() stops the player's pending and active sounds, waits for cleanup, and permanently closes that player. Other players are independent. For system audio controls, new Player({ applicationName: 'My app' }) supplies an application label; the default is your entry-point filename. Windows WASAPI and Linux PulseAudio/PipeWire use it. macOS still identifies the isolated helper process. Platform details explain the distinction. Pass an AbortSignal to play() to tie a sound to an operation's cancellation. Recipes cover cancellation, background notifications, paths, and shutdown.

Support

| System | Architectures | Audio output | | --- | --- | --- | | Windows 10/11 | x64; ARM64 on Windows 11 | System audio, normally WASAPI | | macOS 13+ | Intel and Apple Silicon | Core Audio | | Linux, glibc 2.35+ | x64 and ARM64 | PulseAudio/PipeWire compatibility or ALSA |

Only regular local files and file: URL objects are accepted. HTTP streams, AAC/M4A, Ogg, browsers, Alpine/musl, and 32-bit systems are not supported. Linux needs its system audio libraries and an accessible audio session; headless containers often have neither. Troubleshooting covers missing devices, paths, codecs, and bundled deployments.

Playback streams through bounded buffers. There is no unbounded decoded cache or permanent background process. The default limit is 64 pending/active plays per player; reaching it fails the new play rather than queuing it.

Volume is linear gain from 0 to 1; overlapping loud recordings can clip. Completion means the engine consumed the audio, so a little audio may remain in device buffers. Gapless transitions, and sample-accurate scheduling are not provided.

Documentation

CC0-1.0. Bundled miniaudio uses its public-domain option; see third-party notices.