clipboardy vs clipboard vs copy-paste vs clipboard-polyfill
Client-Side Clipboard Interaction in Web Applications
clipboardyclipboardcopy-pasteclipboard-polyfillSimilar Packages:
Client-Side Clipboard Interaction in Web Applications

clipboard, clipboard-polyfill, clipboardy, and copy-paste are npm packages that provide programmatic access to the system clipboard in JavaScript environments. They address the challenge of copying text (and sometimes other data) to the user's clipboard across different browsers and execution contexts — from browser-based frontend apps to Node.js scripts. Each package targets distinct runtime environments and use cases: some focus exclusively on modern browser APIs with graceful fallbacks, others support both browser and Node.js, while one is strictly for Node.js command-line or server-side usage. Understanding their scope, API design, and environment compatibility is essential for making the right architectural choice.

Npm Package Weekly Downloads Trend
3 Years
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
clipboardy6,199,6741,886920 kB17a day agoMIT
clipboard2,117,36634,18294.5 kB13-MIT
copy-paste439,44244617 kB85 months ago-
clipboard-polyfill155,662924404 kB9a year agoMIT

Client-Side Clipboard Interaction: clipboard vs clipboard-polyfill vs clipboardy vs copy-paste

Copying and pasting data programmatically seems simple, but browser security restrictions, API inconsistencies, and environment differences make it surprisingly tricky. The four packages under review each tackle this problem differently — some for browsers, some for Node.js, and one that’s past its prime. Let’s cut through the noise and see which tool fits your real-world scenario.

🖥️ Runtime Environment: Browser vs Node.js

This is the first and most critical filter. Not all clipboard packages work everywhere.

clipboard and clipboard-polyfill are browser-only. They rely on DOM APIs like document.execCommand() or navigator.clipboard and will throw errors if used in Node.js.

clipboardy is Node.js-only. It uses platform-specific commands (pbcopy/pbpaste on macOS, clip/powershell on Windows, xclip/xsel on Linux) via child processes. It cannot run in a browser.

copy-paste was also designed for Node.js, but it’s deprecated — more on that later.

💡 Rule of thumb: If your code runs in a browser tab → use clipboard or clipboard-polyfill. If it runs in a terminal or Electron main process → use clipboardy.

✂️ Basic Copy Operation: How Each Package Writes Text

Let’s look at the simplest common task: copying a string to the clipboard.

clipboard (browser)

Designed as a minimal wrapper. You create an instance tied to a DOM element (usually a button), and it handles the rest:

import ClipboardJS from 'clipboard';

// Attach to a button with data-clipboard-text
const btn = document.querySelector('#copy-btn');
const clipboard = new ClipboardJS(btn);

// Or specify text dynamically
const clipboard2 = new ClipboardJS('.btn', {
  text: () => 'Hello, clipboard!'
});

clipboard2.on('success', e => {
  console.log('Copied:', e.text);
  e.clearSelection();
});

It automatically chooses between navigator.clipboard.writeText() (modern) and document.execCommand('copy') (legacy).

clipboard-polyfill (browser)

Provides a function-based API that mimics the standard Clipboard API, with built-in polyfill logic:

import { writeText } from 'clipboard-polyfill';

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

// Must be called in response to a user gesture (e.g., click handler)
document.getElementById('copy-btn').addEventListener('click', copyToClipboard);

Under the hood, it handles permission requests, iframe sandboxing, and fallbacks seamlessly.

clipboardy (Node.js)

Simple promise-based API for scripts:

import { write } from 'clipboardy';

await write('Hello, clipboard!');
console.log('Text copied to system clipboard');

Works in any Node.js context — great for CLI tools that need to output something directly to the clipboard.

copy-paste (Node.js, deprecated)

Used a callback-style API:

// ⚠️ DO NOT USE — shown for reference only
const copyPaste = require('copy-paste');

copyPaste.copy('Hello, clipboard!', () => {
  console.log('Copied');
});

But this package is no longer maintained and fails on newer OS versions due to changes in clipboard utilities.

🔍 Reading from the Clipboard

