Wes Ellis./ a personal notebook
Technology. Stories. Side projects.
A few things worth writing down.
← Back to Side Projects

Side Projects

YouTube Subscription Copier: Moving Your Channels to a New Google Account

Hands labeling a VHS tape with a marker on a wooden table.

Part 2 of the thread Desktop tinkering

PROJECT AT A GLANCEOpen source
What it is
Web app
My role
Creator
Year
2024
Built with
  • JavaScript
  • Google Identity Services
  • YouTube Data API v3
  • Bootstrap 4
THE SHORT VERSION4 points
  • Sign in to an old and a new Google account, pick the channels, and it subscribes the new one for you.
  • Everything runs client-side in your browser with OAuth; there's no server.
  • The YouTube API quota caps you at roughly 80-100 subscriptions a day, so progress saves and resumes.
  • You need your own Google Cloud project and OAuth Client ID to run it.

YouTube doesn't give you a button to move your subscriptions from one Google account to another. If you're switching accounts, merging a couple, or starting fresh, the official route is to go through your channel list and click Subscribe on each one again. Fine for twelve channels. Not fine for three hundred.

youtube-subscription-copier does the clicking for you. It's a single web page and one JavaScript file that talk to the YouTube Data API on your behalf.

What it does

You sign in with the account you're copying from, it fetches your subscriptions, and you tick the ones you want. Then you sign in with the destination account and start the transfer. It works through the list one channel at a time with a live progress bar, and skips anything the new account already follows.

Version 2.0 added the things that make a real migration bearable:

Feature What it's for
Selective transfer Checkboxes per channel, plus select all / deselect all
Progress persistence Saves where you got to in localStorage so you can resume
Export / import Back up the list to JSON and transfer from the file later
Quota tracking Live API usage bar, with warnings at 70% and 90%
Auto-retry Failed channels retry up to 3 times with backoff
Duplicate prevention Finished channels are tracked and never re-sent

How it works

It's vanilla JavaScript with Google Identity Services for sign-in and Bootstrap 4 for the look. Under the hood it only uses two API calls: subscriptions.list to read both accounts and subscriptions.insert to add channels to the new one.

There's no backend at all. OAuth tokens are temporary and aren't stored, and your subscription list doesn't go anywhere except between your browser and Google.

The quota problem

This is the part to understand before you start. The YouTube Data API gives a project 10,000 quota units a day, and each subscribe costs around 50. That works out to roughly 80 to 100 channels per day in practice. Hit the ceiling and you'll get a 403.

Tip

Export your subscriptions to JSON right after you sign in to the old account. If the quota runs out halfway, your progress is already saved in the browser, and the export means you can pick up later without signing in to the old account again.

When the quota resets the next day, reload the page, sign in to the new account and hit "Initiate transfer." It carries on where it stopped. A big list can take a few days that way, but you only have to babysit it for a minute each time.

Using it

You need your own OAuth credentials. In the Google Cloud Console, create a project, enable YouTube Data API v3, set up the consent screen and create an OAuth 2.0 Client ID for a web application. Add http://localhost (or wherever you'll host it) as an authorized JavaScript origin, then paste the Client ID into the CLIENT_ID constant on line 2 of main.js.

Opening index.html straight from disk can trip up OAuth in some browsers, so run a quick local server instead:

python -m http.server 8000

Then open http://localhost:8000. GitHub Pages works too, as long as you add that URL to your authorized origins.

Error Usually means
401 Unauthorized The Client ID in main.js is wrong
403 Forbidden Quota's gone for the day
OAuth popup blocked Allow popups for the page

Rough edges

Setting up a Cloud project is the biggest hurdle, and there's no way around it with this approach. Some channels simply won't transfer because they're restricted or unavailable, and large transfers are deliberately slow to avoid throttling.

Note

It's a personal project, not affiliated with Google or YouTube. Use it within YouTube's Terms of Service and the API limits.

It lives in the same drawer as a couple of other browser-side helpers I've built, like a custom new tab page and Browser Profile Icons, which is handy if the reason you're moving accounts is that you've got too many of them.