node-native-clipboard
v1.0.3
Published
Native Node.js module for clipboard file operations across Windows, macOS, and Linux
Maintainers
Readme
node-native-clipboard
A native Node.js module for clipboard file operations across Windows, macOS, and Linux.
Features
- ✅ Copy file paths to the native OS clipboard
- ✅ Paste file paths from the native OS clipboard
- ✅ Cross-platform support (Windows, macOS, Linux)
- ✅ Multiple architectures (x64, ARM64)
- ✅ No special permissions required
Installation
npm install node-native-clipboardUsage
const { copy, paste } = require('node-native-clipboard');
// Copy files to clipboard
copy(['/path/to/file1.txt', '/path/to/file2.txt']);
// Read files from clipboard
const files = paste();
console.log(files); // ['path1', 'path2', ...] or null if no filesAPI
copy(paths: string[]): void
Copy file paths to the native clipboard.
- paths: Array of absolute file paths to copy
Example:
copy(['/Users/john/Documents/file.txt', '/Users/john/Downloads/image.png']);paste(): string[] | null
Retrieve file paths from the native clipboard.
- Returns: Array of file paths, or
nullif no files in clipboard
Example:
const files = paste();
if (files) {
console.log(`Found ${files.length} files:`, files);
} else {
console.log('No files in clipboard');
}listen(callback, options): listenerId
Monitor clipboard changes and receive notifications.
- callback(event): Function called when clipboard changes
event.files: Array of file paths (ornullif no files)event.timestamp: Unix timestamp (seconds) of the change
- options (optional): Configuration object
options.interval: Polling interval in milliseconds (default: 2000)
- Returns: Numeric listener ID (use with
unlisten())
Example:
const { listen, unlisten } = require('native-clipboard');
// Default 2-second polling
const listenerId = listen((event) => {
console.log('Clipboard changed!');
if (event.files) {
console.log('New files:', event.files);
}
});
// Custom 5-second polling
const listenerId2 = listen((event) => {
console.log('Files:', event.files);
}, { interval: 5000 });
// Stop listening
unlisten(listenerId);Notes:
- Uses polling to detect changes (checks every 2 seconds by default)
- Initial clipboard state is captured but doesn't trigger callback
- Works on all platforms (Windows, macOS, Linux)
- Multiple listeners can run simultaneously with different intervals
unlisten(listenerId): void
Stop monitoring clipboard changes.
- listenerId: ID returned from
listen()
Example:
unlisten(listenerId);Platform Support
| Platform | Architecture | Status | |----------|--------------|--------| | macOS | x64 (Intel) | ✅ | | macOS | ARM64 (M1+) | ✅ | | Windows | x64 | ⚠️ (built, untested) | | Windows | ARM64 | ⚠️ (built, untested) | | Linux | x64 | ⚠️ (built, untested) | | Linux | ARM64 | ⚠️ (built, untested) |
Platform-Specific Notes
macOS
- Uses
NSPasteboardAPI via AppKit framework - Works with Finder's file clipboard
- No special permissions required
Windows
- Uses Win32 Clipboard API with
CF_HDROPformat - Works with Explorer's file clipboard
- No special permissions required
Linux
- Native support for both X11 and Wayland
- No external tools required
- Automatically detects display server (X11 or Wayland)
- Works out-of-the-box on all major distributions
Building from Source
Prerequisites
Install Rust if you haven't already:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shBuild for Current Platform (Any OS)
Build the native module for the platform you're currently on:
npm install
npm run buildThis automatically detects your platform and architecture.
Cross-Compilation from macOS
You can build binaries for all platforms (Windows, macOS, Linux) from a single macOS machine!
Building for macOS (from macOS)
# Install targets
rustup target add x86_64-apple-darwin # Intel Macs
rustup target add aarch64-apple-darwin # Apple Silicon (M1/M2/M3)
# Build
npm run build:macOutput (in build/ directory):
build/native-clipboard.darwin-x64.node(Intel)build/native-clipboard.darwin-arm64.node(Apple Silicon)
Building for Windows (from macOS)
Method 1: Cross-compilation (Recommended)
# 1. Install cargo-xwin (downloads Windows SDK automatically)
cargo install cargo-xwin
# 2. Install Windows targets
rustup target add x86_64-pc-windows-msvc # Windows x64
rustup target add aarch64-pc-windows-msvc # Windows ARM64
# 3. Build
npm run build:win:crossNote: First run downloads Windows SDK (~150MB), subsequent builds are fast.
Method 2: Native build on Windows
If building directly on a Windows machine:
# Install targets
rustup target add x86_64-pc-windows-msvc
rustup target add aarch64-pc-windows-msvc
# Build
npm run build:winOutput (in build/ directory):
build/native-clipboard.win32-x64-msvc.node(Intel/AMD)build/native-clipboard.win32-arm64-msvc.node(ARM64)
Testing: Copy the .node files to a Windows machine and run npm test
Building for Linux (from macOS)
Cross-compilation (from macOS)
# 1. Install cross-compilation toolchains (provides gcc linkers for Linux)
brew tap messense/macos-cross-toolchains
brew install messense/macos-cross-toolchains/x86_64-unknown-linux-gnu
brew install messense/macos-cross-toolchains/aarch64-unknown-linux-gnu
# 2. Install Linux targets
rustup target add x86_64-unknown-linux-gnu # Linux x64
rustup target add aarch64-unknown-linux-gnu # Linux ARM64
# 3. Build
npm run build:linuxNote: The cross-compilation toolchains are required - they provide the x86_64-unknown-linux-gnu-gcc and aarch64-unknown-linux-gnu-gcc linkers needed to compile for Linux from macOS.
Native build on Linux
If building directly on a Linux machine:
# Install build tools
sudo apt-get install build-essential
# Install targets
rustup target add x86_64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-gnu
# Build
npm run build:linuxNote: No external clipboard utilities needed - native support for both X11 and Wayland is built-in.
Output (in build/ directory):
build/native-clipboard.linux-x64-gnu.nodebuild/native-clipboard.linux-arm64-gnu.node
Testing: Copy the .node files to a Linux machine and run npm test - no external tools needed!
Build All Platforms at Once (from macOS)
After installing all prerequisites above:
# Build all platforms (uses cargo-xwin for Windows cross-compilation)
npm run build:all:crossThis produces all 6 binaries in the build/ directory:
build/native-clipboard.darwin-x64.nodebuild/native-clipboard.darwin-arm64.nodebuild/native-clipboard.win32-x64-msvc.nodebuild/native-clipboard.win32-arm64-msvc.nodebuild/native-clipboard.linux-x64-gnu.nodebuild/native-clipboard.linux-arm64-gnu.node
Prerequisites summary for all platforms:
# Install cargo-xwin for Windows cross-compilation
cargo install cargo-xwin
# Install cross-compilation toolchains for Linux
brew tap messense/macos-cross-toolchains
brew install messense/macos-cross-toolchains/x86_64-unknown-linux-gnu
brew install messense/macos-cross-toolchains/aarch64-unknown-linux-gnu
# Install all Rust targets
rustup target add x86_64-apple-darwin aarch64-apple-darwin
rustup target add x86_64-pc-windows-msvc aarch64-pc-windows-msvc
rustup target add x86_64-unknown-linux-gnu aarch64-unknown-linux-gnuBuilding on Native Platforms
Building on Windows
Prerequisites:
- Visual Studio Build Tools or Visual Studio with C++ support
- Rust
- Node.js
# Build
npm install
npm run buildBuilding on Linux
Prerequisites:
# Build
npm install
npm run buildBuild Commands Summary
| Command | Description |
|---------|-------------|
| npm run build | Build for current platform only |
| npm run build:mac | Build macOS binaries (x64 + ARM64) |
| npm run build:win | Build Windows binaries (native Windows only) |
| npm run build:win:cross | Build Windows binaries (cross-compile from macOS/Linux with cargo-xwin) |
| npm run build:linux | Build Linux binaries (x64 + ARM64) |
| npm run build:all | Build all platforms (native Windows build) |
| npm run build:all:cross | Build all platforms (cross-compile Windows from macOS) |
| npm run build:debug | Build in debug mode (faster, larger binaries) |
Testing
npm testThe test script will:
- Copy test file paths to the clipboard
- Read them back from the clipboard
- Verify the operation succeeded
You can also test manually:
- Run the test script
- Try pasting in Finder/Explorer/File Manager
- Or copy files in your file manager, then run
paste()to read them
Troubleshooting
macOS: "NSPasteboard class not found"
This error means the AppKit framework isn't linked. Rebuild the project:
npm run buildWindows: Build errors
Make sure you have the Microsoft Visual C++ build tools installed.
Project Structure
native-clipboard/
├── src/
│ ├── index.js # JavaScript entry point (loads platform binaries)
│ ├── napi/
│ │ └── lib.rs # Rust N-API bindings entry point
│ └── platform/
│ ├── macos.rs # macOS clipboard implementation
│ ├── windows.rs # Windows clipboard implementation
│ └── linux.rs # Linux clipboard implementation
├── scripts/
│ └── build.rs # Cargo build script
├── examples/
│ └── visual-test.js # Interactive testing tool
├── test/
│ └── index.test.js # Automated tests
├── build/ # Build output (.node binaries)
├── Cargo.toml # Rust dependencies
├── package.json # Node.js package metadata
└── LICENSE # MIT LicenseArchitecture
- Language: Rust with N-API bindings via
napi-rs - macOS: Direct Objective-C bindings to
NSPasteboard - Windows:
clipboard-wincrate (CF_HDROPformat) - Linux: Native
arboardcrate (X11 viax11rb, Wayland viawl-clipboard-rs)
Performance
All operations are synchronous and typically complete in < 1ms for small file lists. The Linux implementation may be slightly slower due to subprocess execution.
License
MIT
Contributing
Contributions are welcome! Please:
- Test on your platform before submitting
- Update tests for new features
- Follow Rust and JavaScript best practices
- Document platform-specific behavior
Changelog
1.0.0 - Initial Release
- ✅ macOS support (x64, ARM64)
- ⚠️ Windows support (x64, ARM64) - built but untested
- ⚠️ Linux support (x64, ARM64) - built but untested
- Cross-compilation from macOS
- Basic copy/paste operations
1.0.2
- Adds listener API
1.0.3
- Fix repository links
