Library / SDK
sindresorhus/copy-text-to-clipboard avatar
sindresorhus/copy-text-to-clipboard

copy-text-to-clipboard is 0.2 kB of copy behaviour for the browser

Copy text to the clipboard in modern browsers (0.2 kB)

1,047 stars220 forksJavaScriptMIT

At a glance

What is it?
copy-text-to-clipboard is a single function browser module that copies text to the clipboard and reports whether the copy worked, small enough that its size is the selling point. It exists for the case where the native clipboard API is unavailable, and it costs you a user gesture to work at all.
Who is it for?
Adopt copy-text-to-clipboard when you need a copy button on a page served over plain HTTP, on an internal tool, or in any build where the 3.4 kB of clipboard.js is more than you want to ship. Do not adopt it in a new project that already runs on HTTPS, where navigator.clipboard.writeText is the better call.
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?
Yes. The repository last received commits 35 days 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The whole module is measured in fractions of a kilobyte

The project states its own size in the title line and repeats it in the comparison section: this module is 0.2 kB, while clipboard.js is listed at 3.4 kB. That framing tells you what kind of library this is. It is not a clipboard manager, not a format handler and not a permission system. It is a single function that does one thing, and the number attached to it is the argument for using it. The audience is front-end developers who need a copy button, a copy link action or a copy-to-clipboard affordance somewhere in a page, and who would rather not pull a dependency whose size rivals the component they are building. The repository shape backs that up: index.js and index.d.ts are the two files the package publishes, with a readme, an example.html page, a type test file and the usual repository metadata around them. The package is MIT licensed, marked free of side effects, and published as an ES module, so a bundler can drop it entirely if the code path is not reached.

One function, one boolean, no configuration surface to speak of

The API section is short enough to quote. The function is copy(text, options?), it copies the given text to the clipboard, and it returns a boolean saying whether it succeeded. That return value is the part worth pausing on, because a copy operation that fails silently is a common complaint about clipboard code, and here the caller is told. The options argument is an object with a single documented property, target, whose type is HTMLElement and whose default is document.body. So the entire configuration surface is one DOM node, and its purpose is narrow: it is where the temporary, behind-the-scenes textarea used during the copy is appended. Everything else, the text to copy and where to put the working element, is settled by the call site. For a TypeScript consumer the types ship alongside the code, and the package is exercised by xo for linting and by tsd for the type assertions, so the published signature is the one the tests check.

Every call has to sit inside a real user gesture

The API documentation states that the function must be called in response to a user gesture event, like click or keyup. That single rule is the defining constraint of the library, and it decides where the call can live in your code. A copy button handler is the easy case. A copy action fired from a promise resolution, a setTimeout, a fetch callback or a websocket message is not, and browsers block clipboard writes that are not traceable to the user. This is why the alternative approach discussed later in the README mentions the native API in the first place, since the modern Clipboard API imposes the same kind of gesture requirement on its write method. The practical effect for an adopter is that copy-text-to-clipboard cannot be used to put data on the clipboard from background work, however convenient that would be, and any design that wants to do that needs the user's click to be the trigger somewhere in the chain. The README does not document a fallback path for a missed gesture beyond the boolean return, so the return value is the signal to branch on.

The target option exists for the modal case

The one option in the API is not cosmetic. By default the temporary textarea is appended to document.body, and the target property lets you name a different element to append it to. The README gives the reason: in cases where you need to stay within a focus trap, like in a modal. If the copy button lives inside a dialog that traps focus, an element attached to the body sits outside the trap, and some browsers refuse to select or copy from a node outside the focused context. Pointing target at the modal or at a wrapper inside it keeps the working element inside the same focus scope as the control the user pressed. This is a detail that only matters if you have already hit it, which is the nature of a 0.2 kB library: it does one job, and the job has one escape hatch for the situation where the default does not work. If your page has no focus traps, the default of document.body is fine and the option can be left alone.

Against navigator.clipboard.writeText, the difference is secure context

