← All posts
Release

spark-html-dev-tls — test camera & mic from your phone, over local HTTPS

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:

  1. Auto-detects the mode. A spark.json or pages/ folder means spark-ssr; a spark.config.js means spark-html-bun (client-only or prerender). It spawns that exact dev server on a private port.
  2. 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 system openssl — no npm dependencies.
  3. 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

spark-html-dev-tls on npm · source on GitHub.