I like VS Code's Live Server: click Go Live, the page opens, save a file and it reloads. What I didn't like was everything behind it: a Node.js process, a node_modules tree, and about 230 MB of memory to serve a few HTML files.
So I rewrote it in Rust. live-serve is a single binary of about 3 MB that serves a folder, reloads the page when a file changes, and swaps stylesheets in place without reloading.
Try it
brew install nguyentruong354/tap/live-serve # macOS, Linux
scoop install live-serve # Windows (after: scoop bucket add nguyentruong354 https://github.com/NguyenTruong354/scoop-bucket)
cargo install live-serve # anywhere with Rust
live-serve --open
In VS Code, install the extension live-serve-rs (also on Open VSX for VSCodium, Cursor and Windsurf). It bundles the binary, so nothing else needs installing; click Go Live in the status bar.
What it does
- Live reload over a WebSocket; saving a stylesheet swaps only the sheets from your own origin
-
--httpswith a self-signed certificate made on the fly, or--cert/--keyfor one from mkcert -
--proxy /api=http://localhost:3000so a static frontend can call a local backend without CORS -
--spafor single-page apps,--host 0.0.0.0to open it on your phone - Refuses requests from other websites (DNS rebinding, cross-origin reads) and hides
.envand.git -
live-serve init vscode/init zedadds an editor task to the project
Numbers
Against live-server, the package VS Code's Live Server runs, on the same machine and folder (median of six rounds; method):
| live-serve | live-server | |
|---|---|---|
| Folder listing, 1,200 entries | 2.0 ms | ~48 ms |
| HTML page with the reload script | 0.50 ms | 0.7–1.5 ms |
| First response after start | 44 ms | ~1.4 s |
| Memory | 11 MB | ~230 MB |
Static files cost about the same for both: reading the file and the loopback connection dominate. The difference is everything around the files.
Things that were harder than they looked
The watch dies with the folder. Build tools love rm -rf dist && build. A file watcher on dist stops when dist is deleted, so after the first rebuild nothing reloads anymore. live-serve also watches the parent folder and re-arms the watch when the folder comes back. macOS made this fun: FSEvents can report the folder's creation late, after the removal, so "created" alone can't mean "it's back".
Two programs on one port. On Windows and macOS, one program can listen on 0.0.0.0:5500 while another binds 127.0.0.1:5500, and both succeed. live-serve used to "take" localhost away from a server that was already running. It now checks the other kind of address before binding and moves to the next port.
HTTPS without setup. --https makes an ECDSA certificate with rcgen for localhost, 127.0.0.1, ::1 and, with --host 0.0.0.0, your network address, keeps it in a cache folder and renews it before it expires. TLS is rustls with ring, which added about 1.2 MB to the binary. A plain http:// request to the HTTPS port gets a redirect instead of a confusing error.
CSS swaps and editors. Many editors save by writing a temporary file and renaming it. The reload script has to recognise that the stylesheet changed (not that some random .tmp appeared) and swap only the sheets from the page's own origin, so a stylesheet from a CDN or Google Fonts isn't fetched again on every save.
It's built on axum, tokio and notify.
How it was built
I wrote the core myself and used Claude (an AI assistant) for parts of the HTTPS, proxy and file-watching work, the tests and the release pipeline. I reviewed every change before merging.
Feedback welcome
The code is MIT-licensed on GitHub: https://github.com/NguyenTruong354/live-serve
I'd especially like to hear how the file watching behaves with your build tool, and whether the HTTPS setup works on your machine. Issues and PRs are welcome.

Top comments (0)