The README does not bury this. In the install section it points readers at navigator.clipboard.writeText as the thing to consider using directly, and then states the reason this package still exists: the native API requires a secure context, meaning HTTPS, while this package works in non-secure contexts too. That is the whole argument, and it is narrower than it first appears. On an HTTPS deployment, the native method does the same job with no dependency at all, so a new project has little reason to add this module. Where it earns its place is a page served over plain HTTP, an internal tool on a network without certificates, a local development server, or any deployment where a mixed-content or certificate problem stands between the page and the native API. The second difference is size and shape, one function at 0.2 kB against clipboard.js at 3.4 kB, which matters in a bundle budget but not in a desktop application. For a Node-side clipboard, the README points to a separate project, clipboardy, rather than pretending this module covers it.

Installing it and wiring a copy button

Installation is a single npm command, and the package is published as an ES module, so the import is a default import from the package name.

sh
npm install copy-text-to-clipboard
js
import copy from 'copy-text-to-clipboard';

A button then calls the function from its click handler, and the boolean it returns tells you whether the text made it to the clipboard. The example page in the repository, example.html, shows the same pattern wired to a real control. In an application the shape to copy is usually not a constant but a value assembled at click time, for instance a URL built from the current route, and because the call must be in a user gesture the handler is the natural place to assemble it. If the control lives inside a modal, pass the modal element as the target option so the temporary textarea is appended inside the focus trap rather than to the body. The package is published with an engines field of node >=12 and marked as having no side effects, so an import that is never reached costs nothing in the final bundle.

What the package does not do for you

Two boundaries are worth stating plainly. First, this is a browser module. It is written against DOM elements, a temporary textarea and the browser clipboard, and the README points Node users to clipboardy for the system clipboard in Node.js, which is a different mechanism in a different environment. Second, the module does not manage what is on the clipboard, does not read back what it wrote, does not offer formatting and does not prompt. It accepts a string and reports success. The gesture rule described earlier is the constraint most likely to surprise, since a copy triggered by a background event is a natural design and an illegal call site. The package metadata also shows the shape of the maintenance model: the source lives in index.js, the types in index.d.ts, and the test script runs xo, while tsd is available as a dev dependency for the type tests. Releases include v3.2.2 on 2025-09-23 and v3.2.1 on 2025-09-08, and the last push to the repository was on 2026-09-18. The licence is MIT, which places no obligation on a product that uses the module.

Editorial conclusion

Adopt copy-text-to-clipboard when you need a copy button on a page served over plain HTTP, on an internal tool, or in any build where the 3.4 kB of clipboard.js is more than you want to ship. Do not adopt it in a new project that already runs on HTTPS, where navigator.clipboard.writeText is the better call. Verify first that every copy() call site sits inside a real click or keyup handler, since the module only works in response to a user gesture, and decide where the temporary textarea should be appended when the button lives inside a modal.

Frequently asked questions

How do I install copy-text-to-clipboard?

Install it from npm with npm install copy-text-to-clipboard. The package is published as an ES module, so it is imported as a default import from copy-text-to-clipboard.

When does copy-text-to-clipboard not copy anything?

The copy only happens when the function is called in response to a user gesture event such as click or keyup. A call from a timeout or a promise callback is not tied to a gesture, and the function returns a boolean telling you whether the copy succeeded.

Why use this package instead of navigator.clipboard.writeText?

The native API requires a secure context, which means HTTPS. This package works in non-secure contexts as well, so it is the option for pages served over plain HTTP, and it is 0.2 kB against the 3.4 kB listed for clipboard.js.

What is the target option for in copy-text-to-clipboard?

The target option names the DOM element that the temporary, behind-the-scenes textarea is appended to, and it defaults to document.body. It exists for cases where you need to stay within a focus trap, such as a modal.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sindresorhus/copy-text-to-clipboard on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sindresorhus-copy-text-to-clipboard.svg)](https://hysenlabs.com/projects/sindresorhus-copy-text-to-clipboard)

Was this useful?