copy-to-clipboard vs clipboard vs vue-clipboard2 vs clipboard-polyfill vs react-copy-to-clipboard
Copying Text to Clipboard in Web Applications
copy-to-clipboardclipboardvue-clipboard2clipboard-polyfillreact-copy-to-clipboardSimilar Packages:
Copying Text to Clipboard in Web Applications

clipboard, clipboard-polyfill, copy-to-clipboard, react-copy-to-clipboard, and vue-clipboard2 are JavaScript libraries that simplify copying text to the system clipboard across different browsers and environments. They abstract away the complexities of the native document.execCommand('copy') API (now deprecated) and the modern asynchronous navigator.clipboard.writeText() API, handling fallbacks, permissions, and browser inconsistencies. These packages differ significantly in scope: some are framework-agnostic utilities (clipboard, clipboard-polyfill, copy-to-clipboard), while others provide React or Vue-specific bindings (react-copy-to-clipboard, vue-clipboard2).

Npm Package Weekly Downloads Trend
3 Years
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
copy-to-clipboard8,254,5861,38715.1 kB47-MIT
clipboard2,218,24934,18194.5 kB13-MIT
vue-clipboard2103,4411,766-374 years agoMIT
clipboard-polyfill0924404 kB9a year agoMIT
react-copy-to-clipboard02,37140.6 kB24-MIT

Copying Text to Clipboard: A Practical Guide for Frontend Engineers

Copying text to the clipboard seems simple, but browser inconsistencies, security restrictions, and the deprecation of execCommand make it surprisingly tricky. The five packages under review tackle this problem differently — from DOM-centric helpers to modern promise-based utilities and framework wrappers. Let’s cut through the noise and see which tool fits your architecture.

⚠️ Critical Maintenance Note

Before diving in, note that vue-clipboard2 is officially deprecated. Its GitHub repository and npm page state: "This package is no longer maintained. Please use @soerenmartius/vue3-clipboard instead." Do not use it in new projects. We’ll still cover it briefly for legacy context, but treat it as a cautionary tale.

🧩 Core Approach: How Each Package Solves the Problem

clipboard: Declarative DOM Binding

clipboard attaches copy behavior directly to HTML elements using data attributes. You never call a function — just add attributes like data-clipboard-text to a button, and the library handles the rest on click.

<!-- HTML setup -->
<button id="btn" data-clipboard-text="Hello World">Copy</button>
// JS initialization
import ClipboardJS from 'clipboard';
new ClipboardJS('#btn');

It listens for clicks, extracts text from attributes, and attempts to copy. Works only in response to user gestures (required by browser security).

clipboard-polyfill: Standards-Based Promise API

clipboard-polyfill provides a clean, modern interface aligned with the official navigator.clipboard API. It returns promises and handles fallbacks internally.

import { writeText } from 'clipboard-polyfill';

async function copyHandler() {
  try {
    await writeText('Hello World');
    console.log('Copied!');
  } catch (err) {
    console.error('Failed to copy', err);
  }
}

It automatically uses navigator.clipboard.writeText() when available and falls back to legacy methods (with proper sandboxing) in older browsers. Also works in non-DOM environments like Web Workers.

copy-to-clipboard: Minimalist Function

copy-to-clipboard exports a single synchronous function that tries to copy text and returns a boolean success status.

import copy from 'copy-to-clipboard';

function handleClick() {
  const success = copy('Hello World');
  if (success) {
    console.log('Copied!');
  }
}

No promises, no callbacks — just fire-and-forget. Internally, it uses a temporary textarea element to perform the copy operation.

react-copy-to-clipboard: React Component Wrapper

This package wraps copy-to-clipboard in a React component. You render it with text and onCopy props, and it clones its child with extra props.

import { CopyToClipboard } from 'react-copy-to-clipboard';

function App() {
  return (
    <CopyToClipboard text="Hello World" onCopy={() => console.log('Copied!')}>
      <button>Copy</button>
    </CopyToClipboard>
  );
}

Under the hood, it calls copy-to-clipboard when the child element is clicked.

vue-clipboard2: Deprecated Vue Directive

