svenstaro/miniserve
π For when you really just want to serve some files over HTTP right now!
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained β safe to depend on.
Has a license, tests, and CI β clean foundation to fork and modify.
Documented and popular β useful reference codebase to read through.
No critical CVEs, sane security posture β runnable as-is.
- βLast commit 2d ago
- β12 active contributors
- βMIT licensed
Show all 6 evidence items βShow less
- βCI configured
- βTests present
- β Concentrated ownership β top contributor handles 53% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README β live-updates from the latest cached analysis.
[](https://repopilot.app/r/svenstaro/miniserve)Paste at the top of your README.md β renders inline like a shields.io badge.
βΈPreview social card (1200Γ630)
This card auto-renders when someone shares https://repopilot.app/r/svenstaro/miniserve on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: svenstaro/miniserve
Generated by RepoPilot Β· 2026-05-09 Β· Source
π€Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale β STOP and ask the user to regenerate it before proceeding. - Treat the AI Β· unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/svenstaro/miniserve shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything β but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
π―Verdict
GO β Healthy across the board
- Last commit 2d ago
- 12 active contributors
- MIT licensed
- CI configured
- Tests present
- β Concentrated ownership β top contributor handles 53% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
β Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live svenstaro/miniserve
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale β regenerate it at
repopilot.app/r/svenstaro/miniserve.
What it runs against: a local clone of svenstaro/miniserve β the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in svenstaro/miniserve | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit β€ 32 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of svenstaro/miniserve. If you don't
# have one yet, run these first:
#
# git clone https://github.com/svenstaro/miniserve.git
# cd miniserve
#
# Then paste this script. Every check is read-only β no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of svenstaro/miniserve and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "svenstaro/miniserve(\\.git)?\\b" \\
&& ok "origin remote is svenstaro/miniserve" \\
|| miss "origin remote is not svenstaro/miniserve (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift β was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "src/main.rs" \\
&& ok "src/main.rs" \\
|| miss "missing critical file: src/main.rs"
test -f "src/args.rs" \\
&& ok "src/args.rs" \\
|| miss "missing critical file: src/args.rs"
test -f "src/file_utils.rs" \\
&& ok "src/file_utils.rs" \\
|| miss "missing critical file: src/file_utils.rs"
test -f "src/listing.rs" \\
&& ok "src/listing.rs" \\
|| miss "missing critical file: src/listing.rs"
test -f "src/auth.rs" \\
&& ok "src/auth.rs" \\
|| miss "missing critical file: src/auth.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
miss "last commit was $days_since_last days ago β artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) β safe to trust"
else
echo "artifact has $fail stale claim(s) β regenerate at https://repopilot.app/r/svenstaro/miniserve"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
β‘TL;DR
miniserve is a lightweight, self-contained CLI tool written in Rust that serves files and directories over HTTP with zero dependencies on external servers. It bundles features like directory listing, basic auth (plaintext and SHA256), TLS support, WebDAV filesystem access, archive streaming (tar/zip), and markdown renderingβall in a single statically-compiled binary optimized for minimal size (panic=abort, LTO, -z opt-level). Monolithic CLI binary in Rust. Core server logic in src/main.rs orchestrates actix-web. Modular structure: src/args.rs (clap CLI parsing), src/auth.rs (authentication), src/archive.rs (tar/zip streaming), src/listing.rs (directory HTML rendering), src/renderer.rs (template rendering with maud), src/webdav_fs.rs (WebDAV support). Static assets (CSS, logo) compiled into binary via data/ (SCSS β CSS via grass crate). Tests are integration tests (tests/*.rs) spawning HTTP server instances.
π₯Who it's for
DevOps engineers and developers who need to quickly share files over HTTP without setting up nginx/Apache; QA teams testing downloads; CTF/infosec practitioners who need temporary file sharing; users managing embedded systems or CI/CD pipelines where a full web server is overkill.
π±Maturity & risk
Actively maintained and production-ready. v0.35.0 released with 283K+ lines of Rust code, comprehensive test suite (tests/ covers auth, archives, CLI, binding), CI via GitHub Actions (ci.yml, build-release.yml), and clear release process (release.toml). Regular dependabot updates indicate active dependency management.
Low risk: single maintainer (svenstaro) but well-established (MIT license, Docker Hub presence, Crates.io published). Dependencies are well-vetted Rust ecosystem crates (actix-web 4, rustls, serde). No obvious security red flags; auth uses SHA256 hashing. SCSS bundling (data/style.scss, 5 themes) adds frontend complexity but is pre-compiled. Verify TLS cert handling (--tls-cert, --tls-key params) matches your security posture.
Active areas of work
Active maintenance: dependabot.yml configured for auto-updates; recent focus on Rust edition 2024 (Cargo.toml), compression support (brotli, gzip, zstd in actix-web features), and WebDAV/archive functionality. .github/workflows/ show automated builds for multiple platforms. No major breaking changes signaled; steady incremental improvements.
πGet running
git clone https://github.com/svenstaro/miniserve.git
cd miniserve
cargo build --release
./target/release/miniserve /tmp # Serve /tmp on http://127.0.0.1:8080
Daily commands:
Dev mode: cargo build && ./target/debug/miniserve <path>. Release: cargo build --release && ./target/release/miniserve <path>. With options: miniserve --auth user:pass --tls-cert cert.pem --tls-key key.pem --port 9090 /data. Docker: docker run -v /data:/srv svenstaro/miniserve /srv. Makefile: make (inspect Makefile for targets).
πΊοΈMap of the codebase
src/main.rsβ Entry point that initializes the Actix-web server, configures routes, and handles CLI argument processingβessential for understanding the overall request flow.src/args.rsβ Defines all CLI arguments and configuration options; required reading to understand what features miniserve supports and how they're parsed.src/file_utils.rsβ Core file system operations and directory traversal logic; critical for understanding how files are served and listed.src/listing.rsβ Generates directory listings and HTML output; fundamental to the user-facing file browser interface.src/auth.rsβ Implements authentication and authorization middleware; load-bearing for security features.src/archive.rsβ Handles on-the-fly archive generation (tar, zip); key feature for batch file downloads.Cargo.tomlβ Defines all dependencies including Actix-web framework version and compression features; essential for build configuration.
π§©Components & responsibilities
- HTTP Server (main.rs + Actix-web) (Actix-web, Tokio, TLS (optional)) β Accept connections, parse HTTP requests, route to handlers, apply middleware (compression, auth), serialize responses
- Failure mode: Port binding fails if already in use; TLS cert errors prevent server start
- File System Access (file_utils.rs) (std::fs, walkdir, path normalization) β Traverse directories, validate paths against symlink/escape attacks, read file metadata, filter by permissions
- Failure mode: Permission denied errors; symlink loops; missing files returned as 404
- Directory β undefined
π οΈHow to make changes
Add a new CLI argument
- Define the new argument struct field in src/args.rs using Clap derive macros (
src/args.rs) - Add the argument to the main configuration struct in src/config.rs (
src/config.rs) - Use the config value in src/main.rs to influence server behavior (
src/main.rs)
Add a new HTTP endpoint or route
- Create a handler function in the appropriate module (e.g., src/file_op.rs for file operations or src/listing.rs for directory views) (
src/file_op.rs) - Register the route in src/main.rs within the app configuration using .route() or .service() (
src/main.rs) - Add authentication/authorization guards if needed using src/auth.rs utilities (
src/auth.rs) - Add integration tests in tests/ directory following existing patterns (e.g., tests/api.rs) (
tests/api.rs)
Add a new UI theme
- Create a new SCSS theme file in data/themes/ following the naming convention (e.g., data/themes/mytheme.scss) (
data/themes/monokai.scss) - Define CSS variables and rules matching the existing theme structure (
data/themes/monokai.scss) - Theme selection is handled by src/renderer.rs; verify the theme is automatically discovered (
src/renderer.rs)
Add file operation support (upload/delete/rename)
- Implement the operation logic in src/file_op.rs with proper error handling (
src/file_op.rs) - Wrap with authentication check from src/auth.rs if operation is privileged (
src/auth.rs) - Register route in src/main.rs (
src/main.rs) - Add test in tests/upload_files.rs or tests/paste.rs (
tests/upload_files.rs)
π§Why these technologies
- Actix-web 4 β High-performance async web framework for Rust; enables efficient concurrent request handling with minimal overhead ideal for file serving
- Actix-files β Provides optimized static file serving with automatic compression (gzip, brotli, zstd) and range request support
- Actix-multipart β Handles multipart form data for file uploads with streaming to avoid excessive memory usage
- Clap for CLI parsing β Derives CLI argument handling with minimal boilerplate; enables rich help text and validation
- SASS/SCSS theming β Allows maintainable, composable styling system for bundled themes without runtime overhead
βοΈTrade-offs already made
-
Self-contained single binary with embedded assets
- Why: Minimizes deployment friction and external dependencies
- Consequence: Larger binary size but eliminates configuration file lookups and asset serving overhead
-
On-the-fly archive generation instead of pre-computed caches
- Why: Supports dynamic file selection and keeps memory footprint low
- Consequence: Higher CPU usage during archive operations but scales to large directories without pre-allocation
-
HTTP Basic Auth only (no OAuth, JWT, or session tokens)
- Why: Simple, stateless authentication sufficient for ad-hoc file serving
- Consequence: Not suitable for production multi-user systems; credentials in every request
-
WebDAV support alongside HTTP
- Why: Enables remote filesystem access (mount drives, drag-drop files) on supported OSes
- Consequence: Additional protocol complexity and potential security surface
π«Non-goals (don't propose these)
- Not a persistent file managerβno version control, trash, or undo
- Not for large-scale content distributionβno caching CDN integration or bandwidth optimization
- Not a databaseβno querying, indexing, or structured data storage
- Not a reverse proxyβdoes not route to upstream services
- Not production-grade securityβHTTP Basic Auth only, no TLS client certificates, no rate limiting
- Not a real-time collaboration toolβno WebSocket broadcasting or conflict resolution
πͺ€Traps & gotchas
SCSS compilation: data/style.scss is compiled at build time via grass crate; modifying it requires rebuild. Auth file format: src/auth.rs expects newline-separated user:pass pairs in auth file; no comments or blank lines tolerated. TLS key format: --tls-key expects PKCS#8 or traditional PEM; RSA keys must match cert (tests/data/ has examples). Path traversal: src/file_utils.rs uses path normalization; ensure your path handling doesn't bypass it. Async runtime: Tokio is single-threaded by default in CLI context; high concurrency may need tuning. WebDAV: dav-server feature adds complexity; ensure write permissions are intentional (--allow-upload, --allow-delete).
ποΈArchitecture
π‘Concepts to learn
- Actix-web async request handling β Core to miniserve's concurrency model; understanding async/await and Tokio is required to modify request handlers in src/main.rs
- Stream-based file serving (tar/zip creation on-the-fly) β src/archive.rs creates archives without buffering entire contents to disk; critical for serving multi-GB collections without OOM
- HTTP Basic Authentication (RFC 7617) β src/auth.rs implements Base64-encoded credential validation; understanding this is required to extend auth schemes (e.g., digest, bearer tokens)
- WebDAV (RFC 4918) β src/webdav_fs.rs integrates dav-server crate to expose filesystem as WebDAV; enables clients to MOUNT, PROPFIND, and edit files remotely
- Content-Encoding negotiation (Brotli, Gzip, Zstd) β actix-web compress feature in Cargo.toml enables transparent compression; affects response headers and bandwidth optimization
- SCSS to CSS compilation at build time β data/style.scss compiled via grass crate into binary; modifying styles requires understanding Rust build.rs or macro expansion
- Clap derive macros for CLI parsing β src/args.rs uses clap 4 derive API to declaratively define flags, subcommands, and validation; extending CLI requires understanding these macros
πRelated repos
TheWaWaR/simple-http-serverβ Direct alternative: Rust CLI HTTP file server; similar scope but simpler feature set without WebDAV/archiveslycheeverse/lycheeβ Rust ecosystem peer: static site/HTTP tool in same niche; demonstrates actix-web usage patterns for referencelibreddit/libredditβ Larger actix-web project showing scaling patterns; instructive for understanding Rust web app architecturecasey/justβ Rust CLI using similar clap derive patterns for argument parsing; good reference for CLI design in Rustsvenstaro/colorsyncβ By same author; demonstrates Rust packaging/release strategy applicable to miniserve
πͺPR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for WebDAV operations (PUT/DELETE/MKCOL)
The repo has tests/webdav.rs but it's likely incomplete. WebDAV is a critical feature (src/webdav_fs.rs exists) that enables file operations beyond GET. There are no visible tests for file creation, deletion, or directory operations via WebDAV, which are high-risk operations that need thorough coverage.
- [ ] Review existing tests/webdav.rs to identify gaps in PUT, DELETE, MKCOL, PROPFIND coverage
- [ ] Add integration tests for creating files via WebDAV PUT requests
- [ ] Add tests for deleting files/directories via WebDAV DELETE requests
- [ ] Add tests for WebDAV permission handling with authentication enabled
- [ ] Test edge cases like overwriting existing files and nested directory creation
Add tests for archive generation with various file types and symlinks
src/archive.rs handles tar/zip generation which is security-sensitive (potential for path traversal, symlink attacks). While tests/archive.rs exists, the test data directory (tests/data) contains only TLS certificates. There's no visible test coverage for archive contents validation, symlink handling, or large file scenarios.
- [ ] Create comprehensive test fixtures in tests/data/archive_test_files/ with various file types, permissions, and symlinks
- [ ] Add tests in tests/archive.rs to verify tar/zip contents are correctly generated
- [ ] Add tests for symlink handling to ensure they don't escape the served directory
- [ ] Add tests for large files in archives and verify streaming doesn't load entire archive into memory
- [ ] Test archive generation with special characters in filenames
Add CI workflow for testing multiple Rust editions and MSRV (Minimum Supported Rust Version)
Cargo.toml specifies edition = "2024" (likely a typo for 2021), but there's no CI validation for MSRV or edition compatibility. The .github/workflows/ci.yml likely only tests the latest Rust. This is important for a widely-used CLI tool to document and enforce MSRV for users on stable releases.
- [ ] Review .github/workflows/ci.yml to check current Rust version testing strategy
- [ ] Add a rust-toolchain.toml file specifying the project's MSRV (likely 1.70+)
- [ ] Create a new GitHub Actions workflow (e.g., .github/workflows/msrv.yml) that tests against the MSRV
- [ ] Fix the edition field in Cargo.toml (should be '2021' not '2024')
- [ ] Document the MSRV in README.md under installation/requirements section
πΏGood first issues
- Add integration test for --header flag chain: tests/cli.rs exists but lacks coverage of multiple --header flags being combined; add test case spawning server with --header 'X-A:1' --header 'X-B:2' and asserting both appear in response headers
- Document theme selection in README: 5 theme files exist in data/themes/ (archlinux.scss, ayu_dark.scss, monokai.scss, squirrel.scss, zenburn.scss) but --theme flag usage is not documented in README; add section with examples and screenshots
- Add tests for WebDAV PROPFIND edge cases: src/webdav_fs.rs is present but tests/archive.rs and tests/auth.rs don't cover WebDAV scenario (no tests/webdav.rs); write integration test mocking PROPFIND/PROPPATCH requests
βTop contributors
Click to expand
Top contributors
- @svenstaro β 53 commits
- @pzhlkj6612 β 16 commits
- @rktjmp β 9 commits
- @dependabot[bot] β 5 commits
- @7sDream β 4 commits
πRecent commits
Click to expand
Recent commits
02b3bbeβ Bump deps (svenstaro)5e5d542β Add CHANGELOG entry for #1562 (svenstaro)4bc9702β Merge branch 'fix/crypto-uuid-not-found-in-non-https' (svenstaro)92691fcβ Handle pastebin form not being available (svenstaro)5f60126β Merge pull request #1563 from svenstaro/dependabot/cargo/all-dependencies-e5f785638f (svenstaro)93004a5β Bump the all-dependencies group with 9 updates (dependabot[bot])65a27aaβ Use current datetime instead of "crypto.randomUUID()" in non-HTTPS env (pzhlkj6612)eee8e19β Merge pull request #1559 from sermuns/writen-typo (svenstaro)7184849β Fix typo writen->written (sermuns)2cd9c49β Release miniserve version 0.35.0 (svenstaro)
πSecurity observations
- High Β· Incomplete Cargo.toml - Truncated Dependency β
Cargo.toml. The Cargo.toml file appears to be truncated at the 'zip' dependency definition. This makes it impossible to fully analyze all dependencies and their versions for known vulnerabilities. A complete dependency audit cannot be performed. Fix: Provide the complete Cargo.toml file. Run 'cargo audit' to check for known CVEs in dependencies. - High Β· Edition 2024 May Not Exist β
Cargo.toml (line: edition = '2024'). The Cargo.toml specifies edition = '2024', but Rust editions only go up to 2021. This is either a misconfiguration or a typo that will prevent compilation. This should be '2021' for current stable Rust. Fix: Change edition to '2021' or valid edition number. Verify with 'rustc --version' and update accordingly. - Medium Β· Potential Path Traversal in File Operations β
src/file_utils.rs, src/file_op.rs. File serving utilities (src/file_utils.rs, src/file_op.rs) in HTTP servers are common vectors for path traversal attacks. Without seeing the implementation, there's risk that file access controls may not properly validate and sanitize user-supplied paths before accessing the filesystem. Fix: Ensure all file path inputs are canonicalized and validated to be within the intended serving directory. Use std::fs::canonicalize() and verify paths don't escape the base directory using proper comparison logic. - Medium Β· WebDAV Implementation Security β
src/webdav_fs.rs, Cargo.toml (dav-server = 0.11). The codebase includes WebDAV filesystem support (src/webdav_fs.rs) using the dav-server crate. WebDAV introduces significant attack surface through file upload/delete operations. Without authentication, this could allow unauthorized file modifications. Fix: Ensure WebDAV operations require proper authentication. Review dav-server 0.11 for known vulnerabilities. Implement strict access controls and consider disabling WebDAV by default. - Medium Β· Markdown Rendering - Potential XSS Vector β
src/renderer.rs, Cargo.toml (comrak = 0.52). The codebase uses comrak for markdown rendering (src/renderer.rs). If user-supplied markdown content is rendered without proper sanitization, malicious HTML/JavaScript could be injected and executed in browsers. Fix: Configure comrak with safe options (disabled unsafe features). Implement HTML sanitization on rendered output. Use OWASP recommendations for markdown-to-HTML rendering. - Medium Β· Archive Extraction - Zip Bomb/DOS Risk β
src/archive.rs, Cargo.toml (tar, zip dependencies). Archive operations (src/archive.rs) handle tar and zip files without apparent resource limits. This could be vulnerable to zip bomb attacks or decompression DOS attacks if large/nested archives are extracted. Fix: Implement size limits on archive extraction. Set maximum extraction sizes and depth limits. Validate archive contents before full extraction. - Medium Β· Authentication - Plaintext Password Storage Possible β
src/auth.rs, tests/data/auth1.txt. Tests reference auth1.txt file (tests/data/auth1.txt) which may contain plaintext credentials for testing. If similar patterns exist in production code (src/auth.rs), passwords might be stored insecurely. Fix: Use strong password hashing (bcrypt, argon2). Ensure credentials are never logged or stored in plaintext. Review src/auth.rs implementation for secure hash usage. - Low Β· TLS Configuration - Multiple Certificate Formats β
tests/data/key_*.pem, src/main.rs. Test data includes multiple key formats (key_pkcs1.pem, key_pkcs8.pem, key_ec.pem). While appropriate for testing, ensure production TLS configuration uses secure defaults and doesn't accept weaker key types. Fix: Use TLS 1.3 by default. Support only modern, secure key types. Validate certificate strength in configuration. - Low Β· undefined β
undefined. undefined Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
πWhere to read next
- Open issues β current backlog
- Recent PRs β what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals β see the live page for receipts. Re-run on a new commit to refresh.