Not all packages support reading clipboard content — and for good reason: browsers restrict read access for security.

  • clipboard: ❌ Does not support reading. Only writing.
  • clipboard-polyfill: ✅ Supports reading via readText(), but only in secure contexts (HTTPS) and only when triggered by a user gesture. Falls back gracefully where unsupported.
import { readText } from 'clipboard-polyfill';

async function readFromClipboard() {
  try {
    const text = await readText();
    console.log('Pasted:', text);
  } catch (err) {
    console.error('Read failed:', err);
  }
}
  • clipboardy: ✅ Full read/write support in Node.js:
import { read, write } from 'clipboardy';

await write('test');
const content = await read(); // returns 'test'
  • copy-paste: Supported reading via paste(), but again — deprecated and unreliable.

🛡️ Security and User Gesture Requirements

Browsers require clipboard write operations to occur within a user-initiated event (like a click). All browser packages respect this, but they handle violations differently.

  • clipboard: Silently fails if not triggered by a user action. No error thrown in legacy mode.
  • clipboard-polyfill: Throws a clear error in development if called outside a user gesture, helping catch bugs early.
  • clipboardy: No such restriction in Node.js — you can read/write anytime.

Also, clipboard-polyfill properly handles the Permissions API for clipboard access in modern browsers, requesting permission when needed.

🧩 Advanced Features: HTML, Images, Custom Formats

Most apps only need plain text, but some require richer content.

  • clipboard: Plain text only. No support for HTML or other formats.
  • clipboard-polyfill: Supports writing HTML and custom MIME types via write():
import { write } from 'clipboard-polyfill';

const dt = new DataTransfer();
dt.setData('text/plain', 'Fallback text');
dt.setData('text/html', '<b>Bold text</b>');

await write(dt);

This aligns with the official Clipboard API spec.

  • clipboardy: Plain text only. Binary or rich content isn’t supported.
  • copy-paste: Plain text only (and broken).

🚫 Deprecation Warning: Avoid copy-paste

The copy-paste package has been deprecated by its author. Its last update was years ago, it uses unsafe child_process.exec calls without proper escaping, and it fails on modern systems (e.g., macOS Sonoma removed pbcopy from default PATH in some contexts). The README now recommends using clipboardy instead. Do not use copy-paste in new projects.

🧪 Real-World Decision Guide

Scenario 1: “Copy” Button in a React App

You’re building a dashboard with a button that copies an API key to the clipboard.

  • Best choice: clipboard or clipboard-polyfill
  • Why? Both work in browsers. If you only need plain text and want minimal bundle impact → clipboard. If you need better error handling, future-proofing, or plan to read clipboard later → clipboard-polyfill.
// With clipboard-polyfill (recommended for new apps)
import { writeText } from 'clipboard-polyfill';

function CopyButton({ text }) {
  const handleClick = () => writeText(text);
  return <button onClick={handleClick}>Copy</button>;
}

Scenario 2: CLI Tool That Copies Output to Clipboard

You’re writing a Node.js script that generates a config snippet and puts it in the clipboard.

  • Best choice: clipboardy
  • Why? It’s the only actively maintained, reliable option for Node.js.
#!/usr/bin/env node
import { write } from 'clipboardy';

const config = `API_KEY=${process.env.API_KEY}`;
await write(config);
console.log('Config copied to clipboard!');

Scenario 3: Enterprise Web App Supporting IE11

You must support older browsers in a corporate environment.

  • Best choice: clipboard-polyfill
  • Why? It includes robust fallbacks for execCommand and handles quirks in older browsers better than clipboard.

Scenario 4: Reading Pasted Content in a Rich Text Editor

You want users to paste formatted text and capture it.

  • Best choice: clipboard-polyfill (for read() support)
  • Note: You’ll still need to listen to paste events and extract data from event.clipboardData for full control — but readText() can help in simpler cases.

📊 Summary Table

PackageEnvironmentWrite TextRead TextRich ContentActively Maintained
clipboardBrowser
clipboard-polyfillBrowser✅*
clipboardyNode.js
copy-pasteNode.js✅ (broken)✅ (broken)❌ (deprecated)