Historically, this provided a Vue directive for copying:

// ❌ DO NOT USE — deprecated
import VueClipboard from 'vue-clipboard2';
Vue.use(VueClipboard);
<template>
  <button v-clipboard:copy="'Hello World'">Copy</button>
</template>

But again — this package is unmaintained and should be avoided.

🔒 Security and Browser Support Realities

All these libraries must contend with two hard constraints:

  1. User gesture requirement: Browsers only allow clipboard writes during direct user actions (click, keypress). No library can bypass this.
  2. Permission model: Modern browsers (Chrome, Edge) require permission for navigator.clipboard outside of secure contexts.

Here’s how they handle it:

  • clipboard: Only works on click events. Fails silently in unsupported contexts.
  • clipboard-polyfill: Uses the standard permission API when possible. Throws clear errors when blocked, and includes a shouldShowPermissionPrompt() helper.
  • copy-to-clipboard: Tries to copy immediately. Returns false if blocked, but gives no details why.
  • react-copy-to-clipboard: Inherits copy-to-clipboard’s behavior — no error context.
  • vue-clipboard2: Same as clipboard — gesture-bound with minimal error feedback.

🧪 Programmatic vs Declarative Usage

Your choice depends heavily on whether you prefer programmatic control (calling functions from JS) or declarative binding (attaching behavior via HTML/JSX).

When you need programmatic control:

  • Use clipboard-polyfill if you want modern promise handling and detailed error reporting.
  • Use copy-to-clipboard if you just need a fire-and-forget boolean result.
// clipboard-polyfill: async/await with error details
try {
  await writeText(text);
} catch (err) {
  if (err.name === 'NotAllowedError') {
    showPermissionGuide();
  }
}

// copy-to-clipboard: simple boolean
if (!copy(text)) {
  alert('Copy failed — try manually');
}

When you prefer declarative markup:

  • Use clipboard for vanilla JS/jQuery apps with static buttons.
  • Use react-copy-to-clipboard if you’re in React and like component composition.
<!-- clipboard: pure HTML -->
<button data-clipboard-text="...">Copy</button>
{/* react-copy-to-clipboard: JSX */}
<CopyToClipboard text="..."><button>Copy</button></CopyToClipboard>

🌐 Framework Integration Trade-offs

  • React users: react-copy-to-clipboard feels natural but adds an extra dependency layer. Many teams skip it and call clipboard-polyfill directly inside event handlers for more control.
// Common React pattern without wrapper
function CopyButton({ text }) {
  const handleCopy = async () => {
    try {
      await writeText(text);
      // update UI state, etc.
    } catch (err) { /* handle */ }
  };
  return <button onClick={handleCopy}>Copy</button>;
}
  • Vue users: Since vue-clipboard2 is dead, the best path is using clipboard-polyfill directly in methods:
// Vue 3 Composition API example
import { writeText } from 'clipboard-polyfill';

export default {
  methods: {
    async copyText(text) {
      try {
        await writeText(text);
        // handle success
      } catch (err) {
        // handle error
      }
    }
  }
};
  • Framework-agnostic apps: clipboard-polyfill is the safest bet for new projects. It’s actively maintained, follows web standards, and works everywhere from SPAs to Web Workers.

📋 Feature Comparison Summary

PackageAPI StyleAsync SupportError DetailsFramework-SpecificMaintenance Status
clipboardDeclarative DOMNone✅ Active
clipboard-polyfillProgrammatic✅ PromiseNone✅ Active
copy-to-clipboardProgrammatic❌ (boolean)None✅ Active
react-copy-to-clipboardReact ComponentReact✅ Active
vue-clipboard2Vue DirectiveVue 2Deprecated

💡 Final Recommendation

  • For new projects: Use clipboard-polyfill. It’s the most future-proof, gives you detailed error handling, and aligns with web standards. Call it directly from your framework’s event handlers.
  • For simple utility needs: If you don’t care about error details and just want a one-liner, copy-to-clipboard is fine.
  • For legacy jQuery-style apps: clipboard works well if you’re already using data attributes extensively.
  • For React: Skip react-copy-to-clipboard unless you strongly prefer its component API — most teams gain more flexibility by using clipboard-polyfill directly.
  • For Vue: Avoid vue-clipboard2 entirely. Use clipboard-polyfill in methods or composables.

