Skip to content
Jason Jara
Go back

Shipping an app as a single HTML file

Edit page

Table of contents

Open Table of contents

The constraint

Most web apps assume a server somewhere: an API to call, assets split across files, a deploy step that uploads them. 1up Court Queue couldn’t assume any of that, because of where it gets used.

A badminton session has more players than courts, and someone has to track who’s on, who’s waiting, and who plays next. That someone is standing courtside with a phone, and sports halls are notorious for weak signal. A tool that needs a connection can stop working at the exact moment it’s needed most. So the build target became: one file, no server, works offline by default.

What breaks when you build this way

A single-file build removes a few things most web development takes for granted.

There’s no server-side anything — no API routes, no server-rendered pages, nothing running except what’s in the browser. There’s no code-splitting in the usual sense either. Normally a bundler hands out separate chunks on demand; here, every chunk the app will ever need has to be in the one file from the start, because there’s no second request to fetch anything else.

That means JavaScript and CSS both have to live inside a single HTML payload. The build tooling takes care of the mechanics of combining them, but it does shape what’s reasonable to reach for — a lot of third-party libraries assume they can lazy-load something later, and this build target doesn’t give them that option.

What it buys you

In exchange, the app asks nothing of its environment. Open the file and it runs — no install, no deploy pipeline, no hosting account, no DNS. At a venue with no signal and no Wi-Fi, that’s not a nice-to-have, it’s the difference between the app working and not.

It also changes what “shipping” means. There’s no release process beyond handing someone a file. For a tool built for one specific use — organising a session, courtside, on a phone — that simplicity is worth more than the flexibility a normal deploy would offer.

Two details that make it feel native

Being single-file doesn’t mean being careless about the phone it runs on. Two small things carry a lot of the feel:

Neither detail depends on the single-file build — they’re just the kind of polish that’s easy to skip and obvious when it’s missing.

Try it yourself

The full write-up is on the 1up Court Queue project page, including the stack and the rest of what it does on the court side.


Edit page
Share this post:

Previous Post
Why Image to WebP never uploads your files
Next Post
Planning and building a site through an AI workflow