Background

The origins of SwiftMiner

It started as a favour to a few friends — three copies of TwitchDropsMiner running in a Windows VM on my Mac. Here's how that ended up as a native app.

My friends and I wanted Twitch Drops collected on our accounts, and I was the one with a machine that could sit there doing it. So I ran a copy of TwitchDropsMiner per account inside a stripped-down Windows 11 virtual machine on my Mac.

Starting them was not a matter of double-clicking three icons. A PowerShell script, launch-all.ps1, held the setup together, and by February it had accreted a fair amount. It asked GitHub whether a newer dev build existed and compared the release asset's timestamp against a local version.txt, downloading and unpacking the build only when it had changed, then rebuilt each account's miner as a hard link to one master executable so that three miners didn't mean three copies on disk. They shared a single settings.json. It launched my account first and waited for confirmation that it had actually started before bringing up anyone else's, minimised the windows, and wrote a log.

Update checks, one folder per account, startup ordering, a health check before continuing, logging: the shape of what SwiftMiner does now existed before the app did. It was just held together by a script and a virtual machine.

It worked, in the sense that it usually ran. It also spent a lot of memory and CPU doing it, and when one instance fell over it tended to stay fallen over until I next looked — which meant someone was quietly missing drops while everyone else kept collecting.

Three Twitch Drops Miner windows open side by side inside a Windows 11 virtual machine running on macOS
Three TDM instances in a Tiny11 VM on the Mac, 28 October 2025 — one window per account. A whole guest operating system, running so that three Python windows could sit idle waiting for campaigns.

So I wasn't trying to build a new Twitch Drops miner. I wanted one Mac app that could look after all of our accounts at once, with no virtual machine in the middle. The first idea was the obvious one: keep TDM, run a copy per account, and drive them all from a single native app.

It also explains why SwiftMiner is far more app than mining drops requires. Almost everything in it that looks like over-engineering is a gap this setup left behind — something the script did badly, something that only worked if I was watching, or something nobody but me could see.

The first prototype

That project was called TwitchMiner-Server. I started it late on 15 March 2026. It was a Mac dashboard that launched and managed a separate background miner for each Twitch account.

Each of those background miners was an unmodified copy of TDM — TwitchDropsMiner, by DevilXD — the same program I had been running in the VM. TwitchMiner wasn't TDM, and it wasn't a Mac port of TDM's interface. It was a control panel sitting on top of several copies of it.

The dashboard could start and stop each miner, check whether it was still alive, and collect enough information to show progress. A small translator layer passed updates between the two sides.

The original TwitchMiner dashboard showing two Twitch accounts in a native Mac window
The TwitchMiner prototype on 16 March 2026 — one window showing the status and campaign progress of several separate miners.

It already had the rough shape of SwiftMiner: a sidebar, a Drops view, separate accounts, shared settings, an activity log, start and stop controls, progress per miner. It worked. It also made it obvious how much work it would take to keep the dashboard and all of those separate processes in step.

Why I scrapped it

The design was deliberately cheap: duplicate the miner, give every copy its own folder, gather the results in the dashboard. The Mac app had to launch each copy, keep the accounts apart, read progress updates, and notice when one stopped responding.

That's a reasonable way to test an idea and a poor way to ship one. Every extra friend meant another background process and another set of files. Installing, updating and debugging it would only get worse as the group grew.

It had also inherited the VM's real problem. The dashboard could tell that a miner had stopped, and it could stop and start one again, but that was the entire repertoire. Whatever had actually gone wrong was happening inside a program I hadn't written and couldn't reach into, so restarting it and hoping remained the only repair I had. That was the same position the VM had put me in, with a nicer window around it.

The prototype
One dashboard, several separate miners. Each account ran its own copy of TDM in the background, and the Mac app collected their updates.
The rewrite
One app. SwiftMiner talks to Twitch itself, using frameworks already in macOS, and keeps account details in the Keychain.

Starting again

My first instinct wasn't to start again at all. I began a fork of TDM to give it proper Mac support, and got far enough in to discover that somebody had already done that work. It wasn't wasted time. Going through TDM's internals with the intention of porting them made it clear how much of what I actually wanted wasn't a port: not the same miner with a Mac coat of paint, but something built the way I would have built it in the first place, and that I could fix when it broke.

So on 17 March, less than two days in, I started a fresh project called SwiftTwitchMiner. The background miners went. Signing in, finding campaigns, picking streams, tracking progress and claiming rewards were all rewritten in Swift, directly against the frameworks already in macOS. That was the whole point of the rewrite: owning that code is the difference between diagnosing a failure and restarting a process I can't see into.

TDM was still the best reference I had for how Twitch Drops actually behave, and I used what I'd learned from it while writing SwiftMiner. But SwiftMiner was written from scratch, not converted: it contains none of TDM's Python code and doesn't run TDM in the background.

I didn't switch because TDM had failed — it hadn't. I switched because I wanted a different thing: one Mac app, several accounts, an installer you double-click, and a single interface.

The name

It kept the working name SwiftTwitchMiner until 20 March, when I renamed it to SwiftMiner. The first 1.0 release went out that evening.

Both halves of the name are literal. Swift is the language it's written in, and miner is the word TDM and everything around it already used for a Twitch Drops miner. Neither half is a claim about speed.

By then it wasn't a control panel for other miners any more. The ideas from the screenshot survived — accounts, campaigns, progress, logs — but everything behind the interface was new.

What carried over

The code went. A few decisions didn't:

  1. Accounts stay independent. One person's account breaking shouldn't stop everyone else's, and I should still be able to see the whole group at a glance.
  2. The app says what it's doing. Status, activity, progress and recovery belong in the interface, not in a log file somewhere.
  3. It should behave like a Mac app. One signed bundle, Keychain storage, automatic updates, nothing extra to install.
The SwiftMiner Miners view: a sidebar listing five Twitch accounts, with the selected miner's status, current campaign and campaign queue shown alongside
The same list today: one row per account, with progress and a campaign queue per miner. Five accounts instead of three, and no virtual machine underneath.

Plenty has been added since that week — better scheduling and recovery, a web dashboard, Discord integration through SwiftBot, automatic updates, and a lot of reliability work. The job hasn't changed, though. It still sits on one Mac collecting drops for me and the same friends — five accounts now rather than the three in that screenshot, running 24/7, on a machine that no longer needs a Windows VM to do it.

Why there's so much of it

In the VM, I was the only person who could see whether a miner was running and the only person who could restart one, so every question about someone else's account came to me. The app grew ways to answer those questions without me in the middle: SwiftBot DMs each person when their drop is claimed or their campaign finishes, the web dashboard lets them sign in with Discord and watch their own miner from a phone, and new versions install themselves rather than becoming five separate conversations about downloading a file.

For one person, none of that is worth building. You already have access to the machine it runs on, so you can just go and look.

Credit

SwiftMiner originally used TwitchDropsMiner by DevilXD to run its miners. TDM was also a useful reference while SwiftMiner was being rewritten as a native macOS app.

SwiftMiner is now a separate project, but TDM played an important part in its early development.