How to play sound effects in React mobile web applications

Today I went searching for a JavaScript module that plays sound effects when a user taps on a React component. I didn't see any open-source packages that worked well for mobile browsers. Here's a simple home-made solution:


<SoundEffect audioUrl="">
   <button>Click me for sound!</button>


import React from 'react';
import PropTypes from 'prop-types';

// Ensures that we don't replace existing onClick handlers
// on the wrapped child components
const wrapFn = (targetFn, wrapper) => (...args) => {
  return targetFn(...args);
const emptyFn = () => {};

* A container that plays a sound effect when the user interacts
* with any of its child components.
export class SoundEffect extends React.Component {
  static propTypes = {
    listenerType: PropTypes.oneOf(['onClick', 'onMouseDown']),
    onError: PropTypes.func
  static defaultProps = {
    listenerType: 'onClick',
    onError: console.error.bind(console)
  constructor(props) {
    this.playSound = this.playSound.bind(this);
  playSound() {
    try {
      const audio = document.createElement('audio');
      audio.src = this.props.audioUrl;;
    } catch (error) {
  render() {
    const { listenerType, children } = this.props;
    /* An alternative would be rendering <audio>. Though this is more declarative,
    it requires adding an additional wrapper in the DOM, and playback will stop
    when SoundEffect unmounts. It's a trade-off... */
      child => React.cloneElement(child, {
        [listenerType]: wrapFn(child.props.onClick || emptyFn, this.playSound)

If you prefer to implement SoundEffect through a higher-order component (HOC), use this code:

export const withSound = (soundOptions = {}) => (Component) => (props) => (
  <SoundEffect {...soundOptions}>
    <Component {...this.props} />

For example:

const MyButton = () => (<button>Click here</button>);
export default withSound({ audioUrl: 'example.mp3'})(MyButton)
Cody Romano

Cody Romano

Software engineer @Airbnb. Formerly @Amazon. This is my personal site for side projects and ramblings.

Read More