On this page
- lokal.toml and lokal up: one command starts a repo’s whole stack (built)
- LAN mode: open your dev URLs on a phone
- lokal run <service> -- <command>: no port numbers at all (built)
- Error trips: show the coding agent where an error started
- lokal share: public URLs for a dev stack, through Cloudflare Tunnel
- Smaller items
These are the ideas planned for after v0.1.
Note: Apart from
lokal run(released in 0.2.0) andlokal up(released in 0.3.0), nothing on this page is built yet, and the details may change. Each item needs an update to the spec before work starts. Items that change lokal’s security requirements also need explicit sign-off.
Feedback is welcome. If one of these would help you, or you’d design it differently, open an issue.
lokal.toml and lokal up: one command starts a repo’s whole stack (built)#
Released in 0.3.0. A repo commits a lokal.toml, and lokal up routes every service in it in one
reload, then starts each service’s run in its own process group with PORT, {port} and LOKAL_URL_<SUB> for
every service, prefixes each line of output with the service’s name, and prints
✓ ready: N/N services accepting connections. Each service’s output also goes to a log file that
lokal logs <service> reads. Ctrl-C stops every service and keeps the routes, and lokal down removes them. A
person approves a file’s commands before they first run, and again after it changes. A server that listens on
another port gets lokal run’s wrong-port hint, and one whose port turns out to be taken is retried once on a new
port. The command reference has the details.
LAN mode: open your dev URLs on a phone#
Why. Test a project on a real phone on the same Wi-Fi, with a valid certificate.
Sketch.
- Opt-in per project (
lokal lan on -p shop), off by default, and clearly shown instatusanddoctor. - A phone can’t send
.lokallookups to lokal’s DNS server, so LAN mode would bring.localnames back for the opted-in projects (https://api.shop.local): published over mDNS on the real network interfaces with the Mac’s LAN addresses. lokal served.localnames on the Mac itself until 0.6.0. Accept connections on the LAN address only for those names. lokal lan profilewrites a configuration profile with the CA for iOS (Android needs a user CA). The CA’s name constraints still limit what it can sign to.lokaland.local.- This changes the “listeners are loopback-only” rule, so it needs a security review first. Open questions include pairing or client allowlists, and warnings on untrusted networks.
lokal run <service> -- <command>: no port numbers at all (built)#
Released in 0.2.0. lokal run web -- npm run dev picks a free port (or reuses the service’s), routes
https://web.<project>.lokal to it, and starts the command on it with PORT=<port>, a {port} placeholder for
servers that ignore PORT, and LOKAL_URL_<SUB> for every service in the project. It prints
✓ ready: https://… once the server accepts connections, and exits with the command’s exit code. The
command reference has the details. lokal up builds on the same code.
Error trips: show the coding agent where an error started#
Why. When several services run together, the service that shows an error is rarely the one that caused it.
lokal sits in the request path and, with lokal up, owns every process’s output. So it can show the whole trip
of a failing request and name the service where it started.
error trip req a1f3 (412 ms)
console.shop.lokal GET /billing → 500 shows "something went wrong"
└─ api.shop.lokal GET /v1/invoices → 500 "upstream auth failed"
└─ auth.shop.lokal POST /introspect → 401 ← origin
auth | token audience mismatch: expected "api", got "console" src/verify.ts:88Principles.
- lokal captures and correlates. The coding agent diagnoses. There’s no model inside lokal.
- Everything stays on the machine: no account, no collector, no required instrumentation.
- Built in small steps, each useful on its own: per-service logs (from
lokal up, above), recorded proxy hops with W3Ctraceparent, alokal events --errors --jsoncommand for agents, request replay with credentials redacted, and later an OpenTelemetry receiver. - Recording requests touches credentials and customer data, so this needs a security review first: local-only,
0600 files, short retention, and
AuthorizationandCookieredacted by default.
lokal share: public URLs for a dev stack, through Cloudflare Tunnel#
Why. Show a running stack to a reviewer, QA, a client or a webhook provider without deploying it.
Sketch.
- You bring your own Cloudflare account.
lokal share --setupconnects it and picks a zone and base name (dev.example.com). lokal share api webrunscloudflaredwith one rule per shared service, pointing at lokal’s proxy with TLS verification on. Ctrl-C stops sharing and removes the tunnel and its hostnames.- Sharing is always explicit, per command. Nothing is public by default, and lokal’s own listeners stay
loopback-only, because
cloudflareddials out. - Credentials are stored in the macOS keychain. Public exposure needs a security review first.
Smaller items#
- Upstream HTTPS: proxy to dev servers that only speak HTTPS.
service enableandservice disable: keep a service configured but stop serving it.- Shell completions for zsh, bash and fish.
- apt and dnf repositories for Linux: since 0.5.1, each release has
.deband.rpmpackages (Linux (preview)), butapt upgradeanddnf upgradedon’t update them. A signed package repository would.