How to Change YouTube Playback Speed with a Simple Bookmarklet

When watching videos on YouTube, I often toggle the playback speed to run slightly faster than normal. Recently, however, YouTube's playback speed UI has become strangely inconsistent - some videos still show the speed controls, while others show a locked "1x" option with no way to change it.

Playback Controls
Some have it, some don't!

Fortunately, the solution is simple! Crack open the javascript console, and paste:

document.getElementsByTagName("video")[0].playbackRate = 2

Press enter, and this will select the first video element on the page, and set its playback rate to 2x. You can change the "2" to any other number you like - 1.5 for 1.5x speed, 0.75 for 75% speed, etc.

Nice and easy, though a bit tedious to do every time. Ideally I can click something in the UI, keeping it simple. Enter bookmarklets!

What is a bookmarklet?

Bookmarklets are just browser bookmarks that run JavaScript instead of loading a page. When you click the bookmark, the javascript runs on the current page. It's a nice way to add small bits of functionality to web pages, without needing to install extensions or mess around with userscripts.

What are we building?

What we'd like to do is have a bookmarklet which, when clicked, gives us a simple UI to change the playback speed, then get out of the way. We need a visual indicator of the current speed, and ideally this will persist across video loads.

Interface
Simple interface

There are a lot of fiddly little bits to get right here, which sets off all the alarm bells of a "quick side project that somehow consumes a whole weekend". Fortunately, this is exactly the kind of problem AI helps accelerate - with a one-liner to start with, and a few iterative prompts, the first working version was done in under an hour. AI really makes it faster to take things like this from idea to prototype, with minimal effort - Simon Willison has a great post on this general trend.

There's a lot of boilerplate code to handle UI etc, but some interesting bits around SPA persistence and dark mode detection, which we'll go through below. If you're not interested in the code, and just want the bookmarklet, jump right ahead! Otherwise, let's dig into the code a bit.

The Code

The full code is on the Github repo, with most of it dealing with fairly boilerplate UI plumbing (not my street at all - thanks again, AI agents!). Within the code there are still a few interesting bits to highlight. First, the main function, which applies the saved speed, based on our console one-liner from before:


function r() {
  const v = document.querySelector("video");
  if (!v) return;
  if (window.ytSpeedSaved > 0) v.playbackRate = window.ytSpeedSaved;
}

Persistence Across Video Loads

When watching videos on YouTube, ideally we want the speed settings to persist across video loads. Bookmarklets typically only run inside the context of the current page, lost when a user navigates away from a page. However YouTube being a single page app (SPA) helps us out here. In their web app, clicking between videos doesn't reload the page, but instead swaps out the DOM (including the <video> element) in place. The MutationObserver watches for those DOM changes and re-applies the saved playback speed whenever a new video player appears. It's a lightweight way to maintain state without timers or reloading. This is a bit broad, but works well enough for our simple purposes here!

window.ytSpeedObserver = new MutationObserver(r);
window.ytSpeedObserver.observe(document.body, {
    childList: true,
    subtree: true,
  });
}

Dark Mode Detection

YouTube exposes its theme state via a dark attribute on the <html> element. By checking for that flag, the bookmarklet switches to a lighter pill and config panel in dark mode, keeping everything readable against YouTube's near-black background.

const d = document.documentElement.hasAttribute("dark");
...
pill.style.background = d ? "#eee" : "#222";
pill.style.color = d ? "#000" : "#fff";
Light and dark modes
Light and dark modes

Floating Pill Indicator

When the settings are dismissed, we have a small floating pill which shows the current speed, and clicking it opens the main control panel. It hangs around the bottom right of the screen. However, Safari needs some special hand-holding ("quelle surprise", cries anyone who has spent more than 30 seconds in a web dev career..) Safari sometimes inherits top from global CSS when a fixed-position element re-renders. It'll show it in the right place on initial load, but on subsequent loads it gets confused by some of the styles in the YouTube page, and ends up in the top-right corner. To fix this, we explicitly set the top and bottom styles when showing the pill:

//
// Show the floating pill indicator
//
function show() {
  let i = document.getElementById("ytSpeedIndicator");

  ...
  // Ensure it's visible
  i.style.display = "block";

  // Safari positioning fix
  i.style.top = "auto";
  i.style.bottom = "20px";
}
Showing playback speed
Showing playback speed in a "floating pill"

Installation

To install the bookmarklet, simply create a new bookmark in your browser, and paste the following code into the URL field:

Clicking this bookmarklet on any YouTube video page will bring up the speed controls. Adjust the speed as desired, and close the controls - the speed will persist across video loads, and you can always click the floating pill to bring the controls back up.

Safari Users

Safari has some additional security restrictions around bookmarklets, so you'll need to enable the "Allow JavaScript from the Smart Search field" option in Safari's Developer Settings menu.

Safari security settings
Safari security settings

To do this, first enable the Develop menu by going to Developer -> Developer Settings, and checking "Allow Javscript from Smart Search field". This will allow the bookmarklet to run properly in Safari.

Wrap-up

And that should be that! A simple bookmarklet to toggle YouTube playback speed controls, with persistence across video loads. If you have any feedback or suggestions for improvements, feel free to open an issue on the Github repo.


Build Stuff Speaker

Build Stuff 2025

In December 2025, I'll be presenting Digital Cat-and-Mouse: Strategies to Outsmart Scrapers, Phishers, and Thieves at Build Stuff in Vilnius, Lithuania. From selling 10 Downing St, to moving the Eiffel Tower to Dublin, this talk covers real-world examples of unconventional ways to stop scrapers, phishers, and content thieves. You'll gain practical insights to protect assets, outsmart bad actors, and avoid the mistakes we made along the way!

Get your ticket now (15% off!) and I'll see you there!


Share This Article

Related Articles


More