The short answer
In 2026, develop on HTTPS by default. Most browser APIs that touch user data, sensors, or persistent storage require it, and so do every OAuth provider, payment gateway, and webhook signing scheme.
The remaining cases where plain HTTP is fine: pure server-side hello-world, internal CI test harnesses, and tooling pipelines. Anything a real browser will load — switch to HTTPS.
What breaks on plain HTTP
A non-exhaustive list of features that throw or silently fail on http://localhost in 2026:
- Service Workers — registration is HTTPS-only (with a localhost exemption that doesn't extend to LAN IPs or tunneled HTTP URLs).
- Web Push — requires service workers, so HTTPS.
- Geolocation —
navigator.geolocationrequires a "secure context". - Camera / Microphone —
getUserMediarequires a secure context. - Web Bluetooth / USB / Serial — secure context required.
- HTTP/2 + HTTP/3 — virtually all browser implementations are HTTPS-only.
- Cookies with the
Secureflag — won't be set over HTTP. SameSite=Nonecookies — must also beSecure; effectively HTTPS-only.- Mixed content — an HTTPS page loading HTTP resources is blocked.
- CORS preflight + credentials —
Access-Control-Allow-Credentialssemantics differ subtly under HTTP.
A separate category: third-party services that enforce HTTPS regardless of what the browser does:
- OAuth providers (Apple, Google, Facebook, GitHub) — most reject HTTP redirect URIs outright.
- Payment processors (Stripe, Plaid, Adyen) — webhook endpoints and checkout returns must be HTTPS.
- App stores — iOS App Transport Security blocks plain HTTP traffic from the app side.
The localhost exemption
Browsers treat http://localhost (and http://127.0.0.1) as a secure context for most APIs, intentionally. This means in pure local dev, plain HTTP gets you most of the way.
The exemption breaks down when:
- You access from another device on your LAN —
http://192.168.1.42:3000is NOT a secure context. - You want to test from a phone — see above.
- A third party (OAuth provider, webhook) needs to call your URL — they don't see localhost; they see whatever public name you've given.
How to develop with real HTTPS
Three options that work in 2026:
Option 1: A tunnel service
Run an agent that gives your localhost a real, certificate-valid HTTPS URL on the public internet. ngrok, lrok, Cloudflare Tunnel are the popular ones.
$ lrok http 3000
Forwarding https://violet-mole.lrok.io → http://127.0.0.1:3000
Cert is real — Let's Encrypt at the edge. Browsers, OAuth providers, and webhook senders all accept it the same way they accept your prod URL.
Option 2: mkcert + local CA
mkcert installs a local certificate authority on your machine and issues HTTPS certs for localhost / *.test / arbitrary names you pick. Real HTTPS on https://localhost:3000, no tunnel.
Tradeoff: Per-machine setup. Trust must be installed on every browser and every device that hits the URL. Mobile testing requires manually installing the CA on the phone — moderate friction.
Option 3: Caddy / Traefik with their built-in dev TLS
Caddy and Traefik both ship local-TLS modes that issue self-signed certs automatically. Same trust-on-each-device friction as mkcert.
What I'd pick
For most dev work: a tunnel service. The same URL works from your laptop, your phone (cellular, no LAN required), and external services. Single config, no per-machine cert management.
For air-gapped / offline dev: mkcert.
Walkthrough for various stacks — Next.js, Django, Rails, Go, etc.