
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Tiny vanilla TypeScript library for playing UI notification sounds via the Web Audio API — no audio files, no dependencies.
Tiny vanilla TypeScript library for UI notification sounds — pure Web Audio API, no audio files, zero dependencies.
| earcon | Howler.js | Tone.js | ZzFX | |
|---|---|---|---|---|
| No audio files | ✅ | ❌ | ✅ | ✅ |
| Notification-specific API | ✅ | ❌ | ❌ | ❌ |
| TypeScript native | ✅ | via @types | ✅ | ❌ |
| Zero dependencies | ✅ | ✅ | ❌ | ✅ |
| Bundle size | ~3 KB | 318 KB | 5.4 MB | <1 KB |
| Semantic sound names | ✅ | ❌ | ❌ | ❌ |
| Customizable | ✅ | ✅ | ✅ | ✅ |
An earcon is an auditory icon — a short, meaningful sound signal used in user interfaces. This library provides a curated set of them, generated entirely in code.
npm install earcons
<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/earcons/dist/earcon.min.global.js"></script>
<!-- unpkg -->
<script src="https://unpkg.com/earcons/dist/earcon.min.global.js"></script>
All functions are available under the global Earcon object:
<button onclick="Earcon.playSuccess()">✅</button>
<button onclick="Earcon.playError()">❌</button>
<script>
// or
Earcon.earcon("notification", { volume: 0.8 });
</script>
import { playSuccess, playError, playWarning } from "earcons";
// Defaults — medium variant, volume 0.5
await playSuccess();
await playError();
await playWarning();
Each function accepts an optional SoundOptions object.
import {
playSuccess,
playError,
playWarning,
playNotification,
playClick,
playInfo,
} from "earcons";
await playSuccess();
await playError({ variant: "long", volume: 0.8 });
await playWarning({ variant: "short" });
await playNotification({ pitch: 7 }); // +7 semitones
await playClick({ variant: "short" });
await playInfo({ volume: 0.3 });
earcon() — play by nameimport { earcon } from "earcons";
await earcon("success");
await earcon("error", { variant: "long" });
Built-in sound names: success · error · warning · notification · click · info
import { registerSound, earcon } from "earcons";
import type { SoundPreset } from "earcons";
const chirp: SoundPreset = (_variant, _pitch) => ({
name: "chirp",
duration: 0.15,
notes: [
{ frequency: 1200, duration: 0.07, startAt: 0, waveShape: "sine" },
{ frequency: 1600, duration: 0.08, startAt: 0.07, waveShape: "sine" },
],
});
registerSound("chirp", chirp);
await earcon("chirp");
SoundOptions| Option | Type | Default | Description |
|---|---|---|---|
volume | number | 0.5 | Master volume, 0–1 |
variant | "short" | "medium" | "long" | "medium" | Duration variant |
pitch | number | 0 | Semitone offset (±) |
audioContext | AudioContext | shared singleton | Bring your own context |
onEnded | () => void | — | Called when the sound finishes |
import { closeAudioContext, setAudioContext } from "earcons";
// Provide your own AudioContext (useful in frameworks)
const myCtx = new AudioContext();
setAudioContext(myCtx);
// Tear down (e.g. on unmount)
await closeAudioContext();
| Name | Waveform | Character |
|---|---|---|
success | sine | Ascending major triad — bright, positive |
error | sawtooth | Descending tritone — harsh, attention-grabbing |
warning | triangle | Flat then descending minor second — cautious |
notification | sine | Soft descending two-tone ding — neutral |
click | sine | Very short transient — tactile UI feedback |
info | sine | Single soft tone — informational, non-intrusive |
toggle | triangle | Short tactile pop — on/off switch |
delete | sawtooth | Rapid descending — destructive action |
message | sine | Soft high ping — incoming chat message |
upload | sine | Ascending sweep — file sent |
download | sine | Descending sweep — file received |
| Name | Waveform | Character |
|---|---|---|
eightBit | square | Chiptune arpeggio — retro 8-bit 🕹️ |
police | sawtooth | Alternating wee-woo siren 🚨 |
coin | square | Classic pickup coin 🪙 |
boing | sine | Comedy spring drop 🎪 |
Any browser that supports the Web Audio API (all modern browsers since 2014).
Autoplay policy: earcon automatically calls
AudioContext.resume()before playing. Make sure you call a play function in response to a user gesture on first load, or the browser may suppress audio.
MIT
FAQs
Tiny vanilla TypeScript library for playing UI notification sounds via the Web Audio API — no audio files, no dependencies.
We found that earcons demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.