History

VaultPlayer was supposed to be a tiny thing for me, friends and family.

That got slightly out of hand.

This is the history of how a half-hour experiment became VaultPlayer — the features, releases, things that broke, questionable decisions, ridiculous growth, and the time I accidentally deleted the fucking server.

If you want the why, that’s Our Origin Story.

This is what the fuck happened afterwards.

  1. It started because Netflix said no

    On 3 May, my Netflix payment declined.

    A normal person would probably have updated their card details.

    I opened an empty folder and started building a movie player.

    About half an hour later, the basic idea existed: search for something, click it, watch it.

    That first evening it went through names like “Play IMDB embed”, “Movies”, and “Movie Player 2026”. It wasn’t even online.

    But that was day one.

  2. Somehow, it became VaultPlayer

    Apparently I wasn’t very good at leaving it alone.

    Within about 48 hours it had movies, TV, episodes, favourites, mobile work and PWA support.

    It also needed a name.

    It had loads of movies and shows. Basically a massive vault full of things to watch.

    And it was a video player.

    So...

    Vault.

    Player.

    Vault... Player.

    VaultPlayer.

    Fuck me, I’m good at this.

    By 5 May, that’s what it was called.

  3. VaultPlayer goes online

    Six days in, VaultPlayer was no longer a search box with delusions of grandeur.

    On 9 May, it went live on vaultplayer.co.uk.

    By the end of this stretch, VaultPlayer already had Featured, Movies, TV Shows, Favourites, Recent Searches and Continue Watching.

    I’d also started adding visitor logging and a service worker, because apparently a thing I’d made six days earlier now needed analytics.

    Anyone who knows me will tell you that I don’t code things by halves.

    I should probably have realised at this point that the “little personal project” excuse wasn’t going to last.

  4. Starting to look like a proper streaming site

    By 21 May, the beta homepage had become the main site, Featured had got better, and the mobile layout had stopped looking quite so much like I’d designed it in a panic.

    Which I had.

  5. Sync v1

    VaultPlayer Sync

    On 5 June I added VaultPlayer Sync.

    Version one was wonderfully sophisticated: type your email address.

    That was basically it. No password. No magic link. Just an email field, and a touching amount of optimism.

    But it meant your searches, watch progress and favourites could finally follow you between devices. VaultPlayer stopped being stuck on one browser.

  6. 1.4.0

    The first version number I can actually prove

    21 June gives us the first VaultPlayer version number I can actually prove without making shit up: 1.4.0.

    That one added a proper title modal — description, trailer, My List — and started showing the app version instead of pretending it didn’t have one.

    If there were public 1.0 through 1.3 releases, I haven’t got the evidence. I’m not inventing them.

  7. Everything fucking broke

    Then the player died.

    Not “it became a bit unreliable.” Not “I decided native playback would be architecturally cleaner.”

    It stopped fucking working.

    Nothing would play for anyone.

    Until then VaultPlayer depended on embedded playback. The “Watch” part of Search → Click → Watch was now somewhat fucking absent.

    VaultPlayer was still small at this point. In the early public months, the visitor logs that actually exist show roughly ten people a day using it — which meant I couldn’t exactly shrug and leave it broken.

    I’d looked at native playback back in May and decided it could wait.

    It could no longer wait.

    Over 11–12 July, I replaced the embedded playback system with VaultPlayer’s own native HTML5/HLS player.

    What started as “oh fuck, nothing plays” became one of the most important changes VaultPlayer ever had.

  8. Well, that escalated quickly

    And then it fucking exploded.

    The early VaultPlayer logs show roughly ten unique visitors a day.

    From 14–31 July, that average was 770 a day.

    By 29 July, it was pushing 1,500.

    I am not going to pretend I can prove the new player caused that. The visitor log is mostly missing immediately before the change, so I can’t even give you a neat before-and-after graph without making shit up.

    What I can prove is that VaultPlayer went native on 11–12 July, and from 14 July onwards the audience went fucking vertical.

    Around the same stretch I also stopped Sync being “just type an email” and made it send a proper magic-link sign-in. The original version was a laugh. This one at least made you prove you owned the inbox.

  9. Subtitles, because of course

    Apparently being able to hear the film wasn’t enough. People wanted subtitles too.

    Fair enough. Captions arrived, with a CC menu so you could actually pick one.

    There is, however, a limit of 100 subtitle downloads a day.

    That’s an OpenSubtitles limit unless I pay them.

    VaultPlayer doesn’t even run ads to pay for the fucking server.

    I’m not paying for your subtitles as well.

  10. 1.9

    Next episode, still in the player

    Because clicking out of fullscreen between every episode is a fantastic way to make people hate you, 1.9 fixed that.

    The next episode could resolve and play inside VaultPlayer, and fullscreen stayed put. Binge watching started feeling like binge watching instead of a part-time job.

  11. 2.0

    Search grows up

    Until 2.0, search mostly meant “tell me what you want to watch.”

    2.0 made it much more dangerous.

    Actor. Genre. Year. Studio. Filmographies. A proper visual refresh. Richer title details, trailers, genre chips, better discovery, and a less miserable PWA install.

    “I want to watch Jurassic Park” became “show me every film with Jeff Goldblum in it”, which is obviously how civilisation progresses.

  12. 2.5

    Things are getting slightly out of hand

    About 16:51 BST. VaultPlayer 2.5.

    Watch Parties came out of beta. Playlists. Up Next. Watch in order. Sharing. Sync wired through the lot.

    If you want to host a Watch Party you need Sync. Joining one, you don’t.

    The amount of stuff that landed in a very short stretch of August is slightly embarrassing. I was not, at this point, still pretending this was a weekend project.

  13. TV

    VaultPlayer gets on the telly

    A couple of days earlier, I’d started building an Android version of VaultPlayer.

    There was a reason for that.

    My soon-to-be girlfriend’s dad wanted VaultPlayer on his Fire TV Stick.

    I hadn’t even met him yet.

    Apparently I decided the appropriate way to make a good first impression was to put VaultPlayer on his fucking telly.

    So, on 23 August, /tv/ arrived: a proper living-room interface. Big hero, horizontal rows, D-pad navigation, My List, Continue Watching. The Android app knew the difference between a phone and a telly, and VaultPlayer finally escaped the browser properly.

    Later that night, around 21:20, six-digit Sync pairing arrived, because typing an email address with a D-pad is fucking awful. A signed-in device can now sign another one in with a short code. Magic links still work. The remote just doesn’t have to suffer them.

  14. Apparently servers cost money

    By late August, VaultPlayer had grown enough that the server infrastructure needed upgrading.

    Which was great.

    Except servers, somewhat inconveniently, cost money.

    VaultPlayer is free. It doesn’t run ads. I’d quite like to keep it that way.

    So, for the first time, I put up a Support Us notice.

    The maths was basically this: if one in five people threw in a one-off £5, it would help cover the increased server costs without turning VaultPlayer into an advert with a video player attached.

    No subscriptions. No paywalls. No “premium” VaultPlayer.

    Just:

    If you use it, like it, and have a fiver spare — brilliant.

    If you don’t, keep watching.

  15. Important infrastructure update

    Soon-to-be girlfriend became girlfriend.

    This had absolutely nothing to do with VaultPlayer.

    Anyway.

  16. The Great VaultPlayer Deletion of 2026

    On 3 September, at about 01:42 BST, I was deploying a beta VaultPlayer update.

    I was supposed to go to bed at midnight. 1am at the absolute latest. I had to be up early to take my grandfather to a hospital appointment.

    I stayed up.

    Something went catastrophically wrong.

    The deployment was supposed to affect only the VaultPlayer application. Instead, it escaped the application directory and affected the server root.

    It did exactly what it was told to do.

    Unfortunately, what it had effectively been told to do was:

    delete the server.

    Last recovered visitor activity: 01:42:18 BST. The destructive deployment started at 01:42:31. About thirteen seconds later, VaultPlayer was gone.

    I’d managed to delete the server.

    By about 3am, I’d had a “small” amount of rum, a brief little cry, and started the five-hour download of the 79GB fucked disk image for forensic recovery.

    I went to bed.

    I still had to take my grandfather to that hospital appointment in the morning.

    When I got home, I started rebuilding.

    Over the next nine hours, I rebuilt VaultPlayer from the last known-good release while digging through the disk image to recover whatever I could.

    There had been 157 historical Sync accounts.

    I found all 157.

    And restored all 157.

    VaultPlayer came back online at about 19:14.

    Somehow, there were now 158.

    Turns out, at 19:16, someone had already created another Sync account.

    It seems people were waiting.

    The recovery work continued.

    By 01:41 on 4 September, VaultPlayer 2.5.82 was fully back up and running.

    One minute short of 24 hours since I deleted it.

    The forensic recovery also gave me a slightly unhinged picture of how far this had gone:

    • 71,161 historical visits recovered
    • 44,480 unique visitor IDs
    • 193 countries & territories
    • 157 / 157 historical Sync accounts restored

    I do not recommend this as a release process.

  17. The telly got a bit less annoying

    Getting VaultPlayer onto the telly was one thing.

    Keeping the bloody thing updated was another.

    So, the Android app can now update itself. No downloading a new APK, finding it, installing it, and generally doing far too much work just because I changed something.

    There were a load of other fixes along the way too. Sync got better at remembering who you are after an update, the Back button now behaves like an actual Back button, and you can finally remove something from Continue Watching without having to pretend you’ll finish it one day.

    I also spent a frankly unreasonable amount of time dealing with playback randomly giving up and dumping people back onto the Fire TV home screen.

    It now has a go at recovering a dead playback session by itself instead.

    Which is probably what it should have done in the first place.

    Still. Progress.

  18. Apparently everything needs its own universe now

    I’d already added Collections so you could watch things in the right order.

    Then I made them work properly on the TV too.

    And because apparently having collections wasn’t enough, some of those collections now have collections.

    Wizarding World and Middle-earth became proper groups, so all the related films and collections can live together instead of being scattered around the place.

    Basically, I accidentally invented folders.

    Groundbreaking stuff.

    Oh, and somewhere in the middle of all this I managed to break the startup screen.

    If you had reduced motion turned on, the VaultPlayer logo would appear for approximately fuck all time before disappearing, leaving you staring at a mostly empty splash screen.

    Turns out I’d very helpfully told the logo to finish its animation almost instantly. The animation ended, the logo became transparent, and VaultPlayer did exactly what I’d accidentally told it to do.

    So I fixed that too.

    Collections got collections. The telly got better. The logo briefly learnt how to disappear.

    Quite a productive Monday, really.

  19. 3.0

    And then there were three

    VaultPlayer 3.0.

    This one got slightly out of hand.

    What started as me building a Kids version of VaultPlayer somehow turned into three separate versions of the entire thing.

    There’s now VaultPlayer, VaultPlayer Kids and VaultPlayer Teen.

    Kids is brighter, louder and considerably more colourful, with its own catalogue built around age-appropriate stuff.

    Teen sits somewhere between Kids and the normal VaultPlayer. Less childish, still its own thing, and now apparently light blue because I changed my mind about the colour at the last possible moment.

    Both have their own web experience, TV version, branding and app. They’re not switches inside normal VaultPlayer pretending to be different — they’re actually separate versions of it.

    And because apparently making two new versions wasn’t enough, I decided they should all launch together as VaultPlayer 3.0.

    Naturally, the Fire TV artwork decided to be a pain in the arse on launch day as well, so I spent part of the morning fixing manifests, rebuilding apps and persuading Fire TVs to display the right bloody banners.

    Eventually, all three made it out.

    Three experiences.

    One increasingly ridiculous VaultPlayer family.

  20. Well, that lasted 2 hours and 22 minutes

    VaultPlayer 3.0 had been live for exactly 2 hours and 22 minutes.

    Naturally, something broke.

    A few playback sessions were being handed manifests which had already expired by the time the player tried to use them.

    VaultPlayer would find the stream, open the player, get everything ready and then discover that upstream had effectively changed the locks while it was walking to the front door.

    So 3.0.1 arrived.

    More recovery logic. Better handling of dead manifests. More attempts to quietly fix playback in the background instead of throwing the viewer back out and making it their problem.

    It also became the first release in what was about to be a fairly ridiculous couple of days.

    Because while I was fixing VaultPlayer, I decided it would also be a good time to change how I release VaultPlayer.

    Excellent timing.

  21. I gave the deployment scripts buttons

    I've had automated deployment for a while.

    VaultPlayer was already built and deployed using command-line scripts. They packaged everything up, sent it to the VPS, created proper releases, switched production over atomically and kept the previous versions around so I could roll back if I'd done something stupid.

    It worked.

    What it didn't have was a GUI.

    So I built one.

    VaultPlayer Deployment Manager.

    The original idea was basically to put a nice Windows interface over the command-line system I was already using.

    Build & Deploy.

    Rollback.

    Couple of buttons.

    Job done.

    Obviously that's not what happened.

    It started reading the current live version itself.

    Then it started managing the next version.

    Then the release codenames.

    Then it learned the rules around patch, minor and major releases.

    Then GitHub got involved, so a release could be versioned, packaged, committed, pushed, uploaded and deployed as one process.

    And that's roughly where my nice simple GUI briefly became significantly less reliable than the command-line scripts it was supposed to make easier.

    There were WSL path problems.

    SSH sessions hanging around forever.

    Git getting itself involved in things Git had no business getting itself involved in.

    At one point Build & Deploy refused to cooperate so thoroughly that I used the Rollback button to deploy the version I actually wanted.

    It worked.

    I'm choosing not to question that.

    This is also why GitHub contains eighteen separate commits called Release VaultPlayer 3.0.2.

    Eighteen.

    I wasn't releasing the same update over and over because I thought everyone desperately needed another 3.0.2.

    I was testing the thing that releases the releases.

    Repeatedly.

    Somehow 3.0.3 even appeared in the middle of them, after which I went straight back to releasing 3.0.2 again.

    Don't worry about it.

    Eventually it all behaved.

    The command-line deployment system is still there underneath everything, doing the actual work it always did.

    Now it just has a proper Windows GUI on top, knows what version VaultPlayer is, handles the release information for me, talks to GitHub and gives me significantly fewer opportunities to forget a step.

    Which is useful, because apparently deploying my streaming site now requires its own application.

  22. My girlfriend would quite like the film to actually play

    There's a slightly strange thing about building VaultPlayer now.

    It isn't just me using it anymore.

    It hasn't been for ages, obviously, but somewhere along the way it stopped feeling like a website I was building and started becoming something people around me just... use.

    My girlfriend is one of them.

    We met through FiveM, she started using VaultPlayer, and now she's regularly there while I'm working on the bloody thing.

    Sometimes literally next to me.

    Which creates a wonderfully effective testing environment.

    Because I can spend hours looking at logs, recovery states, manifests, HTTP responses and playback sessions...

    ...while her contribution to the debugging process can essentially be:

    "It's still not playing."

    And unfortunately that's usually the more important observation.

    The manifest problem from 3.0.1 wasn't completely dead.

    It had just become more interesting.

    A few people were still occasionally getting stuck on:

    Upstream manifest expired — refreshing...

    Sometimes VaultPlayer recovered.

    Sometimes it apparently interpreted "refreshing" as a long-term career choice.

    So out came the logs.

    And 3.0.4 and 3.0.5 became another round of teaching VaultPlayer not to trust anything upstream tells it.

    It now checks HLS manifests more carefully before giving them to the player.

    If a source is already returning a definite 401, 403 or 410, VaultPlayer can reject it there and then instead of letting the player waste time discovering the same thing.

    But even that wasn't quite enough.

    Because some streams that look dead aren't actually dead.

    They need their URL preparing first.

    They might redirect.

    They might need their authentication refreshing.

    Some will return 401 and then work perfectly happily once VaultPlayer rebuilds the request.

    So the checks now behave much more like real playback does.

    In other words, before VaultPlayer declares a stream dead, it gives the bastard every reasonable opportunity to prove otherwise.

    All of this happens because the person watching doesn't care what an HLS manifest is.

    Nor should they.

    They clicked Play.

    The fucking thing should play.

  23. 3.0.8

    3.0.8

    Somewhere between fixing playback and testing it, the deployment system managed to find another problem.

    VaultPlayer uses atomic releases: each version lives separately on the server and production switches from one to another.

    Nice and clean.

    Except PHP's OPcache could occasionally keep hold of code from the version I'd just replaced.

    Meaning the server could quite correctly say:

    Yes, 3.0.7 is live.

    While PHP was effectively standing behind it whispering:

    3.0.6 though.

    So deployment now restarts PHP-FPM after switching releases and checks that it actually comes back.

    If something goes wrong, the rollback process accounts for that too.

    Because apparently "put the new version on the server" needed several additional definitions.

    And with that, at 23:09 on 10 September, VaultPlayer reached 3.0.8.

    Eight patch numbers beyond 3.0 in a little over two days.

    Some were playback fixes.

    Some were deployment fixes.

    Some existed because Deployment Manager and I were having creative differences.

    But underneath all of that chaos, VaultPlayer came out better.

    Playback recovery got smarter.

    Dead manifests get caught earlier.

    Upstream authentication gets another chance before a stream is abandoned.

    Deployments became safer.

    GitHub became part of the release process.

    And the command-line tools I've been using to deploy VaultPlayer now have a proper application sitting on top of them.

    Meanwhile my girlfriend can continue doing arguably the most important part of VaultPlayer quality assurance:

    Sitting there trying to watch something and immediately discovering whatever I've just fucking broken.

    3.0.8.

    I think that's enough VaultPlayer for two days.

    It probably isn't.

  24. It wasn't

    Turns out 3.0.8 had been broken since I deployed it.

    I just hadn't noticed.

    Because after spending two days fixing playback, improving deployment and building increasingly elaborate ways of checking whether streams actually worked, I had neglected one final piece of the release process:

    Actually opening a fucking title.

    The site itself worked.

    You could open VaultPlayer.

    You could browse.

    You could search.

    Everything looked perfectly healthy.

    But every single title was returning Error 500.

    And had been since 3.0.8 went live.

    For 78 minutes.

    And apparently, during those 78 minutes, not one person thought:

    "Maybe I should tell him."

    Not one bug report.

    Nothing.

    I built an actual bug reporting system into VaultPlayer specifically so that when something breaks, people can tell me that something has broken.

    Every single title on the entire fucking site was broken.

    Nobody reported it.

    WHAT THE FUCK DID I IMPLEMENT THE BUG REPORT BUTTON FOR?

    At this point I can only assume everyone encountered Error 500, stared at it thoughtfully, accepted that this was simply what VaultPlayer did now, and carried on with their evening.

    Thankfully, my girlfriend eventually performed both quality assurance and incident detection by trying to watch something.

    She picked a title.

    Error 500.

    Tried something else.

    Error 500.

    Another one.

    Error 500.

    Every fucking title.

    Then she asked:

    "Should I just go on Prime?"

    No.

    Absolutely fucking not.

    There are production incidents, and then there are threats.

    I did not spend the last four months building a streaming platform, three separate viewing experiences, Android and Fire TV apps, Sync, Collections, playback recovery, a bug reporting system nobody apparently fucking uses and an entire Deployment Manager just to lose a viewer to Prime Video because I'd forgotten to perform the revolutionary testing procedure of clicking on something.

    So I did what any responsible developer would do.

    I rolled the entire fucking thing back to 3.0.1.

    Yes.

    3.0.1.

    The version from two days ago.

    After eighteen separate 3.0.2 commits.

    After 3.0.3.

    After 3.0.4.

    3.0.5.

    3.0.6.

    3.0.7.

    And 3.0.8.

    Two days of increasingly elaborate fixes, recovery logic, deployment changes and attempts to make playback more reliable...

    ...and production was now running 3.0.1 again.

    Because 3.0.1 actually fucking worked.

    VaultPlayer wasn't fixed.

    It had retreated.

    But my girlfriend didn't have to go on Prime.

    That counted as a win.

  25. 3.0.9

    Fine. 3.0.9.

    The retreat lasted about fifteen minutes.

    Because obviously I wasn't actually going to leave it on 3.0.1.

    The Error 500 problem was tracked down to the newer playback preflight code.

    And after two days of playback recovery changes, eighteen 3.0.2s, several more versions, an emergency rollback and my girlfriend threatening to abandon VaultPlayer for Prime, the catastrophic bug responsible for making every single title return Error 500 needed this added:

    $config

    That's it.

    $config.

    The preflight callback was using the configuration, but $config hadn't been included in the variables passed into it.

    One missing variable.

    Every title fucked.

    Add $config.

    Everything works again.

    Computers are brilliant. I hate them.

    So the fix went in, the newer code came back, and at 00:42, VaultPlayer 3.0.9 was committed.

    To recap:

    23:09 — 3.0.8.

    Deploy it.

    Don't test a title.

    Every title is fucked.

    Remain blissfully unaware.

    Nobody files a bug report.

    00:27 — my girlfriend tries to actually use VaultPlayer.

    Discover every title is fucked.

    Girlfriend threatens Prime.

    Rollback to 3.0.1.

    Discover missing $config.

    00:42 — 3.0.9.

    Everything works again.

    Fifteen minutes from "fuck it, roll everything back" to discovering that the difference between VaultPlayer and an extremely elaborate collection of Error 500 pages was:

    $config

    Prime remained closed.

    That's the important bit.

    Oh, and the loading spinner has apparently developed a personality of its own.

    It still works.

    It just does its little dance differently now.

    I looked into it.

    Nothing's actually broken.

    So, after the events of the last 78 minutes, I've consciously decided not to fucking touch it for once.

    This is what personal growth looks like.

  26. This is apparently what personal growth looks like: Part II

    Having concluded at 00:42 that perhaps I should stop touching things that weren't broken, I naturally spent the rest of the day building VaultPlayer 3.1.

    Sort of.

    I haven't actually called it 3.1 yet.

    Because I've learnt things.

    Collections arrived back in VaultPlayer 2.5 as a way of putting films and shows into an order that actually makes sense.

    Since then they've become considerably more elaborate.

    Collections can contain other Collections.

    Different parts of VaultPlayer can have different ones.

    There's release order.

    Chronological order.

    All very clever.

    Administratively, however, they were fucking ridiculous.

    The Collection catalogue lived in the code.

    Which meant adding something to a Collection meant changing the code.

    Removing something meant changing the code.

    Changing an order meant changing the code.

    New Collection?

    Code.

    Artwork?

    Code.

    Then deploy VaultPlayer.

    This seemed like a perfectly acceptable arrangement right up until last night, when deploying VaultPlayer resulted in every title on the website becoming an Error 500 page for 78 minutes.

    Suddenly "maybe changing a Collection shouldn't require a production deployment" felt like quite a good idea.

    So today I built the thing Collections probably should have had in the first place.

    An editor.

    Collections now have their own section in VaultPlayer Admin.

    I can create them there.

    Edit them.

    Add and remove things.

    Reorder them.

    Give them artwork.

    Preview them.

    Control where they appear.

    And, most importantly:

    Save them without changing the fucking VaultPlayer code.

    The old hard-coded catalogue can be brought into the new system, after which Collections live separately from the application itself.

    The website, TV interface, VaultPlayer Teen and VaultPlayer Kids can all read from the same managed Collection data while still showing only what's appropriate for each experience.

    There's proper storage behind it.

    Revision protection so two edits can't quietly trample over each other.

    Artwork gets managed properly.

    The existing Collections can be migrated instead of recreated from scratch.

    And because I apparently haven't completely abandoned yesterday's approach to software development, there are actual automated tests around the thing too.

    Then I deployed it as 3.0.10.

    Not 3.1.

    Because this time, before declaring a major new VaultPlayer feature finished, I thought it might be sensible to actually fucking test it.

    Growth.

    About two minutes later, that testing produced 3.0.11.

    Thankfully, nothing was on fire.

    The new Collections interface just wasn't properly respecting people's VaultPlayer colour themes.

    It had its own colours.

    Which isn't particularly useful when Sync lets people choose how VaultPlayer looks.

    So 3.0.11 taught Collections to inherit the actual VaultPlayer theme instead.

    Backgrounds.

    Panels.

    Borders.

    Text.

    Accent colours.

    Even the TV version.

    Much better.

    And that's where I'm leaving it for now.

    The new Collections system exists.

    It's running.

    It's being tested.

    But it is not VaultPlayer 3.1 yet.

    Last night I deployed something, assumed it worked and went about my evening while every title on VaultPlayer was completely fucked.

    Today I've built something much bigger and deliberately not slapped the new version number on it until I'm happy it actually works.

    This is what personal growth looks like.

    Apparently it took $config.

Search → Click → Watch → $config