☰

Reddit Reels

Mobile-first full-screen reels for Reddit feeds: swipe, one stream with sound, Reddit video and RedGifs, native voting.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

लेखक
quantavil
दैनिक स्थापनाहरू
1
कुल स्थापनाहरू
18
मूल्याङ्कनहरू
0 0 0
संस्करण
3.2.0
सिर्जना गरियो
2026-09-19
अद्यावधिक गरिएको
2026-10-03
साइज
80.9 के.बी.
इजाजतपत्र
MIT
मा लागू हुन्छ

📱 Reddit Reels

GitHub Runtime: Bun Build: Vite

A mobile-first userscript (Violentmonkey / Tampermonkey; Firefox Android, Kiwi, Safari/Orion, desktop) that turns any Reddit feed into a full-screen, swipeable reel: one post per screen, one stream with sound, Reddit video and RedGifs, native voting.

Tap the Reels button on a feed. The reel opens over Reddit; the phone's Back button (or ✕ / Esc) closes it and leaves you on the post you were watching.


How it works (and why)

The reel is its own full-screen view (shadow DOM, own CSS), not a restyle of Reddit's page. Restyling Reddit's markup breaks whenever the markup differs per device, which is what happened in v2. Reddit's page stays underneath, hidden, as the data source.

Piece How
Posts Read from Reddit's rendered <shreddit-post> attributes (title, author, score, media).
More posts Same HTML endpoint Reddit's feed uses (faceplate-partial[slot=load-after], e.g. /svc/shreddit/community-more-posts/…?after=). New pages are inserted into Reddit's real feed, so they are live posts. No .json API, no rate-limit traps.
Reddit video Direct packaged-media.redd.it mp4 (has audio) when Reddit provides one (re-read when the slide opens, since Reddit fills it in late); otherwise the HLS stream through the full hls.js build (Reddit keeps audio in a separate playlist, which the light build can't play). Native HLS is only a last resort: Chrome claims support but fails Reddit's streams. If a source fails, the next one is tried.
Reddit "gifs" Served as a silent mp4 (preview.redd.it/…gif?format=mp4), played directly. (Before 3.2 they went to the HLS player and failed, e.g. all of r/gifs.)
RedGifs RedGifs API → mp4 → blob. Requests go through GM_xmlhttpRequest because Reddit's CSP blocks redgifs hosts and RedGifs blocks Reddit referrers. If that fails, the slide falls back to RedGifs' own player iframe.
YouTube / Streamable Their embed player, mounted only while the slide is on screen.
Audio One shared <video> moved into the active slide. Only one stream can exist, so no audio bleed. Once your first tap has played it, mobile browsers keep allowing sound on later slides.
Voting Clicks Reddit's own vote buttons inside the post, so auth and CSRF stay Reddit's. Logged out → a "log in" toast.
Text posts Full-height story: the title is sized by length, the body keeps Reddit's formatting (paragraphs, lists, quotes, links, spoilers) through an allow-list sanitizer. Long bodies fade out; Read more (or tapping the text) opens a scrollable reader sheet. Back or Esc closes it. The body never scrolls inside the slide, so a swipe always goes to the next post.
App nags Mobile Reddit points post, user and subreddit links at applink.reddit.com, an App Link that launches the Reddit app. They are rewritten to www.reddit.com (tracking params dropped), and the header Open App button is hidden.
Comments Opens Reddit's post page (new Reddit) in a new tab, so the reel keeps its place.
Memory Only the active slide and its neighbours hold images/iframes; far slides are emptied.
Landscape On a phone held sideways, video slides hide the close button, subreddit, title, rail and seek bar (opacity only, so swiping stays smooth). A tap brings them back for 3 s; they stay while paused. Rotating keeps the same slide in view.
Swiping The slide switches only after the scroll settles, and live UI (seek bar, spinner, pulses) sits in a fixed layer above the track. Changing layout inside a scroll-snap track mid-swipe makes browsers snap back, which felt like "swipe twice".

Controls

Gesture / key Action
Swipe up / down, J K, ↓ ↑ Next / previous
Tap Play / pause (first tap after a blocked autoplay turns sound on; a ▶ shows when the browser blocked autoplay entirely)
Double tap Upvote
Tap a long text post / Read more Reader sheet (Back / Esc / ✕ closes it)
Rotate the phone (video) Immersive: only the video; tap shows the controls for 3 s, the next tap plays/pauses
Drag the bottom bar Seek
← → Gallery image, or seek ±5 s
Space Play / pause
M Mute
C Captions (Reddit videos that have them)
F / rail button Fit ↔ fill screen
Back, ✕, Esc Close

Mute is remembered. Vertical videos fill the screen by default; others are letterboxed over a blurred backdrop.


Install

  1. Install Violentmonkey (recommended) or Tampermonkey.
  2. Open dist/reddit-reels.user.js and click Install.
  3. Open a feed on https://www.reddit.com/ and tap the orange button.

hls.js (full build) is loaded via @require from jsDelivr. @connect covers api.redgifs.com / media.redgifs.com; allow it when the manager asks.


Project structure

src/
├── index.ts              # Entry
├── app.ts                # FAB on feed routes, open/close, Back button, comments in a new tab
├── core/route.ts         # Feed-route matcher + client-side navigation watcher
├── feed/
│   ├── extract.ts        # <shreddit-post> → Post (video/redgifs/embed/gallery/image/text/link)
│   ├── sanitize.ts       # Allow-list copy of a text post's markdown HTML
│   ├── source.ts         # Posts in the page + next pages via Reddit's load-after partial
│   ├── vote.ts           # Native vote buttons
│   └── types.ts
├── media/
│   ├── player.ts         # The one shared <video>: mp4 → HLS fallback chain, RedGifs blob, mute, captions
│   └── redgifs.ts        # Token, gif lookup, blob download (GM_xmlhttpRequest)
├── reel/
│   ├── reel.ts           # Overlay: snap track + fixed HUD, settle-based activation, gestures, keys, voting
│   ├── slide.ts          # Slide shell + mount/unmount of heavy content
│   ├── reel.css          # Shadow-root styles (mobile first, phone column on desktop)
│   └── icons.ts
├── page/declutter.ts     # App links → www.reddit.com, hide "Open App"
├── ui/fab.ts             # Floating Reels button (own shadow root)
└── utils.ts
tests/
├── fixtures/feed.html    # Real Reddit feed markup (video+mp4, video HLS-only, gallery, image, text, link)
├── fixtures/extras.html  # Real "gif" post (r/gifs) and formatted text post (r/tifu)
├── fixtures/server.ts    # Serves them + build + a fake load-after endpoint
├── unit/                 # Extractor, feed paging, routes, RedGifs/API retry, source choice
└── reel.spec.ts          # Playwright (Pixel 7): open, swipe, unmount, paging, Back, comments tab, keys

Development

bun install
bun test tests/unit
bun run build            # dist/reddit-reels.user.js (unminified, @license MIT)
bun run test:e2e         # needs the build; PW_CHROMIUM=/path/to/chromium to override the browser

The Playwright Chromium has no H.264 decoder, so e2e tests check sources, slides and lifecycle, not actual decoding. Playback with audio was verified separately in Google Chrome against live mobile Reddit (mp4 and HLS slides).

Known limits

  • RedGifs tokens are tied to the requesting network. Very flaky networks can make lookups fail; the slide then uses RedGifs' iframe player.
  • Logged-out Reddit hides NSFW feeds and asks to log in for votes. The script does not bypass Reddit's age/NSFW gates: confirm once with Reddit's own "Yes, I'm over 18" button, or log in with NSFW enabled in your Reddit settings.
  • Text bodies come from the feed's preview markup; very long posts may be cut where Reddit cuts the preview. Comments opens the full post.
  • The reel reads what Reddit renders; if Reddit renames <shreddit-post> attributes, feed/extract.ts is the one place to update.

License

MIT