Serve the current directory over HTTP
Spin up a throwaway HTTP server that exposes the current directory — for ad-hoc file sharing, local QA, and sending a static build over your LAN.
How to serve the current directory over http in each shell
python3 -m http.server 8000Binds to `0.0.0.0` by default (visible on the LAN). For loopback only: `python3 -m http.server 8000 --bind 127.0.0.1`. Serves `index.html` if present, directory listing otherwise.
python3 -m http.server 8000python3 -m http.server 8000python3 -m http.server 8000Same one-liner where Python is installed (the official installer adds it to PATH). Native-pwsh alternative: 4 lines of `[System.Net.HttpListener]` (see notes) — useful when Python is not on the box.
python -m http.server 8000cmd has no native HTTP server. If Python is missing, `npx serve` (requires Node) or download the standalone `dotnet-serve` (`dotnet tool install --global dotnet-serve`) are common 1-binary alternatives.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **`python3 -m http.server` is the most portable answer** — present on every macOS (since 12.3), every modern Linux distro's base install, and the official Python.org Windows installer. Defaults: binds `0.0.0.0:8000`, serves the current directory, single-threaded (one request at a time — slow for large transfers). Multi-threaded variant since Python 3.7: `python3 -m http.server --bind 0.0.0.0 8000 --directory /srv/files` (`--directory` was added 3.7, `--bind` was 3.4). The legacy `python -m SimpleHTTPServer 8000` (Python 2) is GONE on macOS 12.3+ and most distros since 2020 — paste-of-old-blog-posts trap.
- **Non-Python one-liners worth knowing**: `npx serve -l 8000` (Node — auto-detects single-page apps and adds fallback routing); `php -S 0.0.0.0:8000` (PHP — runs `.php` files too if any are present); `ruby -run -e httpd . -p 8000` (Ruby ≥ 1.9 — uses WEBrick); `busybox httpd -f -p 8000 -h .` (Busybox — single-binary 1 MB, common on Alpine/embedded); `caddy file-server --listen :8000 --root .` (Caddy — adds HTTPS + auto-cert if you have a real domain); `miniserve .` (Rust binary — `cargo install miniserve`, has QR-code-of-URL flag handy for phone testing).
- **Native PowerShell HTTP server** (no Python/Node/etc.): the .NET `HttpListener` class gets you 90% there in ~10 lines — `$L = New-Object System.Net.HttpListener; $L.Prefixes.Add("http://+:8000/"); $L.Start(); while ($L.IsListening) { $ctx = $L.GetContext(); $path = Join-Path . $ctx.Request.Url.LocalPath.Trim("/"); if (Test-Path $path -PathType Leaf) { $bytes = [IO.File]::ReadAllBytes($path); $ctx.Response.OutputStream.Write($bytes, 0, $bytes.Length) }; $ctx.Response.Close() }`. Gotcha: `http://+:8000/` (URL ACL prefix) requires `netsh http add urlacl url=http://+:8000/ user=Everyone` on first run (admin), OR run pwsh elevated. Production projects prefer `dotnet-serve` (`dotnet tool install --global dotnet-serve`).
- **Bind-address security**: `0.0.0.0` (the default for `python3 -m http.server`, `php -S`, most others) exposes the directory to ANYONE on the LAN — coffee shop wifi included. `127.0.0.1`/`localhost` is loopback-only (safe). For wifi sharing without exposing too widely, bind to the wifi interface IP: `python3 -m http.server 8000 --bind 192.168.1.50`. Anti-pattern: `python3 -m http.server` on a public-IP cloud VM — anyone scanning that port can `curl http://yourvm:8000/.env` (`http.server` blocks dotfiles by default since Python 3.11, BUT `php -S` does not, and neither does WEBrick). For internet-facing transient sharing prefer `caddy` (TLS by default) or `ngrok http 8000` (signed tunnel).
- **Don't serve a build directory while watching it**: most static-site generators (Vite, Next.js, Hugo, Jekyll) atomically rewrite `index.html` mid-build — a parallel `http.server` returning the file at the wrong instant produces `ERR_HTTP2_PROTOCOL_ERROR` or zero-byte responses in Chrome. Use the framework's OWN dev server (`vite`, `next dev`, `hugo server`) which handles atomic swaps. `http.server` is for STATIC content — a finalized `dist/`, a folder of PDFs, etc.
Related commands
Related tasks
- Download a file from a URL— Save a remote file to disk via HTTP/HTTPS, with progress and resume where supported.
- Get the local IP address— Find the IPv4 address your machine is using on the local network — for sharing dev servers, configuring peers, and debugging "why can't my phone reach my laptop".
- Check if a URL is reachable— Test whether a URL returns 2xx/3xx — useful for healthchecks, wait-for-it scripts, and CI smoke tests.
- Test a TCP connection with nc— Confirm whether you can open a TCP socket to host:port — the basic "is this thing reachable" check before debugging deeper protocol issues.