Dumbify
YouTube without the distractions. No thumbnails, no autoplay, no ads, no shorts; just videos you wanted to watch."
Inspiration
Sometimes it feels like every social media platform is optimizing for retention. We remember YouTube when it was much simpler. Now, we have thousands of creators optimizing their thumbnails for grasping your attention, and YouTube optimizing everything for retention.
We want our choice back. We aren't building another social media platform. We aren't building another app. This simple chrome extension sits on top of YouTube.com, keeping everything you love and getting rid of things you don't.
What it does
Dumbify replaces YouTube's UI before it renders. Feeds become text rows — title, channel, views, date, duration. Home, search, history, subscriptions, channels, playlists, all of it.
The watch page keeps YouTube's real player, relocated into a minimal frame, so quality, speed, captions and fullscreen still work. Around it: title, collapsible description, and full comment threads.
Subscribe, like, reply, and save to playlists all hit YouTube's own API with your own session. Then you make it yours: day/night, 8 font families, 14–32px, custom text colors, custom background images with an opacity slider.
How we built it
Manifest V3, plain TypeScript via Vite, hand-written CSS, zero runtime dependencies. Only two permissions needed: storage and scripting. Storage for keeping your saved settings in persistent memory, and scripting to read YouTube's DOM.
We used the assistance of Claude Code and other frontier AI models.
Challenges we ran into
A moving target. YouTube's markup and JSON shapes drift constantly, so we tried four ways to get data reliably: inline scripts → MAIN-world bridge → fetch the HTML → scrape the DOM. If strategy $i$ fails with probability $p_i$, the pipeline only fails when all four do.
The isolation wall. Content scripts see the DOM but can't see window.ytInitialData. Everything routes through a background worker firing chrome.scripting.executeScript into the MAIN world, which makes every read async and failable.
Authentication. SAPISIDHASH depends on cookies and wall-clock time, and fails differently when it's subtly wrong versus completely wrong.
SPA navigation. YouTube does no page loads, so we hook pushState, popstate and yt-navigate-finish in order to refresh and add new videos when scrolling.
Accomplishments that we're proud of
- 23 (and counting) ACTIVE USERS in the first 28 days of launch
- Fallback for critical error When everything breaks, Dumbify sets
html.df-failedand steps aside. In the worst case, a broken Dumbify just gives you back regular YouTube. - Real data modification Subscribing, commenting, and playlists actually work, through YouTube's own endpoints.
- Nothing leaves the tab. No server, no telemetry, no accounts.
- Consistency - You will never see flashes of YouTube. We thoroughly tested edge cases before production.
- Zero runtime dependencies.
What we learned
- Learned about YouTube's JSON and DOM content
ytInitialDataandytInitialPlayerResponsegenerate everything before the page loads. - InnerTube is the API behind every button. One internal endpoint, gated by a
SAPISIDHASHheader built from your cookie and a timestamp. Getting that hash right was the moment this became a real client. - CSS is a difficult when the YouTube owns the page. YouTube sets
html { font-size: 10px }. Our entire UI rendered at 60% scale until we found it.
What's next for Dumbify
- Keyboard-first navigation all the way down (
j/kthrough a feed, never touch the mouse, Vim-style) - Custom GIF backgrounds.
- Per-channel mute rules.
- An export button
Log in or sign up for Devpost to join the conversation.