Installation
Install WebTorrent using npm:npm install webtorrent
import WebTorrent from 'webtorrent'
// or
const WebTorrent = require('webtorrent')
Connecting to Web Peers
The standard
webtorrent package in Node.js cannot connect to browser peers (WebRTC). To connect to both traditional BitTorrent peers and browser peers, use webtorrent-hybrid.npm install webtorrent-hybrid
import WebTorrent from 'webtorrent-hybrid'
const client = new WebTorrent()
// Now can connect to both TCP/UDP peers and WebRTC peers
Basic Usage
Create a client
import WebTorrent from 'webtorrent'
const client = new WebTorrent()
client.on('error', err => {
console.error('Client error:', err)
})
Download a torrent
const magnetURI = 'magnet:?xt=urn:btih:...'
client.add(magnetURI, { path: '/path/to/downloads' }, torrent => {
console.log('Downloading:', torrent.name)
torrent.on('done', () => {
console.log('Torrent download finished')
})
})
Monitor progress
client.add(magnetURI, torrent => {
const interval = setInterval(() => {
console.log('Progress:', (torrent.progress * 100).toFixed(1) + '%')
console.log('Download speed:', torrent.downloadSpeed, 'bytes/sec')
console.log('Upload speed:', torrent.uploadSpeed, 'bytes/sec')
console.log('Peers:', torrent.numPeers)
}, 1000)
torrent.on('done', () => {
clearInterval(interval)
console.log('Download complete!')
})
})
Downloading Torrents
From Magnet URI
const magnetURI = 'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10'
client.add(magnetURI, { path: './downloads' }, torrent => {
console.log('Downloading:', torrent.name)
})
From .torrent File
import fs from 'fs'
const torrentFile = fs.readFileSync('./my-torrent.torrent')
client.add(torrentFile, { path: './downloads' }, torrent => {
console.log('Downloading:', torrent.name)
})
From URL
const torrentUrl = 'https://webtorrent.io/torrents/sintel.torrent'
client.add(torrentUrl, { path: './downloads' }, torrent => {
console.log('Downloading:', torrent.name)
})
From Info Hash
const infoHash = '08ada5a7a6183aae1e09d831df6748d566095a10'
client.add(infoHash, { path: './downloads' }, torrent => {
console.log('Downloading:', torrent.name)
})
Seeding Torrents
Seed a File
import WebTorrent from 'webtorrent'
const client = new WebTorrent()
client.seed('/path/to/file.mp4', torrent => {
console.log('Client is seeding:', torrent.magnetURI)
})
Seed a Directory
client.seed('/path/to/folder', torrent => {
console.log('Client is seeding:', torrent.infoHash)
console.log('Files:', torrent.files.length)
})
Seed with Options
client.seed('/path/to/file.mp4', {
name: 'My Video', // Torrent name
comment: 'Shared via WebTorrent',
createdBy: 'WebTorrent/1.0',
private: false, // Enable DHT/PEX
announceList: [ // Custom trackers
['udp://tracker.example.com:6969'],
['wss://tracker.example.com']
]
}, torrent => {
console.log('Seeding torrent:', torrent.name)
})
When you seed a file, WebTorrent automatically creates the .torrent metadata and starts announcing to trackers and DHT.
Working with Files
Create a Read Stream
In Node.js, you can create a standard Node.js readable stream:import fs from 'fs'
client.add(magnetURI, torrent => {
const file = torrent.files[0]
// Create a read stream
const stream = file.createReadStream()
// Pipe to file
stream.pipe(fs.createWriteStream('/path/to/output.mp4'))
// Or process chunks
stream.on('data', chunk => {
console.log('Received chunk:', chunk.length, 'bytes')
})
stream.on('end', () => {
console.log('File stream complete')
})
})
Stream a Specific Range
const file = torrent.files[0]
// Stream bytes 1000-5000
const stream = file.createReadStream({
start: 1000,
end: 5000
})
Get File as Buffer
const file = torrent.files[0]
const buffer = Buffer.from(await file.arrayBuffer())
console.log('File size:', buffer.length)
Setting Up an HTTP Server
You can create an HTTP server to stream torrents over HTTP:import WebTorrent from 'webtorrent'
const client = new WebTorrent()
const magnetURI = 'magnet:?xt=urn:btih:...'
// Create HTTP server
const server = client.createServer()
server.listen(3000, () => {
console.log('Server listening on http://localhost:3000')
})
client.add(magnetURI, torrent => {
// Files are now accessible via HTTP
const file = torrent.files[0]
console.log('Stream URL:', `http://localhost:3000${file.streamURL}`)
// Access torrents at:
// http://localhost:3000/webtorrent/<infoHash>/<file-path>
})
Server Configuration
const server = client.createServer({
origin: '*', // CORS origin (default: '*')
hostname: 'localhost', // Only accept requests to this hostname
path: '/torrents' // Base path (default: '/webtorrent')
})
server.listen(8080)
The HTTP server supports range requests, which enables seeking in video players.
Client Configuration
Configure the WebTorrent client with advanced options:const client = new WebTorrent({
maxConns: 55, // Max connections per torrent
nodeId: Buffer.from('...'), // DHT node ID (20 bytes)
peerId: Buffer.from('...'), // Wire protocol peer ID (20 bytes)
tracker: true, // Enable trackers
dht: true, // Enable DHT
lsd: true, // Enable local service discovery
utPex: true, // Enable peer exchange
natUpnp: true, // Enable NAT port mapping via UPnP
natPmp: true, // Enable NAT port mapping via PMP
webSeeds: true, // Enable web seeds
utp: true, // Enable uTorrent transport protocol
downloadLimit: -1, // Download throttle (bytes/sec, -1 = unlimited)
uploadLimit: -1, // Upload throttle (bytes/sec, -1 = unlimited)
blocklist: [] // List of blocked IPs
})
Bandwidth Throttling
const client = new WebTorrent({
downloadLimit: 1000000, // 1 MB/s
uploadLimit: 500000 // 500 KB/s
})
// Change limits dynamically
client.throttleDownload(2000000) // 2 MB/s
client.throttleUpload(1000000) // 1 MB/s
// Disable throttling
client.throttleDownload(-1)
client.throttleUpload(-1)
IP Blocklist
const client = new WebTorrent({
blocklist: [
'1.2.3.4',
'5.6.7.0/24'
]
})
// Or load from URL
const client = new WebTorrent({
blocklist: 'https://example.com/blocklist.txt'
})
Torrent Options
Configure individual torrents when adding them:client.add(magnetURI, {
path: '/downloads', // Download location
announce: ['udp://...'], // Additional trackers
maxWebConns: 4, // Max web seed connections
private: false, // Disable DHT/PEX for private torrents
strategy: 'sequential', // Piece selection: 'sequential' or 'rarest'
storeCacheSlots: 20, // Cache size (0 to disable)
skipVerify: false, // Skip hash verification
destroyStoreOnDestroy: false // Delete files when torrent destroyed
}, torrent => {
console.log('Torrent added')
})
Monitoring and Events
Client Events
client.on('torrent', torrent => {
console.log('Torrent ready:', torrent.name)
})
client.on('error', err => {
console.error('Fatal error:', err)
})
Torrent Events
torrent.on('ready', () => {
console.log('Torrent metadata received')
})
torrent.on('download', bytes => {
console.log('Downloaded:', bytes, 'bytes')
})
torrent.on('upload', bytes => {
console.log('Uploaded:', bytes, 'bytes')
})
torrent.on('done', () => {
console.log('Download complete')
})
torrent.on('wire', (wire, addr) => {
console.log('Connected to peer:', addr)
})
torrent.on('noPeers', announceType => {
console.log('No peers found via', announceType)
})
Statistics
Access real-time statistics:// Client-level stats
console.log('Download speed:', client.downloadSpeed, 'bytes/sec')
console.log('Upload speed:', client.uploadSpeed, 'bytes/sec')
console.log('Progress:', (client.progress * 100).toFixed(1) + '%')
console.log('Ratio:', client.ratio)
// Torrent-level stats
console.log('Downloaded:', torrent.downloaded, 'bytes')
console.log('Uploaded:', torrent.uploaded, 'bytes')
console.log('Download speed:', torrent.downloadSpeed, 'bytes/sec')
console.log('Upload speed:', torrent.uploadSpeed, 'bytes/sec')
console.log('Progress:', (torrent.progress * 100).toFixed(1) + '%')
console.log('Ratio:', torrent.ratio)
console.log('Time remaining:', torrent.timeRemaining, 'ms')
console.log('Peers:', torrent.numPeers)
Cleanup
Remove a Torrent
// Remove but keep files
await client.remove(torrentId)
// Remove and delete files
await client.remove(torrentId, { destroyStore: true })
Destroy Client
client.destroy(err => {
if (err) console.error('Error:', err)
else console.log('Client destroyed')
})
Complete Example
Here’s a complete example that downloads a torrent and serves it over HTTP:import WebTorrent from 'webtorrent'
const client = new WebTorrent()
const magnetURI = 'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10'
// Create HTTP server
const server = client.createServer()
server.listen(8000, () => {
console.log('Server listening on http://localhost:8000')
})
// Add torrent
client.add(magnetURI, { path: './downloads' }, torrent => {
console.log('Downloading:', torrent.name)
// Print progress every second
const interval = setInterval(() => {
console.log('Progress:', (torrent.progress * 100).toFixed(1) + '%')
console.log('Download:', torrent.downloadSpeed, 'bytes/sec')
console.log('Upload:', torrent.uploadSpeed, 'bytes/sec')
console.log('Peers:', torrent.numPeers)
console.log('---')
}, 1000)
// List files and URLs
torrent.files.forEach(file => {
console.log('File:', file.name)
console.log('URL:', `http://localhost:8000${file.streamURL}`)
})
torrent.on('done', () => {
clearInterval(interval)
console.log('Download complete!')
})
})
// Graceful shutdown
process.on('SIGINT', () => {
client.destroy(() => {
console.log('Client destroyed')
process.exit(0)
})
})
Debug Logging
Enable debug logs to troubleshoot issues:DEBUG=* node app.js
DEBUG=webtorrent* node app.js
DEBUG=bittorrent-protocol node app.js