Front-end work rarely needs a full stack: a one-command static server previews files over http://, which ES modules, fetch() and service workers require.
| Server | Start command | Default port | Best for |
|---|---|---|---|
| Python http.server | python -m http.server | 8000 | Nothing to install |
| http-server | npx http-server | 8080 | Quick static preview |
| serve | npx serve -s | 3000 | Single-page apps |
| PHP built-in | php -S localhost:8000 | as given | PHP without Apache |
| Vite 25,978 | npm 2,036 run dev | 5173 | Instant reload |
| Caddy 7,400 | caddy file-server | 80 | Easy HTTPS |
| nginx 75 | systemctl start nginx | 80 | Production proxying |
Run python -m http.server 8080 --bind 127.0.0.1 and it prints Serving HTTP on 127.0.0.1 port 8080, then logs each request. Keep these servers off the internet: Python's documentation warns that http.server implements only basic security checks, and PHP's built-in server runs a single thread.
Vite
Vite (vite.dev (https://vite.dev/ 25,978 ), MIT) is used by 25.4% of respondents to the Stack Overflow survey 2025; npm create vite@latest scaffolds a React 7,897 , Vue 5,482 or Svelte 36,701 project (MEAN, MERN and MEVN). Vite 8, released on March 12, 2026, replaced its two bundlers (esbuild 126 and Rollup 141,981 ) with Rolldown 181,166 , a single Rust-based bundler.
Caddy and nginx as reverse proxies
In production, one web server usually faces the internet, terminates HTTPS, serves the built front end and forwards API calls to the application server from MEAN, MERN and MEVN-Ruby on Rails on a private port. Caddy (caddyserver.com (https://caddyserver.com/ 7,400 ), Apache 2.0) does this in a few lines and obtains a certificate for the domain automatically; nginx needs more configuration and a separate certificate tool (Securing with HTTPS):
example.com {
root * /srv/notes/client/dist
reverse_proxy /api/* localhost:3000
try_files {path} /index.html
file_server
encode
}server {
listen 80;
server_name example.com;
root /srv/notes/client/dist;
location / {
try_files $uri $uri/ /index.html; # single-page-app fallback
}
location /api/ {
proxy_pass http://127.0.0.1:3000; # Node.js, Gunicorn or Puma
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}X-Forwarded-Proto tells the application whether the visitor used HTTPS. Test nginx changes with sudo nginx -t before sudo systemctl reload nginx, and Caddy changes with caddy validate.