<div align="center">
# webserve
**Static file server for local development** — SPA fallback, optional live reload, configurable host and port.
[Rust](https://www.rust-lang.org/) · [Actix Web](https://actix.rs/) · [Tokio](https://tokio.rs/)
[](https://github.com/marcuwynu23/webserve/stargazers)
[](https://github.com/marcuwynu23/webserve/network/members)
[](https://github.com/marcuwynu23/webserve/issues)
[](LICENSE)
[](https://crates.io/crates/webserve)
[**Repository**](https://github.com/marcuwynu23/webserve) · [**Issues**](https://github.com/marcuwynu23/webserve/issues) · [**Pull requests**](https://github.com/marcuwynu23/webserve/pulls)
</div>
---
## Features
| Static hosting | Serve any folder; directory listing when no `index.html` is present |
| Directory listing UI | Full-width layout, breadcrumbs, folders first then files; name, size, modified; light/dark theme with icon toggle (persisted) |
| SPA mode | `--spa` — unknown paths serve `index.html` (client-side routing) |
| Live reload | `--watch` — filesystem watcher + injected reload script for HTML |
| Open browser | `--open` — after bind, open default browser (uses `127.0.0.1` when host is `0.0.0.0`) |
| URL normalization | Collapses `//` and `.` segments; directory URLs get a trailing `/` redirect (disable with `--no-redirect-dir-slash`) |
| Binding | Configurable `--host` and `--port` (defaults: `127.0.0.1`, `8080`); if port is in use, tries next port until one is free |
---
## Requirements
- **Rust** (stable), e.g. via [rustup](https://rustup.rs/)
---
## Installation
**From a clone**
```bash
git clone https://github.com/marcuwynu23/webserve.git
cd webserve
cargo build --release
```
Binary: `target/release/webserve` (or `webserve.exe` on Windows).
**Install into Cargo bin path**
```bash
cargo install --path .
```
**Install from registry***
```bash
cargo install webserve
```
---
## Usage
```bash
webserve [OPTIONS]
```
Run `webserve --help` for the full option list.
### Options
| `--dir` | `-d` | Root directory to serve | Current working directory |
| `--port` | `-p` | TCP port | `8080` |
| `--host` | `-h` | Bind address | `127.0.0.1` |
| `--spa` | — | SPA fallback to `index.html` | off |
| `--watch` | `-w` | Watch files and reload browsers | off |
| `--open` | — | Open default browser to server URL | off |
| `--no-redirect-dir-slash` | — | Don’t redirect `/dir` → `/dir/` | off (redirect on) |
### Examples
Serve the current directory:
```bash
webserve
```
Serve a production build with SPA and reload (typical for Vite/React/Vue `dist`):
```bash
webserve --dir ./dist --spa --watch
```
Open the site in the browser after start:
```bash
webserve --open --port 8080
```
Listen on all interfaces (e.g. phone on same LAN):
```bash
webserve --host 0.0.0.0 --port 3000 --dir ./public
```
---
## Development
```bash
cargo build
cargo test
```
**Git hooks (tag + version check):** use the repo’s hooks directory (native `core.hooksPath`):
```bash
git config core.hooksPath .githooks
```
Hooks are **off by default** so `git push` isn’t delayed. Optional tag check: `WEBSERVE_HOOK_VERSION_CHECK=1 git push origin v1.2.1` — see [`.githooks/README.md`](.githooks/README.md).
---
## License
MIT © [Mark Wayne Menorca](mailto:marcuwynu23@gmail.com)