Skip to content
shellmap

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

Bashunix
python3 -m http.server 8000

Binds 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.

Zshunix
python3 -m http.server 8000
Fishunix
python3 -m http.server 8000
PowerShellwindows
python3 -m http.server 8000

Same 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.

cmd.exewindows
python -m http.server 8000

cmd 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