For years, I tried to convince developer friends to build a scuba-focused site where my dive buddies and I could share videos. I even thought there was a nugget of a lifestyle startup in it: adventure sports video combined with activity-specific metadata and enrichment. The chats over coffees and beers never led to anything. About a year and a half ago, I started to explore “vibe coding” and copy-pasting code out of ChatGPT. Before specialized coding tools shipped, the process wasn't exactly smooth. Then, last spring, I picked the project back up with Claude Code. A month and roughly 200 commits later, I had a working video sharing site for my buddies and me. I named it ScubaTube, and I've kept building on it ever since.

I haven't done any software development in years, but I led product teams in past lives and missed the chance to get my hands dirty like this.
ScubaTube is a small, private-by-default video site for dive footage: upload a clip, tag the dive site on a globe, add depth and water temp, and share it with the people who were on the boat. I dislike the term "dogfooding," but building ScubaTube was a fantastic way to really get to know the latest Mux capabilities, including Mux Robots and Video.js v10.
The requirements
Neither YouTube nor Facebook was a fit for me, for the same reasons Mux customers build their own video products instead of handing their content to an aggregator.
I wanted to own the video. Not in a philosophical way. I wanted the files to be mine and under my control. Portable and exportable so I could use them how I saw fit in the future.
I wanted to share it with actual people. I didn't care about likes and subscribers. This was about sharing directly with local divers and the dive community, with more context than a social feed allows. I have visions of future functionality supporting the community in deeper ways. I’d like to use the site to help organizations I support, like the Sunflower Star Lab and Giant Giant Kelp Restoration Project.
I wanted the quality to hold up. Dive footage is tough on encoders: blue-green color casts (often just green at my home base in Monterey), low light, particulates in the water column, and constant motion. If the pipeline is sloppy or one-size-fits-all, a good dive looks like a bad dive.
I wanted it to survive me. Every video on ScubaTube has a downloadable MP4 behind it. If the site goes away, if I get bored, if Mux pivots to juice machines, the footage is still portable and still watchable. I also wanted real control over embeds and sharing, not the illusion of it. I can picture my favorite dive shop or instructors using the service and dropping videos onto their own sites.
I wanted the dive data, too. Depth, water temperature, whether it was a boat or shore dive, and the specific dive site name (which differs from a general geographic location). Several dive sites often share nearly the same entry point or coordinates, and no general-purpose platform has a structured place for that data. Dive computers capture all of it throughout the dive, and I wanted that on the video too. More on that below.
The curated Claude Code video app stack
I chose two things: Mux for video and Vercel for hosting. I started from Mux’s Next.js example app, which brought Next.js and Tailwind along. Claude Code recommended most of the rest, and I took its recommendations, mostly without arguing. Here's most of the stack:
- Next.js (App Router) for the app itself, a natural fit with Vercel. I picked Vercel because of the long-standing Mux integration.
- Tailwind CSS for styling
- Cloudflare for Turnstile (a CAPTCHA alternative) and domain protection
- Resend for email (a Mux partner, for good reason)
- Mapbox for the dive-site globe and geo-lookup
- Clerk for authentication and user management
- Anthropic’s Claude API for writing SEO descriptions for each video
- Upstash Redis and Vercel Blob for storage instead of a real database. If things get more sophisticated, I’d look at Mux partners Sanity or Contentful (both of which now have plugins integrated with Mux Robots)
Most of these have a generous free tier for hobbyists, which let me build early with minimal spend.

My biggest takeaway from platform selection is that these services have a lot in common: good documentation, versatility, and a strong developer experience (which is increasingly an agent experience). Claude, ChatGPT, and Replit usually recommend Mux for streaming integrations like this. When Claude recommended the other services, I suspect a key factor was agent experience and compatibility. The products that respected my time were the ones I never had to think about.
Taste and product direction matter
I played the role of editor more than engineer. I set the vision and direction, got the basic structure of the site in place, and then added more sophisticated features one at a time. When I wasn't sure what I wanted, I asked for options. The thumbnail picker is a good example: I had Claude build a few versions, tried each one, and kept the best. Other times, I asked open-ended questions and let the answers shape the next round. My job was knowing what looked good and providing direction until we got to a good stopping point. It’s also why I now hate the term “vibe coding.” It diminishes the intentionality and creativity that go into a project, and makes it seem like a haphazard accident if anything useful gets created.
Editing also meant working through a lot of fixes. Some were interesting: the logo clipped in a way that took far more attempts to resolve than it should have, my AI tagging ran twice because the upload page and a webhook were both kicking it off, and the Mapbox globe crashed initially.
Most fixes were unglamorous. The upload flow went through three separate rounds of iteration: adding an elapsed timer and status overlay, making the analysis step non-blocking, and sorting out redirect vs. polling. That's not a dramatic story. It's just the day-to-day grind of building.
Mux’s just-in-time encoding is speedy, and I introduced two little delighters to make the wait time feel even shorter. First, a little scuba trivia while the video is being processed before it’s viewable. Second, an email via Resend that confirms the video is processed.
My favorite story is the clip trimmer. I built it in March with a visual timeline and drag handles, then ripped it out completely because the implementation wasn’t smooth and the UX was clunky. We rebuilt it from scratch in September with multi-segment support, and it took three same-day fixes to stick. Knowing when to throw something away is as much a product call as knowing what to build.
What Mux let me build: Mux Robots, Mux Data, and a dive data overlay
Some of the best moments in the project came when a new capability showed up and I could use it the same week.
Video.js v10 is now GA. I migrated ScubaTube from Mux Player during the beta in August and moved to the GA release when it shipped on October 1. It took only a few minutes, and, to my eye, the player feels more polished and is snappier. I’d also been part of the Video.js beta testing since the spring release, reporting a few bugs along the way, including a CSS conflict between the Video.js skin and Tailwind 3 that went away when I upgraded to Tailwind 4. I’m still finding edge cases specific to my stack. Because Video.js is open source, it’s been rewarding to contribute to the project.
One of the biggest wins of migrating to Video.js v10 was unexpectedly being able to ship one of my dream features: a dive data overlay on top of the video. My Shearwater dive computer is “AI” (air integrated), from before AI was hot. It captures key metrics throughout the dive. This is synced to my Submersion dive log app and exported in standard dive interchange format, UDDF (Universal Dive Data Format), which Subsurface, MacDive, and other dive log apps also export. That data now rides on top of the video, showing depth, air consumption, and temperature throughout the dive. Video.js made it easy to build this interactive overlay without burning it into the video asset.
Anyone who uploads can see engagement and drop-off for their own videos, which is expected on YouTube and a nice feature to carry over here on a hobby site. The watch-time visualization is built from Mux Data's per-view video_completion, averaged across the most recent 100 views of the video.