Remember: no library can bypass browser security. Always design your UI to handle copy failures gracefully — show a fallback tooltip, highlight the text for manual selection, or guide users through permission prompts when needed.

How to Choose: copy-to-clipboard vs clipboard vs vue-clipboard2 vs clipboard-polyfill vs react-copy-to-clipboard
  • copy-to-clipboard:

    Choose copy-to-clipboard if you want the simplest possible function-based API for programmatic copying without any DOM coupling. It’s a good fit for utility-heavy applications where you trigger copies from JavaScript logic rather than HTML attributes, and you prefer minimal abstraction over feature richness.

  • clipboard:

    Choose clipboard if you need a DOM-focused utility that binds copy behavior directly to HTML elements via data attributes, and your app uses buttons or other interactive elements where declarative markup is preferred. It’s ideal for simple static sites or jQuery-style apps but requires manual DOM setup and doesn’t support programmatic copying outside of user-triggered events.

  • vue-clipboard2:

    Avoid vue-clipboard2 in new projects — it is officially deprecated as of 2021 and unmaintained. The author recommends migrating to @soerenmartius/vue3-clipboard for Vue 3 or using a framework-agnostic alternative like clipboard-polyfill. Do not use it for production applications due to lack of updates and security patches.

  • clipboard-polyfill:

    Choose clipboard-polyfill if you require a lightweight, modern, framework-agnostic solution that prioritizes standards compliance and works reliably in both browser and non-browser environments (like Web Workers). It supports both promise-based and callback APIs, handles permission prompts gracefully, and actively maintains compatibility with the latest web standards.

  • react-copy-to-clipboard:

    Choose react-copy-to-clipboard only if you’re working in a React codebase and prefer a component-based API that integrates naturally with JSX. Note that it wraps copy-to-clipboard under the hood, so it inherits its simplicity but adds React-specific ergonomics like render props or children-as-function patterns.

README for copy-to-clipboard

Copy to clipboard Build Status

Simple module exposing copy function that will try to use execCommand with fallback to IE-specific clipboardData interface and finally, resort to usual prompt with proper text content and message.

If you are building using Electron, use their API.

Example

import copy from 'copy-to-clipboard';

copy('Text');

// Copy with options
copy('Text', {
  debug: true,
  message: 'Press #{key} to copy',
});

API

copy(text: string, options: object): boolean — tries to copy text to clipboard. Returns true if no additional keystrokes were required from user (so, execCommand, IE's clipboardData worked) or false.

ValueDefaultNotes
options.debugfalseBoolean. Optional. Enable output to console.
options.messageCopy to clipboard: #{key}, EnterString. Optional. Prompt message. *
options.format"text/html"String. Optional. Set the MIME type of what you want to copy as. Use text/html to copy as HTML, text/plain to avoid inherited styles showing when pasted into rich text editor.
options.onCopynullfunction onCopy(clipboardData: object): void. Optional. Receives the clipboardData element for adding custom behavior such as additional formats

* all occurrences of #{key} are replaced with ⌘+C for macOS/iOS users, and Ctrl+C otherwise.

Browser support

Works everywhere where prompt* is available. Works best (i.e. without additional keystrokes) in Chrome, FF, Safari 10+, and, supposedly, IE/Edge.

Note: does not work on some older iOS devices.
* – even though Safari 8 has prompt, you cannot specify prefilled content for prompt modal – thus it doesn't work as expected.

Installation

  • Can be used as npm package and then leveraged using commonjs bundler/loader:
npm i --save copy-to-clipboard
  • Can be utilized using wzrd.in. Add following script to your page:
<script src="https://wzrd.in/standalone/copy-to-clipboard@latest" async></script>

You will have window.copyToClipboard exposed for you to use.

UI components based on this package:

See also:

Running Tests

This project has some automated tests, that will run using nightwatch on top of selenium.

npm i
npm test

Typescript

This library has built-in Typescript definitions.

import * as copy from 'copy-to-clipboard';