New tiny package: spark-html-dev-tls. One command gives your spark dev server local HTTPS, so you can open the app on your phone and actually use the camera, microphone, geolocation, or a service worker while you build.
Why you need it
The browser gates its most powerful APIs behind a secure context:
getUserMedia (camera/mic), geolocation,
ServiceWorker, the clipboard, and more only run on
https:// or localhost. That's fine on your laptop —
http://localhost:3000 counts as secure. But the moment you pull
out your phone to test the real thing and hit
http://192.168.1.20:3000, none of it works. A LAN IP over plain
HTTP is not a secure context, so the camera call silently fails.
The fix is real HTTPS in dev — which normally means fiddling with
openssl, wiring certs into a server, and remembering to undo it.
spark-html-dev-tls does that once, as a wrapper, and leaves your existing
setup untouched.
How to use it
It's purely additive. Keep your dev script exactly as it is
(plain HTTP), and add a secure script next to it:
{
"scripts": {
"dev": "bun spark-ssr",
"secure": "bun spark-html-dev-tls"
}
}
New apps from create-spark-html-app already ship this — every
template (client, SSR, prerender) has the secure script. For an
existing project, add the script and the dev dependency:
bun add -d spark-html-dev-tls
Then, instead of bun run dev, run:
bun run secure
[spark-html-dev-tls] 🔒 HTTPS on :3000 → bun spark-ssr on :3001
local: https://localhost:3000/
network: https://192.168.1.20:3000/ ← open this on your phone
(self-signed — accept the browser warning once)
Open that network URL on your phone, tap through the
one-time certificate warning, and the camera works. That's the whole flow.
What it actually does
It's a small HTTP→HTTPS reverse proxy that runs in front of your normal dev server:
- Auto-detects the mode. A
spark.jsonorpages/folder means spark-ssr; aspark.config.jsmeans spark-html-bun (client-only or prerender). It spawns that exact dev server on a private port. - Generates a certificate covering
localhost,127.0.0.1, and your machine's LAN IPs (so the phone URL validates), cached in.spark/and reused until it nears expiry. It uses your systemopenssl— no npm dependencies. - Fronts it with HTTPS and proxies everything through: plain requests, the live-reload and live-data Server-Sent Events, and the WebSocket hot-reload channel. Hot reload and live updates keep working over the secure connection.
Because an HTTP→HTTPS proxy doesn't care what's behind it, the same one command works identically for SSR, client-only, and prerender apps — no per-mode configuration.
Sessions keep working
The proxy adds an x-forwarded-proto: https header on the way
to your dev server, so spark-ssr correctly marks session and flash cookies
Secure — logins and redirects behave exactly as they will in
production behind a real TLS terminator. Nothing to configure.
Options
Sensible defaults, easy to override:
bun spark-html-dev-tls --port 8443 # pick the HTTPS port
bun spark-html-dev-tls --cert c.pem --key k # bring your own cert (no warning)
bun spark-html-dev-tls -- bun spark-ssr # skip auto-detect; wrap explicitly
Self-signed certs show a one-time browser warning. If you'd rather have
zero warnings — handy when several devices test at once — generate a
locally-trusted cert with mkcert
and pass it with --cert/--key.
A note on scope
This is a dev / testing tool, on purpose. It doesn't
touch your app code, your build, or production — where HTTPS is normally
terminated by your host or a reverse proxy, and the x-forwarded-proto
path already handles it. spark-html-dev-tls exists for exactly one job:
making the secure-context APIs testable on a real device while you develop,
with a single script and no ceremony.
Get it
bun add -d spark-html-dev-tls