TypeScript api wrapper for Transmission using ofetch
npm install @ctrl/transmission
Requires Node.js 24 or newer.
import { Transmission } from '@ctrl/transmission';
const client = new Transmission({
baseUrl: 'http://localhost:9091/',
password: '',
});
async function main() {
const res = await client.getAllData();
console.log(res);
}
Docs: https://transmission.ep.workers.dev
API Docs: https://github.com/transmission/transmission/blob/main/docs/rpc-spec.md
Things that work differently from the other clients:
label is the first of Transmission's labels, normalizedAddTorrent sets labels: [label]totalSeeds/totalPeers come from tracker scrapes and are 0 until a tracker respondsThese functions are normalized through @ctrl/shared-torrent, which makes it easier to support multiple torrent clients. See below for alternative supported torrent clients.
Returns all torrent data and an array of label objects. Data has been normalized and does not match the output of native listTorrents().
const data = await client.getAllData();
console.log(data.torrents);
Returns one torrent data from torrent hash
const data = await client.getTorrent('torrent-hash');
console.log(data);
Pause or resume one or more torrents
await client.pauseTorrent('torrent-hash');
await client.resumeTorrent(['torrent-hash', 'other-torrent-hash']);
Remove one or more torrents. Does not remove data on disk by default.
// does not remove data on disk
await client.removeTorrent('torrent-hash', false);
// remove data on disk
await client.removeTorrent(['torrent-hash', 'other-torrent-hash'], true);
Move a torrent up or down the queue
await client.queueUp('torrent-hash');
await client.queueDown('torrent-hash');
Add a torrent from a magnet link or torrent file, has client specific options. Also see normalizedAddTorrent
import { readFileSync } from 'node:fs';
const result = await client.addTorrent(new Uint8Array(readFileSync('./linux.torrent')));
console.log(result);
Add a torrent and return normalized torrent data, can start a torrent paused and add label
const result = await client.normalizedAddTorrent('magnet:?xt=urn:btih:...', {
startPaused: false,
label: 'linux',
});
console.log(result);
Failed requests throw a TorrentClientError from @ctrl/shared-torrent with a code of torrent_not_found, unauthorized, request_failed or client_error, the http status when there is one and the original error as the cause.
import { TorrentClientError } from '@ctrl/transmission';
try {
await client.getTorrent('torrent-hash');
} catch (error) {
if (error instanceof TorrentClientError && error.code === 'torrent_not_found') {
// not in the client
}
}
If you're shutting down the server often (serverless?) you can export the state
const state = client.exportState();
const restored = Transmission.createFromState(config, state);
All of the following npm modules provide the same normalized functions along with supporting the unique apis for each client.
Usenet clients with the same normalized approach:
docker run -d \
--name=transmission \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Etc/UTC \
-p 9091:9091 \
-p 51413:51413 \
-p 51413:51413/udp \
-v ~/Documents/transmission/config:/config \
-v ~/Documents/transmission/downloads:/downloads \
-v ~/Documents/transmission/watch:/watch \
--restart unless-stopped \
lscr.io/linuxserver/transmission:latest