How to Convert Magnet URI to a .torrent File and Traverse Its ContentsHow to Convert Magnet URI to a .torrent File and Traverse Its ContentsHow to Convert Magnet URI to a .torrent File and Traverse Its Contents

2025::11::21
4 min
AUTHOR:Z. SHINCHVEN

Magnet URIs are a convenient way to share torrents without having to host a .torrent file. However, sometimes you might need to inspect the contents of a torrent before you start downloading it, or you might want to save the .torrent file for later use.

In this post, we'll explore how to use Node.js and the webtorrent library to convert a magnet URI into a .torrent file and traverse the list of files it contains.

Prerequisites

Before we start, make sure you have Node.js and npm installed on your system.

Setting up the Project

First, let's set up a new Node.js project. Open your terminal and run the following commands:

mkdir magnet-converter
cd magnet-converter
npm init -y
npm install webtorrent

This will create a new directory, initialize a Node.js project, and install the webtorrent library.

The Code

Now, create a file named index.js and add the following code:

const WebTorrent = require('webtorrent');
const fs = require('fs');
const path = require('path');

const client = new WebTorrent();

/**
 * Converts a magnet URI to a .torrent file and traverses its files.
 * @param {string} magnetURI The magnet URI to process.
 * @param {string} [outputDir='./torrents'] The directory to save the .torrent file.
 */
async function processMagnetURI(magnetURI, outputDir = './torrents') {
    if (!magnetURI) {
        console.error('Error: No magnet URI provided.');
        console.log('Usage: node index.js "magnet:?xt=urn:btih:..." [output_directory]');
        client.destroy();
        return;
    }

    // Ensure output directory exists
    if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, { recursive: true });
    }

    console.log(`Adding magnet URI: ${magnetURI}`);

    client.add(magnetURI, (torrent) => {
        console.log(`Torrent "${torrent.name}" added.`);

        torrent.on('metadata', () => {
            console.log('Metadata received.');

            // Save the .torrent file
            const torrentFilePath = path.join(outputDir, `${torrent.name}.torrent`);
            fs.writeFile(torrentFilePath, torrent.toTorrentFile(), (err) => {
                if (err) {
                    console.error(`Error saving .torrent file: ${err.message}`);
                } else {
                    console.log(`Saved .torrent file to: ${torrentFilePath}`);
                }
            });

            console.log('\n--- Files in Torrent ---');
            if (torrent.files.length === 0) {
                console.log('No files found in this torrent.');
            } else {
                torrent.files.forEach((file, index) => {
                    console.log(`File ${index + 1}:`);
                    console.log(`  Name: ${file.name}`);
                    console.log(`  Path: ${file.path}`);
                    console.log(`  Size: ${file.length} bytes`);
                });
            }

            client.destroy(() => {
                console.log('WebTorrent client destroyed.');
            });
        });

        torrent.on('error', (err) => {
            console.error(`Torrent error: ${err.message}`);
            client.destroy();
        });
    });
}

// Get magnet URI and optional output directory from command line arguments
const magnet = process.argv[2];
const output = process.argv[3];

processMagnetURI(magnet, output);

How it Works

The script uses the webtorrent library to fetch the torrent metadata from the BitTorrent network. Here's a breakdown of what the code does:

  1. Initialization: It initializes the webtorrent client.
  2. processMagnetURI function: This function takes a magnet URI and an optional output directory as input.
  3. client.add: This is the core function that starts the process. It takes the magnet URI and a callback function.
  4. metadata event: The webtorrent client emits a metadata event when it has fetched the torrent's metadata. This is the point where we have all the information we need.
  5. Saving the .torrent file: Inside the metadata event handler, we use torrent.toTorrentFile() to get the torrent file data and then save it to a file using fs.writeFile().
  6. Traversing files: The torrent.files array contains a list of all the files in the torrent. We can iterate over this array to get information about each file, such as its name, path, and size.
  7. Cleanup: Finally, client.destroy() is called to close the client and release resources.

Running the Script

To run the script, use the following command in your terminal, replacing "YOUR_MAGNET_URI_HERE" with a valid magnet URI:

node index.js "YOUR_MAGNET_URI_HERE"

For example:

node index.js "magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent"

You can also specify an output directory for the .torrent file:

node index.js "YOUR_MAGNET_URI_HERE" "./my_torrents"

After running the script, you will see the list of files in the torrent printed to the console, and a new .torrent file will be saved in the specified output directory.

Share Node: