RepoPilotOpen in app β†’

svenstaro/miniserve

🌟 For when you really just want to serve some files over HTTP right now!

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained β€” safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI β€” clean foundation to fork and modify.

Learn fromHealthy

Documented and popular β€” useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture β€” runnable as-is.

  • βœ“Last commit 2d ago
  • βœ“12 active contributors
  • βœ“MIT licensed
Show all 6 evidence items β†’
  • βœ“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.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/svenstaro/miniserve)](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:

  1. 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.
  2. 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.
  3. 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 |

<details> <summary><b>Run all checks</b> β€” paste this script from inside your clone of <code>svenstaro/miniserve</code></summary>
#!/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).

</details>

⚑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

  1. Define the new argument struct field in src/args.rs using Clap derive macros (src/args.rs)
  2. Add the argument to the main configuration struct in src/config.rs (src/config.rs)
  3. Use the config value in src/main.rs to influence server behavior (src/main.rs)

Add a new HTTP endpoint or route

  1. 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)
  2. Register the route in src/main.rs within the app configuration using .route() or .service() (src/main.rs)
  3. Add authentication/authorization guards if needed using src/auth.rs utilities (src/auth.rs)
  4. Add integration tests in tests/ directory following existing patterns (e.g., tests/api.rs) (tests/api.rs)

Add a new UI theme

  1. Create a new SCSS theme file in data/themes/ following the naming convention (e.g., data/themes/mytheme.scss) (data/themes/monokai.scss)
  2. Define CSS variables and rules matching the existing theme structure (data/themes/monokai.scss)
  3. Theme selection is handled by src/renderer.rs; verify the theme is automatically discovered (src/renderer.rs)

Add file operation support (upload/delete/rename)

  1. Implement the operation logic in src/file_op.rs with proper error handling (src/file_op.rs)
  2. Wrap with authentication check from src/auth.rs if operation is privileged (src/auth.rs)
  3. Register route in src/main.rs (src/main.rs)
  4. 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

  • TheWaWaR/simple-http-server β€” Direct alternative: Rust CLI HTTP file server; similar scope but simpler feature set without WebDAV/archives
  • lycheeverse/lychee β€” Rust ecosystem peer: static site/HTTP tool in same niche; demonstrates actix-web usage patterns for reference
  • libreddit/libreddit β€” Larger actix-web project showing scaling patterns; instructive for understanding Rust web app architecture
  • casey/just β€” Rust CLI using similar clap derive patterns for argument parsing; good reference for CLI design in Rust
  • svenstaro/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

πŸ“Recent commits

Click to expand
  • 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.


Generated by RepoPilot. Verdict based on maintenance signals β€” see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals Β· svenstaro/miniserve β€” RepoPilot