Sound effects for the interface, performed live.
A div has never made a sound in its life. Foley is the library that gives it one — 28 cues synthesized in the browser from oscillators and filtered noise, no audio files anywhere. Add one attribute to a button and it finally clicks.
Testimonials · 100% synthesized, like everything else on this page
I removed the entire visual UI. The app is sound only now. Revenue tripled.a founder who has gone too far
We A/B tested ‘thock’. The B group unionized.a growth lead, under oath
My cat answers to ‘chime’ now. I no longer control this household.a cat owner, formerly in charge
The ‘denied’ thud healed something in me.someone’s therapist, confused but supportive
I played ‘complete’ at my wedding. Even the CI pipeline wept.a groom, deployed successfully
I put it on my smart fridge. ‘warning’ plays at 2am. I’ve lost ten pounds.an unverifiable success story
I removed the entire visual UI. The app is sound only now. Revenue tripled.a founder who has gone too far
We A/B tested ‘thock’. The B group unionized.a growth lead, under oath
My cat answers to ‘chime’ now. I no longer control this household.a cat owner, formerly in charge
The ‘denied’ thud healed something in me.someone’s therapist, confused but supportive
I played ‘complete’ at my wedding. Even the CI pipeline wept.a groom, deployed successfully
I put it on my smart fridge. ‘warning’ plays at 2am. I’ve lost ten pounds.an unverifiable success story
A palette, not a pile of clicks.
Each family has its own material — noise for touch, glides for motion, harmonics for news. Click any cue, or just start typing: every cue is mapped to a key.
Keyboard mode: press the key on each cue — 1–0, Q–P, A–K. The ⤓ on a cue exports it as a 16-bit .wav, rendered with your current transpose and space — ready for Figma, video, or native apps.
Hear it where it lives.
Sounds audition differently on a marketing grid than on a real control. These components use the same attributes you'd ship.
Two-part press
data-foley-press · data-foley-releaseDown and up are different sounds, so a click feels like a real mechanism. Hold it — the release waits for you.
Toggle
data-foley-toggleA click and a clack. On and off are siblings, not twins, so your ears know the state without looking.
Hover ticks
data-foley-hover="tick"A grain of feedback as the pointer crosses each option. Sub-decibel by default; enable “play on hover” in the inspector to hear it here too.
Typing
data-foley-type="thock"A soft mechanical thock per keystroke, and a flourish on Enter. Try writing a sentence.
Notifications
play("ping" | "chime" | "error")Programmatic cues for things the user didn't click. Each raises a real toast.
Progress
play("rise") → play("complete")Loading ticks while work happens, a rise as it finishes, then the arrival chord. Start an upload.
Stepper
data-foley-click="tick" + pitchThe same tick, re-pitched with the count, so quantity has a contour. Overshoot the limits to hear “denied”.
Slider
play("tick", { pitch })Detent ticks across the track that rise in pitch with the value — the sound of a thumb wheel.
Not quite your sound? Change it.
Shape any cue with four plain dials — no synthesis degree required — and hear every change live. Export .wav or JSON, share a design as a link, or apply it site-wide as a sound set your app loads in one line. The full layer editor is a click away.
Space replays. Exports honor your transpose, space, and theme — and designs live in the URL, so copy the link to share one.
Install, mark up, bind. Done.
Foley ships as one ES module. The declarative layer covers the common cases; the imperative API covers everything else.
Install
$ npm install @foleyjs/core
Mark up and bind
<!-- one attribute per behavior -->
<button data-foley-press data-foley-release>Save</button>
<a data-foley-hover="tick">Docs</a>
<button data-foley-toggle>Dark mode</button>
<input data-foley-type="thock">
<!-- and things nobody clicked -->
<div data-foley-enter="bubble">Saved</div>
import { bind, observe, play, set } from "@foleyjs/core";
bind(); // wires every data-foley-*
observe(); // …and elements appearing or changing state
set({ volume: 0.7, // 0 – 1
transpose: 0, // semitones, ±12
space: 0.2, // reverb send
theme: "glass" }); // a name — or your sound set object
play("complete"); // any of the 28 cues
set({ theme: brandSet }); // load your identity — build one in the designer ↓
play("tick", { pitch: 4, volume: 0.3 });
const wav = await toWav("chime"); // Blob — offline render
In React or Vue
// npm install @foleyjs/react
import { useFoley } from "@foleyjs/react";
function App() {
const { play } = useFoley({ volume: 0.7 });
return <button onClick={() => play("success")}>
Save
</button>;
}
// npm install @foleyjs/vue
import { FoleyPlugin } from "@foleyjs/vue";
app.use(FoleyPlugin, { theme: "soft" });
<!-- then in any template -->
<button v-foley="'success'">Save</button>
<a v-foley:hover="'tick'">Docs</a>