I recently built NoSub, a browser-based VOD player for Twitch and Kick.
The goal was simple at first: paste a Twitch or Kick VOD link and watch it in a cleaner player. But the project quickly became more interesting once I started adding synced chat replay, clip creation, streamer pages, multilingual SEO pages, and safe ad integration.
NoSub does not host VODs and does not recover deleted or expired replays. It only works when the replay source is still available.
What it does
- Plays Twitch and Kick VODs in the browser
- Shows synced chat replay when available
- Lets users create clips from VODs
- Supports streamer search and profile pages
- Uses source quality when available
- Has multilingual landing pages for SEO
- Runs as a Flask app with a custom frontend player
The hardest parts
HLS playback
The player has to deal with different stream sources, quality levels, buffering states, and browser differences.
One thing I learned quickly: “the video URL exists” does not mean “the player experience is good.” You still need proper loading states, quality selection, error handling, and fallbacks.
Synced chat replay
Chat replay makes old streams feel alive again.
Without chat, watching an old stream can feel weirdly empty. The challenge is keeping chat aligned with the video timeline, especially when users seek around or when the VOD is several hours long.
Clip creation
I wanted clip creation to feel closer to Twitch/Kick, not just a form with start/end inputs.
The current approach is to let users choose a segment from the VOD timeline, add a title, preview it, and generate a shareable clip page.
SEO
Because the app is mostly dynamic, I added server-rendered metadata, canonical URLs, hreflang tags, sitemap.xml, robots.txt, Open Graph tags, and landing pages for multiple languages.
I also added clean 301 redirects for common search intents, but without creating doorway pages or duplicated content.
Ads without breaking the app
I integrated ads carefully because VOD proxying and hosting can cost money.
The difficult part was making sure ads don’t take over the main app. The solution was to isolate them in a separate frame/service so they can render while keeping the main app protected.
What I would improve next
- More real-world testing on very long VODs
- Better mobile player ergonomics
- More robust clip export options
- Better observability for failed VOD loads
- Cleaner modularization of the frontend code
Live demo
NoSub is available here:
I’d love feedback from people who build video apps, work with HLS, or edit Twitch/Kick content.
What would you improve first: playback reliability, chat sync, clip creation, or mobile UX?