react-copy-to-clipboard: a twenty-line component that hides three browser fallbacks
Copy-to-clipboard React component
At a glance
- What is it?
- A single-dependency wrapper around copy-to-clipboard that renders no markup of its own, wraps one child, and reports success through a callback.
- Who is it for?
- The interesting part of react-copy-to-clipboard is not the component, it is the fallback chain underneath it. Copying to a clipboard has been awkward in browsers for long enough that a reliable answer involves a modern asynchronous path, a document.execCommand fallback, an old IE clipboardData interface, and finally a prompt asking the user to press Ctrl+C.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 7 months ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A wrapper that renders nothing and captures clicks on its child
The design is stated early and plainly: CopyToClipboard is a simple wrapping component, it does not render any tags, so it requires the only child element to be present, which will be used to capture clicks.
That constraint is the API. There is no button prop, no variant, no className. You supply one element, the component attaches its click handler to it, and that element remains fully yours. It can be a span, a button, an anchor, anything that accepts a click.
<CopyToClipboard text="Hello!">
<button>Copy to clipboard</button>
</CopyToClipboard>The README's own example demonstrates the flexibility by wrapping both a span and a button in the same render, both bound to the same text and the same callback, which makes the point that the wrapper is agnostic about what it wraps.
There are only three runtime dependencies and one of them is the component library this exists to wrap: `copy-to-clipboard` at ^3.3.3 and `prop-types` at ^15.8.1, with React itself declared as a peer dependency of >=15.3.0. A peer range that old is a deliberate signal that the component has no React version coupling, which is consistent with it rendering no markup of its own.
The callback takes two arguments and the second one is the useful one
The onCopy prop has a signature worth knowing precisely, because a component that cannot report failure is much less useful than one that can. It is called as `onCopy(text, result)`, where result is a boolean that returns true if the copy succeeded and false otherwise.
The README lists onCopy as optional, which is accurate: it is a notification, not a requirement. But treating it as decoration is a mistake, since it is the only way to know whether the clipboard operation actually worked.
<CopyToClipboard text={this.state.value}
onCopy={() => this.setState({copied: true})}>
<button>Copy to clipboard with button</button>
</CopyToClipboard>Note what that example does with the result: it ignores it. The state variable it sets is called copied, which reads as a success flag, but the example's arrow function takes no parameters, so it would flip to true whether or not the copy worked. Reading the second argument makes the demo's own variable name honest, and the README states the contract plainly:
onCopy(text, result)`result (bool)`: Returns `true` if copied successfully, else `false`.
The other two props are the text itself, a required string, and an options object passed straight through to copy-to-clipboard, typed as a shape covering debug, message and format.
The fallback chain is the real specification
One line in the README carries most of the project's value, and it is easy to skim past. The plan is to try execCommand with a fallback to the IE specific clipboardData interface, and finally a fallback to a simple prompt with proper text content and a 'Copy to clipboard: Ctrl+C, Enter' message.
That is a three-stage degradation, and it maps onto the history of browser clipboard APIs. The modern asynchronous clipboard API is permission-gated and requires a secure context, which is not available in every situation a user might click. `document.execCommand('copy')` works far more broadly but is deprecated. The IE `clipboardData` interface is a legacy path. And the final fallback simply asks the user to press Ctrl+C themselves, with the text pre-filled in a prompt so the gesture is easy.
Two consequences follow. First, the operation can fail and the component will tell you so through that boolean, which is why the callback matters. Second, in the last-resort case the user is shown a prompt, which is a visible artefact you should think about before shipping it in a polished interface.
There is also a hard browser constraint underneath all of this: writing to the clipboard only works from a user gesture. Any design where a copy happens on a timer, after a fetch resolves, or inside a programmatic sequence will not behave the way the component name suggests.
An example written for React 17 in a project that claims React 18 support
The README's usage example ends by creating a div, appending it to the body and calling `ReactDOM.render`:
const appRoot = document.createElement('div');
document.body.appendChild(appRoot);
ReactDOM.render(<App />, appRoot);That call was removed from React in version 18. Meanwhile the v5.1.0 release notes, published in April 2022, say the example code was updated to use React 18 and Strict mode.
So the repository contains two statements about the same example file and they disagree. The release note describes work that the current README does not show. The most likely explanation is mundane: a later change to the README or the example reverted the entry point to the older API, or the release note described a directory that the current tree no longer reflects.
What this means practically is that you should not treat the README snippet as a working modern React 18 mount. Under React 18 the equivalent is `createRoot`, and the component itself does not care either way, because it renders no markup and only needs a child to attach a handler to. The peer dependency range of >=15.3.0 remains the accurate statement of what React versions the component works with, and that range is genuinely broad.
It is a fair illustration of a general hazard with library READMEs: the prose is maintained more often than the example code, and a release note describing a fix is not proof the fix is still in the file.
Small active project, unusual lint tooling, 15 open issues
The last release is v5.1.1, published on 2026-03-07, and the repository's recorded push carries the same date. The release body for that version says only that it is a build update, referencing pull request 204. The two before it are v5.1.0 and v5.0.4, both from April 2022, where v5.1.0 added a React 18 peer dependency and v5.0.4 added a reference to another project to the README.
So the pattern is a quiet four years followed by a build refresh. For a component this small that is a reasonable place to be: the browser behaviour it depends on is stable, and the API is unlikely to need breaking changes.
The tooling has moved more than the component has. The lint script runs `biome check .` rather than eslint, and there is a `biome.json` in the tree. The test script is unusually direct, `node test/Component-test.js`, so the suite is a plain Node script rather than a test framework runner. The README documents that pair directly:
# to run Biome check
yarn lint
# to run tests
yarn testThe package manager is Yarn with a `.yarn/` directory and a `.yarnrc.yml`, and the scripts show separate lib, dist and min bundles, a webpack config directory and depcheck wired into a dependency check target. The rest of the tree is small and conventional: `src/`, `test/`, `example/`, `.babelrc` and `.depcheckrc`.
With 15 open issues and 2368 stars, the ratio suggests a component that does one thing and does not generate much discussion. The author field in the manifest names a person and an email address, which is uncommon enough in a package with this many installs to be worth noticing: this is a maintained single-author project rather than a team effort, and it is licensed MIT with that stated in both the manifest and the README.
Editorial conclusion
The interesting part of react-copy-to-clipboard is not the component, it is the fallback chain underneath it. Copying to a clipboard has been awkward in browsers for long enough that a reliable answer involves a modern asynchronous path, a document.execCommand fallback, an old IE clipboardData interface, and finally a prompt asking the user to press Ctrl+C. All of that is delegated to copy-to-clipboard, and this package's value is having tested it once. What it does not do is render, style, or manage your button state, and it will not copy without a user gesture. If your application already depends on this, there is nothing to migrate. If you are choosing a clipboard dependency, read the fallback description in this README, because that paragraph is the real specification.
Frequently asked questions
How do I know whether react-copy-to-clipboard actually copied the text?
Use the second argument of the onCopy callback, which is a boolean that is true on success and false on failure. The signature is onCopy(text, result). The README's own example takes no parameters, which sets the flag regardless of outcome, so read the result if the state matters.
Can I use any element as the child of CopyToClipboard?
Yes, as long as it accepts clicks. The component renders no tags of its own and attaches the handler to the single child element you supply, so a span, a button or an anchor all work. The README demonstrates both a span and a button wrapping the same text.
What happens when the browser refuses to copy to the clipboard?
There is a chain of fallbacks. The library tries execCommand first, then the IE specific clipboardData interface, and finally shows a prompt containing the text with a message telling the user to press Ctrl+C and Enter. The onCopy callback's boolean reports whether the copy succeeded.
Which React versions does react-copy-to-clipboard support?
The peer dependency is react at >=15.3.0, which is accurate because the component renders no markup of its own and only needs a clickable child. React is a peer dependency rather than a bundled one, so you install it yourself; the README also notes that npm@3 users must install peer dependencies manually.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nkbt-react-copy-to-clipboard)