* readText() requires user gesture and secure context.

💡 Final Recommendation

  • For modern browser apps: Use clipboard-polyfill. It’s standards-aligned, handles edge cases, and prepares you for future clipboard features.
  • For simple browser copy buttons with minimal footprint: clipboard is acceptable if you don’t need read access or advanced error reporting.
  • For Node.js or CLI tools: clipboardy is the only sane choice.
  • Never use copy-paste — it’s a relic.

Choose based on your runtime first, then your feature needs. Don’t overcomplicate it — most web apps only need to write plain text, and both clipboard and clipboard-polyfill do that well. But if you care about maintainability and forward compatibility, clipboard-polyfill is the smarter long-term bet for browser-based clipboard interaction.

How to Choose: clipboardy vs clipboard vs copy-paste vs clipboard-polyfill
  • clipboardy:

    Choose clipboardy if you’re writing scripts or tools that run in Node.js (e.g., CLI utilities, build scripts, or Electron main processes) and need to interact with the system clipboard outside the browser. It does not work in browser environments and should never be bundled into frontend code. It supports both reading and writing clipboard content on macOS, Windows, and Linux.

  • clipboard:

    Choose clipboard if you're building a browser-based UI component (like a 'copy' button) and want a lightweight, zero-dependency wrapper around the modern navigator.clipboard API with automatic fallback to legacy execCommand for older browsers. It’s ideal for simple copy operations triggered by user gestures in web apps, but it doesn’t support reading from the clipboard or Node.js environments.

  • copy-paste:

    Avoid copy-paste in new projects — it is deprecated and unmaintained. The package hasn’t been updated in years, relies on outdated Node.js child process patterns, and lacks support for modern security practices. Use clipboardy instead for Node.js clipboard needs.

  • clipboard-polyfill:

    Choose clipboard-polyfill if you need robust cross-browser clipboard write (and limited read) support with automatic feature detection and polyfilling, including handling of permissions and sandboxed iframes. It’s well-suited for applications that must work reliably in enterprise environments with older browsers or strict security policies, and it supports writing plain text, HTML, and custom formats via the standard Clipboard API shape.

README for clipboardy

clipboardy

Access the system clipboard (copy/paste)

Cross-platform. Supports: macOS, Windows, Linux (including Wayland), OpenBSD, FreeBSD, Android with Termux, and modern browsers.

Install

npm install clipboardy

Usage

import clipboard from 'clipboardy';

await clipboard.write('🦄');

await clipboard.read();
//=> '🦄'

// Or use the synchronous API
clipboard.writeSync('🦄');

clipboard.readSync();
//=> '🦄'

API

Browser usage: Requires a secure context (HTTPS). Synchronous methods are not available in browsers.

clipboard

.write(text)

Write (copy) to the clipboard asynchronously.

Returns a Promise<void>.

text

Type: string

The text to write to the clipboard.

await clipboard.write('🦄');

.read()

Read (paste) from the clipboard asynchronously.

Returns a Promise<string>.

const content = await clipboard.read();
//=> '🦄'

.writeSync(text)

Write (copy) to the clipboard synchronously.

Doesn't work in browsers.

text

Type: string

The text to write to the clipboard.

clipboard.writeSync('🦄');

.readSync()

Read (paste) from the clipboard synchronously.

Returns a string.

Doesn't work in browsers.

const content = clipboard.readSync();
//=> '🦄'

FAQ

Where can I find the source of the bundled binaries?

The Linux binary is just a bundled version of xsel. The source for the Windows binary can be found here.

On Windows, clipboardy first tries the native PowerShell cmdlets (Set-Clipboard/Get-Clipboard) and falls back to the bundled binary if PowerShell is unavailable or restricted.

Does this work on Wayland?

Yes. On Linux, clipboardy automatically detects Wayland sessions and uses wl-clipboard when available. If not, it gracefully falls back to X11 tools. Also works with WSLg (Windows Subsystem for Linux GUI). Install wl-clipboard using your distribution's package manager.

Related