You have some files — a built site, a folder of images, a single
index.html — and you want to look at them in a browser.
Opening the file directly often isn't enough: file://
breaks relative links, blocks fetch, and makes a service
worker impossible. What you want is a real server, for thirty seconds,
with no setup.
scua serve
That's the whole command. It serves the directory you're standing in and prints the URL:
$ scua serve
scua: serving . on http://127.0.0.1:8000/ (Ctrl-C to stop)
#It won't fail because the port is taken
This is the part worth knowing. Every other one-line dev server stops dead when something is already on its port, and hands you an error instead of a server:
OSError: [Errno 48] Address already in use
scua serve tries the next few ports instead, takes the
first free one, and tells you where it went:
$ scua serve
scua: port 8000 was busy — serving . on http://127.0.0.1:8003/ (Ctrl-C to stop)
It names the port that was busy on purpose. Landing somewhere else silently is how you end up staring at a stale tab showing yesterday's server and wondering why your changes aren't there.
If everything nearby is taken, it asks the operating system for any free port rather than giving up. So the command does not have a "port in use" failure — the only thing that changes is which number you copy.
#Saying which port and which directory
scua serve ./public # serve a particular directory
scua serve --port 3000 # try 3000 first
scua serve 3000 # the same thing — a bare number is a port
scua serve ./public --port 3000 # both
scua serve --port 0 # don't try to guess: give me any free port
#It listens on your machine only
By default the server is reachable from your computer and nowhere else. That is deliberate. The obvious alternative — listening on every network interface — means the folder you happen to be standing in is readable by everyone on the same Wi-Fi, and nothing tells you that has happened.
When you do want that, say so, and you'll be told what you just did:
$ scua serve --host 0.0.0.0
scua: serving . on http://0.0.0.0:8000/ (Ctrl-C to stop)
scua: this is reachable from other machines on your network.
That is the setting to reach a dev server from your phone. It is also the setting to think about for a second first.
#What it serves
index.htmlif there is one, otherwise a listing of the directory, with folders marked and a link back up.- The right
content-typefor around thirty common extensions. Anything it doesn't recognise is sent as a plain byte stream rather than guessed at — a wrong content type is worse than none, because a browser told something is HTML will treat it as HTML. - Nothing outside the directory you named. A URL
containing
.., an absolute path, or a symlink pointing out of the folder gets a 404. This isn't a filter that tries to spot bad paths; the file access itself is confined to that one directory, so there is no path that reaches outside it. - No dotfiles, unless you pass
--all..git/config,.envand.sshare the ones that matter, and serving a project folder is exactly when you'd otherwise expose them. They return 404 rather than 403, so the answer doesn't confirm they exist. - Nothing cached. Every response says not to cache it. A stale asset that won't go away is the second most annoying thing about a dev server, after the port.
#What it is not
It's a development server, and a few limits follow from that:
- No large files. A response is built in memory, so a very large file costs several times its size in RAM and a really large one won't serve at all. Fine for a site; not for a video library.
- No range requests, so seeking within audio or video won't work, and neither will resuming a download.
- A
HEADrequest reports a content length of 0 rather than the size the file would have been. If you're usingHEADto size a download first, it won't tell you what you want. - No HTTPS, no compression, no live reload.
- It serves files and nothing else. There's no way to point it at a script of your own — that's writing a server, which is a different job with a different command.
For a server that answers requests with your own code, see Serve HTTP requests.