local-web-server: a modular static and proxy server for front-end work
A lean, modular web server for rapid full-stack development.
At a glance
- What is it?
- local-web-server, the ws command, is a small Node server that hosts a directory, serves a single page application with a fallback rule, proxies matching URLs to a remote API, and enables HTTPS or HTTP2, with a default stack of fourteen middleware. It suits a front-end developer who needs a static host with a proxy in front of an API, and it is a development tool rather than a production server.
- Who is it for?
- local-web-server suits a front-end developer who needs a static host with a proxy to a real API and a SPA fallback rule, and who wants a middleware stack they can trim. It does not suit production hosting, since it is explicitly a development tool, and it does not suit a project that needs a database, an application server or authentication beyond the basic auth middleware in the default stack.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One command hosts a directory, a SPA or a proxy
local-web-server installs a ws command on your PATH, and the basic use is to run it with no arguments in a directory you want to expose.
$ ws
Listening on http://mbp.local:8000, http://127.0.0.1:8000, http://192.168.0.100:8000Navigating to the server renders a directory listing, or your index.html if that file exists. That is the whole baseline, and it is a small thing to have, because serving a front-end build on a phone on the same network is a common need that otherwise means fighting a firewall.
The Single Page Application case is the first real feature. A static host returns 404 for a path like /user/1 or /login, because no file exists at that location, which breaks client-side routing. Passing --spa index.html creates a rule: if a static file is requested, serve it, and if not, serve the specified SPA and let the route be handled on the client.
$ ws --spa index.htmlThe proxy case is the second. Requests matching a pattern are forwarded to a remote server, so a front-end calling /posts/1 reaches a real API without CORS configuration and without a separate mock server.
$ ws --rewrite '/posts/(.*) -> https://jsonplaceholder.typicode.com/posts/$1'The rewrite pattern is a regular expression on the left and a target on the right with a capture group reference. HTTPS and HTTP2 are both flags, --https and --http2, and the server then reports https addresses in its listening line.
The middleware stack is the product
What makes local-web-server modular is that the default stack is a list of separate packages, each doing one thing, and you can replace the whole list with the --stack option. The defaults are, in order: Basic Auth for password protecting a server, Body Parser which makes ctx.request.body available downstream, Request Monitor which feeds traffic information to the verbose output, Log which writes an access log or a stats view to the console, Cors for setting CORS headers, Json which pretty-prints JSON responses, Rewrite for URL rewriting to local or remote destinations, Blacklist to forbid access to sensitive or private resources, Conditional Get for HTTP conditional requests, Mime to customise the mime type returned with static resources, Compress which gzips responses, Spa for single page application support, Static for serving static files, and Index for directory listings.
The dependencies list in package.json shows that each of those is a separate npm package under the lws- prefix, alongside lws itself and a couple of extras, lws-range and current-module-paths for module resolution. The result is that you can install only the behaviour your project needs, which is the personalisation the README describes as small and 100 percent personalisable.
Two of the defaults are worth pausing on for a development context. Basic Auth being on by default is unusual and slightly surprising, and the Blacklist middleware is there to forbid access to sensitive or private resources, which is a sensible default when you are serving a directory that might contain.env files. The Log middleware offers two output formats, an access log and a stats view, and the examples directory holds a recording of the static hosting with both of them. There is also a request monitor feeding the --verbose output, and a --static.extensions option for a default file extension, and the middleware list in the README is described as designed to cover most typical web development scenarios rather than to be minimal.
It is a distribution of lws with a starter pack
The architecture point is in one line of the README: local-web-server is a distribution of lws bundled with a starter pack of useful middleware. The lws project is the underlying framework, and the version pin in the dependencies is lws at 4.2.1. The distinction matters for anyone who wants to change the behaviour, because the underlying framework is where the extension points live and the starter pack is just a preset.
The package itself is a plain ES module, with type set to module, the export pointing at index.js, and the CLI at bin/cli.js under the ws name. The files array in the manifest limits what ships to bin, lib and index.js, so the repository is not published wholesale. The engines field asks for node 12.20 or newer, which is a floor rather than a target, since the project is ES module based.
The programmatic interface is mentioned alongside the command line one, and the ability to attach a custom view to personalise how activity is visualised is listed as a core feature. That custom view is the piece that goes beyond the middleware stack, because it is how the request monitor output and the log formats are rendered. The readme notes that the documentation site has a wiki with the usage guide and the individual tutorials, and the repository holds a test/ directory with a small test-runner based suite.
The project's own documentation is honest about its scope. The stated uses are building any type of front-end web application, static, dynamic, single page app, progressive web app or React, prototyping a back-end service such as a REST API, a microservice, a websocket or a Server Sent Events service, and monitoring activity, analysing performance and experimenting with caching strategy. Every one of those is a development activity.
Where local-web-server is the wrong tool
Three cases argue against it. The first is production hosting. The stated purpose is rapid full-stack development, the default stack includes development conveniences like a pretty-printing JSON middleware and a request monitor, and nothing in the documentation describes a production configuration, a process supervisor, or TLS certificate management beyond a development self-signed setup. If you need to serve a site to real users, a production server is the right category of tool.
The second case is a project that needs more than static files and a proxy. There is no database, no session handling beyond the basic auth middleware, no application framework, and no routing layer for your own endpoints. A backend developer reaching for ws to serve an API will find it serves files and forwards requests, which is a different thing.
The third case is a team that wants one command and no configuration. The default stack is long, and the readme says you can load and use only the behaviour required by your project, which means a custom --stack option and a dependency list you now own. A team that wanted a zero-config static host for a docs build is better served by a much smaller tool.
Two smaller operational points are worth knowing. The default Basic Auth middleware means a server started with no arguments may present a credential prompt, which surprises people the first time. And the release discipline is uneven: v5.4.0 was tagged in August 2024, v5.3.0 in February 2023 and v5.1.0 in August 2021, with the last push on 2026-10-14, so the readme's request that upgraders read the release notes is worth heeding, because the defaults have changed across those versions.
The licence is MIT, the author is Lloyd Brookes, and the documentation is generated with jsdoc-to-markdown, which tells you the project is documented from its own source comments rather than kept separately.
Editorial conclusion
local-web-server suits a front-end developer who needs a static host with a proxy to a real API and a SPA fallback rule, and who wants a middleware stack they can trim. It does not suit production hosting, since it is explicitly a development tool, and it does not suit a project that needs a database, an application server or authentication beyond the basic auth middleware in the default stack. Before you adopt it, check the release notes for the version you pin, because the readme asks upgraders to read them, and note that the last push was on 2026-10-14 with the newest tagged release v5.4.0 from 2024-08-01.
Frequently asked questions
How do I install and run local-web-server?
Install it with npm install -g local-web-server, which puts the ws command on your PATH, then run ws in the directory you want to serve. It listens on port 8000 by default and shows the local network addresses it is reachable on.
How do I serve a Single Page Application with local-web-server?
Pass the --spa flag with the name of the entry file, for example ws --spa index.html. That creates the rule that a static file is served if it exists and the SPA is served otherwise, so client-side routes like /login no longer return 404.
Can local-web-server proxy requests to a remote API?
Yes, with the --rewrite option, for example ws --rewrite '/posts/(.*) -> https://jsonplaceholder.typicode.com/posts/$1'. The left side is a pattern and the right side is the target with a capture group reference.
What is in the default middleware stack of local-web-server?
The readme lists Basic Auth, Body Parser, Request Monitor, Log, Cors, Json, Rewrite, Blacklist, Conditional Get, Mime, Compress, Spa, Static and Index, and you can replace the whole list with the --stack option.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lwsjs-local-web-server)Was this useful?