Install
openclaw skills install @openlark/webtorrentUse WebTorrent to implement streaming BitTorrent client functionality in Node.js and the browser. Supports torrent downloading, seeding, magnet links, streaming media playback, and peer-to-peer transfer (via WebRTC Data Channel in the browser, and TCP/UDP in Node.js).
openclaw skills install @openlark/webtorrentA BitTorrent client that runs in both Node.js and the browser, implemented in pure JavaScript with zero native dependencies.
Use when users need to download torrent/magnet links, seed and share files, implement browser-side P2P transfer, build streaming torrent media players, or use webtorrent-related features.
webtorrent, torrent download, magnet link, torrent, seeding, P2P transfer, browser torrent, WebRTC file sharing, streaming download.
npm install webtorrent
CLI tool:
npm install webtorrent-cli -g
import WebTorrent from 'webtorrent'
const client = new WebTorrent()
// Download via magnet link
client.add(magnetURI, (torrent) => {
console.log('Downloading:', torrent.infoHash)
torrent.files.forEach(file => {
console.log(`File: ${file.name} (${file.length} bytes)`)
})
})
// Seed — share local files
client.seed('/path/to/file.mp4', (torrent) => {
console.log('Seeding:', torrent.magnetURI)
})
import WebTorrent from 'webtorrent'
const client = new WebTorrent()
client.add(magnetURI, (torrent) => {
torrent.files.forEach(file => {
file.getBuffer((err, buf) => {
if (err) throw err
console.log(`Download complete: ${file.name}, ${buf.length} bytes`)
})
})
})
<script type="module">
import WebTorrent from 'https://esm.sh/webtorrent'
// Or local: import WebTorrent from 'webtorrent.min.js'
const client = new WebTorrent()
// ... same as above
</script>
client.add(torrentId, [opts], [callback])Add a torrent to start downloading.
torrentId — magnet URI / info hash / torrent file Buffer / remote .torrent URLopts — Optional configuration (see below)Torrent objectclient.add(magnetURI, { path: './downloads' }, (torrent) => {
console.log('Metadata obtained')
})
client.seed(input, [opts], [callback])Seed and share files.
input — File path / File object / FileList / Buffer / ReadableStream// Drag-and-drop file seeding in the browser
import dragDrop from 'drag-drop'
dragDrop('body', (files) => {
client.seed(files, (torrent) => {
console.log('Seeding:', torrent.magnetURI)
})
})
client.destroy([callback])Destroy the client and release all resources.
client.on('error', callback)Global error handling.
client.add(magnetURI, (torrent) => {
// Properties
torrent.infoHash // string — torrent hash
torrent.magnetURI // string — magnet link
torrent.name // string — torrent name
torrent.files // File[] — file list
torrent.progress // number 0-1
torrent.downloaded // number — bytes downloaded
torrent.uploaded // number — bytes uploaded
torrent.downloadSpeed // bytes/s
torrent.uploadSpeed // bytes/s
torrent.numPeers // number — connected peers
torrent.path // string — download directory
torrent.ready // boolean — metadata ready
// Events
torrent.on('ready', () => {}) // Metadata ready
torrent.on('download', (bytes) => {}) // Data chunk received
torrent.on('upload', (bytes) => {}) // Data chunk sent
torrent.on('done', () => {}) // Download complete
torrent.on('error', (err) => {}) // Error
torrent.on('warning', (err) => {}) // Warning
torrent.on('wire', (wire) => {}) // New peer connected
torrent.on('noPeers', () => {}) // No peers available
// Methods
torrent.pause() // Pause
torrent.resume() // Resume
torrent.destroy() // Remove torrent
})
const file = torrent.files[0]
// Properties
file.name // Filename
file.length // File size (bytes)
file.downloaded // Bytes downloaded
file.progress // Download progress 0-1
// Methods
file.getBuffer((err, buffer) => {}) // Get complete Buffer
file.getBlob((err, blob) => {}) // Get Blob (browser)
// Streaming read — create a readable stream
const stream = file.createReadStream()
stream.pipe(someWritableStream)
// Render to page
file.appendTo('#container') // Append to DOM element
file.renderTo('#container') // Replace DOM element content
// Streaming video playback
file.renderTo('video#player') // Render to <video> tag
file.renderTo('img#preview') // Render to <img> tag
file.renderTo('audio#player') // Render to <audio> tag
Native Node.js webtorrent only uses TCP/UDP and cannot directly connect to browser WebRTC peers. For bidirectional communication, use:
npm install webtorrent-hybrid
import WebTorrent from 'webtorrent-hybrid'
// API is identical, but additionally supports WebRTC
const client = new WebTorrent({
maxConns: 55, // Maximum number of connections
dht: true, // Enable DHT
tracker: true, // Enable tracker
webSeeds: true, // Enable web seeds
lsd: true, // Enable local service discovery
utp: true, // Enable μTP (Node only)
downloadLimit: -1, // Download rate limit (bytes/s), -1 = unlimited
uploadLimit: -1 // Upload rate limit (bytes/s), -1 = unlimited
})
client.add(magnetURI, {
path: './downloads', // Download directory
store: 'auto', // Storage strategy: 'auto' | MemoryStorage | custom
destroyStoreOnDestroy: false, // Delete files on destroy
private: false, // Use private trackers only
announce: ['wss://...'], // Custom tracker list
deselect: false, // true = do not auto-select files to download
strategy: 'sequential' // 'sequential' | 'rarest'
})
# Download a magnet link
webtorrent magnet_uri
# Stream to various devices
webtorrent magnet_uri --airplay # Apple TV
webtorrent magnet_uri --chromecast # Chromecast
webtorrent magnet_uri --vlc # VLC
webtorrent magnet_uri --mpv # MPV
webtorrent magnet_uri --mplayer # MPlayer
webtorrent magnet_uri --xbmc # XBMC
webtorrent magnet_uri --stdout # Standard output
client.add(magnetURI, (torrent) => {
const file = torrent.files.find(f => f.name.endsWith('.mp4'))
if (file) file.renderTo('video#player')
})
client.add(magnetURI, (torrent) => {
torrent.on('download', () => {
const pct = (torrent.progress * 100).toFixed(1)
console.log(`Progress: ${pct}% | Speed: ${formatSpeed(torrent.downloadSpeed)}`)
})
torrent.on('done', () => {
console.log('Download complete!')
})
})
function formatSpeed(bps) {
const units = ['B/s', 'KB/s', 'MB/s']
let i = 0
while (bps >= 1024 && i < units.length - 1) { bps /= 1024; i++ }
return `${bps.toFixed(1)} ${units[i]}`
}
client.add(magnetURI, { deselect: true }, (torrent) => {
// After metadata is ready, only select needed files
torrent.on('ready', () => {
torrent.files.forEach(file => {
if (file.name.endsWith('.mp4')) file.select()
else file.deselect()
})
})
})
import MemoryChunkStore from 'memory-chunk-store'
client.add(magnetURI, { store: MemoryChunkStore }, (torrent) => {
// Data stored in memory, not written to disk
torrent.on('done', () => {
torrent.files[0].getBuffer((err, buf) => {
console.log(`Completed in memory: ${buf.length} bytes`)
})
})
})
| Mechanism | Description | Node | Browser |
|---|---|---|---|
| DHT | Distributed Hash Table | ✅ | ✅ (WebRTC) |
| Tracker | Centralized tracking server | ✅ | ✅ (WebSocket) |
| LSD | Local Service Discovery | ✅ | ❌ |
| ut_pex | Peer Exchange Extension | ✅ | ✅ |
For the detailed API reference, see references/api-reference.md.