react-copy-kit
v0.1.0
Published
A tiny, modern alternative to react-copy-to-clipboard with first-party TypeScript, React 18/19 support, SSR safety, and modern Clipboard API usage
Downloads
7
Maintainers
Readme
react-copy-kit
A tiny, modern alternative to react-copy-to-clipboard with first-party TypeScript, React 18/19 support, SSR safety, accessibility announcements, and modern Clipboard API usage.
Why migrate from react-copy-to-clipboard?
- React 19 support:
react-copy-to-clipboardhas peer dependency conflicts with React 19 (GitHub issue).react-copy-kitsupports React 18 and 19 out of the box. - Stale maintenance: Last release was v5.1.0 on Apr 22, 2022 (~3 years ago).
react-copy-kitis actively maintained. - Modern API: Uses the Async Clipboard API (
navigator.clipboard.writeText) first, with graceful fallbacks. No legacyprompt()UI or IE-specific paths. - First-party TypeScript: Built-in TypeScript types—no need for separate
@typespackages or type definition issues. - SSR/Next.js safe: Fully compatible with server-side rendering.
- Accessibility: Optional screen reader announcements with customizable labels.
- Tiny bundle: Less than 2 kB gzipped.
Installation
npm install react-copy-kit
# or
pnpm add react-copy-kit
# or
yarn add react-copy-kitQuick Start
Using the Hook
import { useCopy } from 'react-copy-kit';
function MyComponent() {
const { copy, status } = useCopy();
return (
<button onClick={() => copy('Hello, world!')}>
{status === 'copied' ? 'Copied!' : 'Copy'}
</button>
);
}Using the Headless Button
import { CopyButton } from 'react-copy-kit';
function MyComponent() {
return <CopyButton text="Hello, world!">Copy</CopyButton>;
}API
useCopy(initialText?, options?)
A React hook that provides copy-to-clipboard functionality.
Parameters
initialText(optional): Initial text to copy whencopy()is called without arguments.options(optional): Configuration object:resetAfter: Number of milliseconds before status resets to'idle'(default:1500)onCopy: Callback invoked when copy succeeds(text: string) => voidonError: Callback invoked when copy fails(error: unknown) => void
Returns
copy(text?): Function to copy text to clipboard. ReturnsPromise<boolean>status: Current copy status:'idle' | 'copying' | 'copied' | 'error'error: Error object if copy failed,nullotherwiselastText: Last text that was copied,nullif none
Example
function Example() {
const { copy, status, error } = useCopy('default text', {
onCopy: (text) => console.log('Copied:', text),
onError: (err) => console.error('Error:', err),
resetAfter: 2000,
});
return (
<div>
<button onClick={() => copy('Hello!')}>Copy</button>
<p>Status: {status}</p>
{error && <p>Error: {String(error)}</p>}
</div>
);
}<CopyButton />
A headless button component that handles copying automatically.
Props
Extends React.ButtonHTMLAttributes<HTMLButtonElement> with:
text: Required. Text to copy to clipboard.announce: Whether to announce copy status to screen readers (default:true)announceLabels: Custom labels for announcements:copying?: string(default:'Copying to clipboard...')copied?: string(default:'Copied to clipboard')error?: string(default:'Failed to copy to clipboard')
Example
function Example() {
return (
<CopyButton
text="Hello, world!"
announce
announceLabels={{
copied: 'Successfully copied!',
}}
>
Copy to Clipboard
</CopyButton>
);
}SSR / Next.js
react-copy-kit is fully SSR-safe. All browser APIs are guarded with typeof window !== 'undefined' checks.
// Works in Next.js App Router
'use client';
import { useCopy } from 'react-copy-kit';
export function ClientComponent() {
const { copy, status } = useCopy();
// ...
}Browser Support
| Browser | Clipboard API | Fallback (execCommand) | |---------|---------------|------------------------| | Chrome 66+ | ✅ | ✅ | | Firefox 63+ | ✅ | ✅ | | Safari 13.1+ | ✅ | ✅ | | Edge 79+ | ✅ | ✅ | | IE 11 | ❌ | ✅ |
The library automatically falls back to document.execCommand('copy') when the Clipboard API is unavailable.
Comparison with react-copy-to-clipboard
| Feature | react-copy-to-clipboard | react-copy-kit | |---------|------------------------|----------------| | React 19 support | ❌ (peer dep errors) | ✅ | | First-party TypeScript | ❌ (uses @types) | ✅ | | Modern Clipboard API | ⚠️ (with legacy fallbacks) | ✅ (primary method) | | SSR/Next.js safe | ⚠️ (partial) | ✅ | | Accessibility | ❌ | ✅ (announcements) | | Bundle size | ~3.5 kB | < 2 kB | | Maintenance | ⚠️ (stale since 2022) | ✅ (active) | | No prompt() fallback | ❌ | ✅ |
Migration Guide
From react-copy-to-clipboard
Before:
import { CopyToClipboard } from 'react-copy-to-clipboard';
<CopyToClipboard text={value} onCopy={() => console.log('Copied!')}>
<button>Copy</button>
</CopyToClipboard>After (using hook):
import { useCopy } from 'react-copy-kit';
function MyComponent() {
const { copy, status } = useCopy();
return (
<button onClick={() => copy(value)}>
{status === 'copied' ? 'Copied!' : 'Copy'}
</button>
);
}After (using button):
import { CopyButton } from 'react-copy-kit';
<CopyButton text={value} onCopy={() => console.log('Copied!')}>
Copy
</CopyButton>Key Differences
- Hook-based API:
useCopyprovides more control and composability. - Status management: Built-in status tracking (
idle,copying,copied,error). - Promise-based:
copy()returns aPromise<boolean>for better async handling. - No render prop: Direct function calls instead of render props.
Development
# Install dependencies
pnpm install
# Build
pnpm build
# Test
pnpm test
# Lint
pnpm lint
# Format
pnpm format
# Storybook
pnpm storybook
# Check bundle size
pnpm sizeLicense
MIT
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