As I add chapters and longer videos, I expect those engagement insights to get more interesting.
Mux Robots, hosted AI workflows, rolled out progressively while I was building, so I got to integrate several features as they landed:
- Tags, titles, and descriptions are suggested automatically based on what's detected in the video.
- The best thumbnail is selected automatically, and the owner can override it from a thumbnail editor on the watch page by scrubbing to a frame or shuffling through options.
- Captions and translation are available for footage with dialogue. My videos don't have much dialogue, so I used other workflows.
- Chapters are generated visually, not from speech. Mux Robots splits each dive into scenes (now through its analyze_structure workflow), and the site turns those scenes into a WebVTT chapters track for the Video.js player.
The new Mux Robots plugin for Adobe Premiere is great in editing and production mode. I’m able to pull the best thumbnails and automatically break up long dive videos into discrete segments based on the action in the video. This is very helpful when going through hours of dive video from a trip.
TV mode: gapless playback with Video.js v10
My friend Mike wanted a lean-back mode for his TV, so we built TV mode: seamless, gapless, full-screen playback with no controls. It's made for connected TVs, AirPlay, and casting.
The first versions were clunky. A single player loading each new clip left too much of a gap between dives, and a lean-back mode with a visible seam every 90 seconds isn't really lean-back. Claude and I kicked around a few approaches, tested them, and landed on one that worked. It's a great example of what the collaboration feels like: I knew what wrong looked like, and we iterated until it was right.
Under the hood, it uses Video.js v10 (via @videojs/react) and Mux, but the trick is in how it hides transition gaps. Instead of one player restarting between clips, ScubaTube keeps two players active at once, stacked directly on top of each other. While you're watching one video, the next one in the shuffled queue buffers silently in the background. When a clip ends, the app crossfades between the two layers and starts playing the preloaded video. No spinner, no black flash, and no stutter. One dive scene dissolves smoothly into the next, complete with an MTV-style title and location card.
The SEO gap
Back in March, I thought I had set up everything correctly: clean slugs, robots.txt, a sitemap, VideoObject JSON-LD, and a default OG image. Textbook SEO plumbing.
Then, I didn't check on it again for six months.
When I finally ran an audit, I fixed about a dozen things in one day: duplicate page indexing, dead-slug 404s, slow homepage TTFB, missing self-canonicals, an OG image regression, and a description priority bug, among others. The plumbing looked right and went unverified the entire time, which I now think is the characteristic failure mode of building this way. Generated code can look correct and still never be tested against reality. What caught it was a newer model reviewing the older implementation.
What I got that I wasn't expecting
I now understand Mux and the ecosystem around it far better than I did as someone who comes from the commercial side of the business. Our APIs and documentation made the process fun and iterative.
I also gained hands-on experience with agent development, which requires a different skillset than traditional coding, giving me a firsthand perspective on how our customers build today.
And I found out firsthand why Mux keeps coming up in AI tool discovery. When I asked ChatGPT, Replit, and Claude how to build a video streaming product, Mux was the first thing each of them suggested. Having now built on it, I get it.

The idea I'm handing to our product team
I wanted better search, discovery, and metadata for the videos. Mux Robots covered tags, titles, and thumbnails, and captions can only work with what’s said, which isn’t much in silent dive footage.
Now imagine captions generated from what's in the frame rather than what's being said. "Sea lion swims through kelp." "Diver enters swim-through." That one feature would give me navigation, chapter markers, search, SEO, and real accessibility, all from footage that has no dialogue to caption. Anyone with underwater, wildlife, security, sports, or drone footage would benefit in the same way.
I didn't know I wanted this until I'd built a site full of silent video and tried to make it findable. Mux Robots' new Analyze Structure workflow already gets me part of the way there: it gives each scene a short title, which for silent footage comes almost entirely from what’s on screen. Turn that into a real, timed caption track, and pair it with the multimodal search Mux has on its roadmap, and silent footage becomes as searchable as a podcast.
Going forward
The site is in a really good place right now. I’m hoping some more divers jump in and drive the next round of ideas. As the audience grows, I'll likely add post moderation with Mux Robots to keep content on-topic and family-friendly.
Barriers are dropping for new kinds of products and mom-and-pop SaaS. It reminds me of the dotcom boom, when starting an e-commerce site took $1M running on Sun, Oracle, and Cisco. That became $1,000 on LAMP, then $10 on Shopify. Traffic is very low on the site right now, and I’m mostly on free tiers. If I grow it, I’d probably be spending a few hundred dollars a month. Lowering these barriers hopefully drives creativity and opportunity for builders and entrepreneurs of all sizes.



