{"id":17319087,"url":"https://github.com/kevinsqi/react-piano","last_synced_at":"2025-04-04T13:09:25.205Z","repository":{"id":37774069,"uuid":"131371006","full_name":"kevinsqi/react-piano","owner":"kevinsqi","description":"An interactive piano keyboard for React","archived":false,"fork":false,"pushed_at":"2023-02-02T06:15:06.000Z","size":8222,"stargazers_count":290,"open_issues_count":29,"forks_count":79,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-28T12:05:20.501Z","etag":null,"topics":["music","piano","react"],"latest_commit_sha":null,"homepage":"https://www.kevinqi.com/react-piano/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kevinsqi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-28T03:59:31.000Z","updated_at":"2025-03-15T14:16:26.000Z","dependencies_parsed_at":"2023-02-02T21:16:09.655Z","dependency_job_id":null,"html_url":"https://github.com/kevinsqi/react-piano","commit_stats":null,"previous_names":["iqnivek/react-piano"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsqi%2Freact-piano","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsqi%2Freact-piano/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsqi%2Freact-piano/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsqi%2Freact-piano/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kevinsqi","download_url":"https://codeload.github.com/kevinsqi/react-piano/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247181641,"owners_count":20897370,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["music","piano","react"],"created_at":"2024-10-15T13:22:19.909Z","updated_at":"2025-04-04T13:09:25.183Z","avatar_url":"https://github.com/kevinsqi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-piano\n\n[![npm version](https://img.shields.io/npm/v/react-piano.svg)](https://www.npmjs.com/package/react-piano)\n[![build status](https://travis-ci.com/kevinsqi/react-piano.svg?branch=master)](https://travis-ci.com/kevinsqi/react-piano)\n[![bundle size](https://img.shields.io/bundlephobia/min/react-piano.svg)](https://bundlephobia.com/result?p=react-piano)\n\nAn interactive piano keyboard for React. Supports custom sounds, touch/click/keyboard events, and fully configurable styling. [**Try it out on CodeSandbox**](https://codesandbox.io/s/7wq15pm1n1).\n\n\u003ca href=\"https://www.kevinqi.com/react-piano/\"\u003e\u003cimg width=\"600\" src=\"/demo/public/images/react-piano-screenshot.png\" alt=\"react-piano screenshot\" /\u003e\u003c/a\u003e\n\n## Installing\n\n```\nyarn add react-piano\n```\n\nAlternatively, you can download the UMD build from [unpkg](https://unpkg.com/react-piano).\n\n## Usage\n\nYou can view or fork the [**CodeSandbox demo**](https://codesandbox.io/s/7wq15pm1n1) to get a live version of the component in action.\n\nImport the component and styles:\n\n```jsx\nimport { Piano, KeyboardShortcuts, MidiNumbers } from 'react-piano';\nimport 'react-piano/dist/styles.css';\n```\n\nImporting CSS requires a CSS loader (if you're using create-react-app, this is already set up for you). If you don't have a CSS loader, you can alternatively copy the CSS file into your project from [src/styles.css](src/styles.css).\n\nThen to use the component:\n\n```jsx\nfunction App() {\n  const firstNote = MidiNumbers.fromNote('c3');\n  const lastNote = MidiNumbers.fromNote('f5');\n  const keyboardShortcuts = KeyboardShortcuts.create({\n    firstNote: firstNote,\n    lastNote: lastNote,\n    keyboardConfig: KeyboardShortcuts.HOME_ROW,\n  });\n\n  return (\n    \u003cPiano\n      noteRange={{ first: firstNote, last: lastNote }}\n      playNote={(midiNumber) =\u003e {\n        // Play a given note - see notes below\n      }}\n      stopNote={(midiNumber) =\u003e {\n        // Stop playing a given note - see notes below\n      }}\n      width={1000}\n      keyboardShortcuts={keyboardShortcuts}\n    /\u003e\n  );\n}\n```\n\n## Implementing audio playback\n\nreact-piano does not implement audio playback of each note, so you have to implement it with `playNote` and `stopNote` props. This gives you the ability to use any sounds you'd like with the rendered piano. The [react-piano demo page](https://www.kevinqi.com/react-piano/) uses @danigb's excellent [soundfont-player](https://github.com/danigb/soundfont-player) to play realistic-sounding soundfont samples. Take a look at the [**CodeSandbox demo**](https://codesandbox.io/s/7wq15pm1n1) to see how you can implement that yourself.\n\n## Props\n\n| Name | Type | Description |\n| ---- | ---- | ----------- |\n| `noteRange` | **Required** object | An object with format `{ first: 48, last: 77 }` where first and last are MIDI numbers that correspond to natural notes. You can use `MidiNumbers.NATURAL_MIDI_NUMBERS` to identify whether a number is a natural note or not. |\n| `playNote` | **Required** function | `(midiNumber) =\u003e void` function to play a note specified by MIDI number. |\n| `stopNote` | **Required** function | `(midiNumber) =\u003e void` function to stop playing a note. |\n| `width` | **Conditionally required** number | Width in pixels of the component. While this is not strictly required, if you omit it, the container around the `\u003cPiano\u003e` will need to have an explicit width and height in order to render correctly. |\n| `activeNotes` | Array of numbers | An array of MIDI numbers, e.g. `[44, 47, 54]`, which allows you to programmatically play notes on the piano. |\n| `keyWidthToHeight` | Number | Ratio of key width to height. Used to specify the dimensions of the piano key. |\n| `renderNoteLabel` | Function | `({ keyboardShortcut, midiNumber, isActive, isAccidental }) =\u003e node` function to render a label on piano keys that have keyboard shortcuts |\n| `className` | String | A className to add to the component. |\n| `disabled` | Boolean | Whether to show disabled state. Useful when audio sounds need to be asynchronously loaded. |\n| `keyboardShortcuts` | Array of object | An array of form `[{ key: 'a', midiNumber: 48 }, ...]`, where `key` is a `keyEvent.key` value. You can generate this using `KeyboardShortcuts.create`, or use your own method to generate it. You can omit it if you don't want to use keyboard shortcuts. **Note:** this shouldn't be generated inline in JSX because it can cause problems when diffing for shortcut changes. |\n| `onPlayNoteInput` | Function | `(midiNumber, { prevActiveNotes }) =\u003e void` function that fires whenever a play-note event is fired. Can use `prevActiveNotes` to record notes. |\n| `onStopNoteInput` | Function | `(midiNumber, { prevActiveNotes }) =\u003e void` function that fires whenever a stop-note event is fired. Can use `prevActiveNotes` to record notes. |\n\n## Recording/saving notes\n\nYou can \"record\" notes that are played on a `\u003cPiano\u003e` by using `onPlayNoteInput` or `onStopNoteInput`, and you can then play back the recording by using `activeNotes`. See [this CodeSandbox](https://codesandbox.io/s/l4jjvzmp47) which demonstrates how to set that up.\n\n\u003ca href=\"https://codesandbox.io/s/l4jjvzmp47\"\u003e\u003cimg width=\"300\" src=\"/demo/public/images/recording-demo.gif\" alt=\"demo of recording\" /\u003e\u003c/a\u003e\n\n## Customizing styles\n\nYou can customize many aspects of the piano using CSS. In javascript, you can override the base styles by creating your own set of overrides:\n\n```javascript\nimport 'react-piano/dist/styles.css';\nimport './customPianoStyles.css';  // import a set of overrides\n```\n\nIn the CSS file you can do things like:\n\n```css\n.ReactPiano__Key--active {\n  background: #f00;  /* Change the default active key color to bright red */\n}\n\n.ReactPiano__Key--accidental {\n  background: #000;  /* Change accidental keys to be completely black */\n}\n```\n\nSee [styles.css](/src/styles.css) for more detail on what styles can be customized.\n\n## Upgrading versions\n\nSee the [CHANGELOG](CHANGELOG.md) which contains migration guides for instructions on upgrading to each major version.\n\n## Browser compatibility\n\nTo support IE, you'll need to provide an `Array.find` polyfill.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinsqi%2Freact-piano","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinsqi%2Freact-piano","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinsqi%2Freact-piano/lists"}