{"id":49612676,"url":"https://github.com/anantadwi13/explorer","last_synced_at":"2026-05-04T18:01:33.906Z","repository":{"id":355437402,"uuid":"1227967392","full_name":"anantadwi13/explorer","owner":"anantadwi13","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-03T15:28:02.000Z","size":986,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T17:27:30.638Z","etag":null,"topics":["ai-generated","claude-code","file-browser","file-explorer","vibe-coding"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anantadwi13.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-03T12:14:45.000Z","updated_at":"2026-05-03T15:28:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/anantadwi13/explorer","commit_stats":null,"previous_names":["anantadwi13/explorer"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/anantadwi13/explorer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anantadwi13%2Fexplorer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anantadwi13%2Fexplorer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anantadwi13%2Fexplorer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anantadwi13%2Fexplorer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anantadwi13","download_url":"https://codeload.github.com/anantadwi13/explorer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anantadwi13%2Fexplorer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32618391,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"ssl_error","status_checked_at":"2026-05-04T10:08:02.005Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-generated","claude-code","file-browser","file-explorer","vibe-coding"],"created_at":"2026-05-04T18:01:31.771Z","updated_at":"2026-05-04T18:01:33.891Z","avatar_url":"https://github.com/anantadwi13.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# explorer\n\n[![Go version](https://img.shields.io/github/go-mod/go-version/anantadwi13/explorer)](go.mod)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n\u003e ⚠ **Playground / personal use only.** This is a hobby project, not a\n\u003e hardened service. There is no authentication, no rate limiting, and no\n\u003e security audit. Anyone who can reach the port can read every file\n\u003e under the served directory. Run it on your own machine bound to\n\u003e loopback (the default), or on a trusted LAN — never expose it to the\n\u003e public internet, behind a tunnel, or on a shared host.\n\nA single-binary local directory browser — point it at a folder, open the URL, read everything in place from your phone on the same Wi-Fi.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/desktop.gif\" alt=\"explorer on the desktop: browse a folder, open a markdown file, switch to dark theme\" width=\"820\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/mobile.gif\" alt=\"explorer on mobile: open a folder, tap a markdown file, scroll\" width=\"320\"/\u003e\n\u003c/p\u003e\n\n## Why explorer?\n\nSometimes you just want to read the markdown notes, text files, and images on your laptop from the couch — on a phone, in a browser, without copying anything anywhere. `explorer` is a single static Go binary that serves a chosen directory over HTTP as a read-only browser, with markdown rendering, inline images, and deep-linkable URLs. No accounts, no writes, no cloud.\n\n## Install\n\n### Download the binary (fastest)\n\nBare binary, no extract step. Replace `\u003cTAG\u003e` with the latest release version from the [Releases page](https://github.com/anantadwi13/explorer/releases) (e.g. `v0.2.0`).\n\n```bash\n# linux/amd64\ncurl -L -o explorer https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_linux_amd64 \u0026\u0026 chmod +x explorer \u0026\u0026 ./explorer ./\n\n# linux/arm64\ncurl -L -o explorer https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_linux_arm64 \u0026\u0026 chmod +x explorer \u0026\u0026 ./explorer ./\n\n# darwin/amd64 (Intel Macs)\ncurl -L -o explorer https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_darwin_amd64 \u0026\u0026 chmod +x explorer \u0026\u0026 ./explorer ./\n\n# darwin/arm64 (Apple Silicon)\ncurl -L -o explorer https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_darwin_arm64 \u0026\u0026 chmod +x explorer \u0026\u0026 ./explorer ./\n```\n\nWindows (PowerShell):\n\n```powershell\nInvoke-WebRequest -Uri https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_windows_amd64.exe -OutFile explorer.exe\n.\\explorer.exe .\n```\n\n### Download the archive (with LICENSE + README)\n\nSame binary inside, plus `LICENSE` and `README.md` at the same directory level. The unix archive preserves the executable bit, so no `chmod` is needed after extracting.\n\n```bash\n# linux/amd64\ncurl -L -o explorer.tar.gz https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_linux_amd64.tar.gz \u0026\u0026 tar -xzf explorer.tar.gz \u0026\u0026 ./explorer ./\n\n# linux/arm64\ncurl -L -o explorer.tar.gz https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_linux_arm64.tar.gz \u0026\u0026 tar -xzf explorer.tar.gz \u0026\u0026 ./explorer ./\n\n# darwin/amd64\ncurl -L -o explorer.tar.gz https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_darwin_amd64.tar.gz \u0026\u0026 tar -xzf explorer.tar.gz \u0026\u0026 ./explorer ./\n\n# darwin/arm64\ncurl -L -o explorer.tar.gz https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_darwin_arm64.tar.gz \u0026\u0026 tar -xzf explorer.tar.gz \u0026\u0026 ./explorer ./\n```\n\nWindows (PowerShell):\n\n```powershell\nInvoke-WebRequest -Uri https://github.com/anantadwi13/explorer/releases/download/\u003cTAG\u003e/explorer_\u003cTAG\u003e_windows_amd64.zip -OutFile explorer.zip\nExpand-Archive .\\explorer.zip -DestinationPath .\n.\\explorer.exe .\n```\n\n### Verify the download\n\nEach release ships a single `checksums.txt` covering both bare binaries and archives. `--ignore-missing` lets the verify step succeed for whichever subset you actually downloaded.\n\n```bash\n# linux\nsha256sum --ignore-missing -c checksums.txt\n\n# macOS\nshasum -a 256 --ignore-missing -c checksums.txt\n```\n\nAfter running the binary, confirm what you have with `./explorer --version` — it prints the embedded tag, short commit, and build date in `\u003ctag\u003e (commit \u003cshort-sha\u003e, built \u003cyyyy-mm-dd\u003e)` form.\n\n**macOS Gatekeeper:** the first launch may show *\"cannot be opened because the developer cannot be verified\"* — these binaries are not signed/notarised. Clear the quarantine attribute once with:\n\n```bash\nxattr -d com.apple.quarantine ./explorer\n```\n\nThis applies to both the bare binary and the binary extracted from the archive.\n\n**Windows SmartScreen:** the first launch may show *\"Windows protected your PC\"*. Click **More info → Run anyway**. Same caveat applies to both shapes — the binaries are not Authenticode-signed.\n\n### With Go (recommended for users with a Go toolchain)\n\nRequires Go 1.24+.\n\n```bash\ngo install github.com/anantadwi13/explorer/cmd/explorer@latest\n```\n\nThis drops an `explorer` binary in `$GOBIN` (or `$GOPATH/bin` — make sure it is on your `PATH`). Once tagged releases exist, pin a version with `@v0.2.0` instead of `@latest`.\n\nTo try it without installing:\n\n```bash\ngo run github.com/anantadwi13/explorer/cmd/explorer@latest \u003cdir\u003e\n```\n\n### From source (for contributors)\n\nRequires Go 1.24+ and Node 18+.\n\n```bash\ngit clone https://github.com/anantadwi13/explorer.git\ncd explorer\nmake build      # builds the SPA, embeds it, produces ./explorer\n./explorer \u003cdir\u003e\n```\n\n### Docker / Docker Compose\n\n```bash\ndocker compose up --build\n```\n\nThen open `http://localhost:8080`. The `docker-compose.yml` bind-mounts the current directory into `/data` (read-only) and runs:\n\n```\nexplorer /data --host 0.0.0.0 --port 8080\n```\n\n**`--host 0.0.0.0` is mandatory inside the container.** With the default `127.0.0.1`, the server listens only on the container's loopback interface and Docker's port mapping cannot reach it.\n\n## Quick start\n\n```bash\n# Serve the current directory on the default loopback port\nexplorer .\n\n# Serve /home/alice/docs on port 9000\nexplorer /home/alice/docs --port 9000\n\n# Expose on all interfaces (LAN-accessible — read the warning below)\nexplorer . --host 0.0.0.0\n```\n\nWhen `--host` is not a loopback address, the startup banner prints a warning:\n\n**Output:**\n```\nexplorer (playground build — no auth, no audit; do not expose publicly)\nexplorer serving /home/alice/docs\n  → http://0.0.0.0:8080\n  ⚠ host is not loopback — anyone on this network can read these files.\n```\n\n## Configuration\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--port` | `8080` | TCP port to listen on |\n| `--host` | `127.0.0.1` | Address to bind to |\n| `--version`, `-v` | — | Print `\u003cversion\u003e (commit \u003cshort-sha\u003e, built \u003cyyyy-mm-dd\u003e)` and exit |\n\n## Features\n\n- Serves any local directory over HTTP as a read-only browser\n- Embedded React SPA: markdown rendering (GFM), syntax-highlighted text viewer for 35+ languages (Go, TypeScript, Python, Kotlin, Swift, Rust, JSON, TOML, and more), inline images, download button for everything else\n- Mobile-first responsive layout; desktop shows a persistent tree sidebar\n- Deep-linkable URLs for every folder and file\n- Light / dark / system theme toggle\n- Single static binary — no runtime dependencies\n\n## Security model\n\n`explorer` is designed for trusted, local use:\n\n- **Read-only.** No write, update, or delete endpoints exist. The binary never modifies the served tree.\n- **Loopback by default.** `--host` defaults to `127.0.0.1`, so out of the box only your own machine can reach it.\n- **Path-traversal containment.** Every path-accepting endpoint resolves the request relative to the served root, rejects `..` and absolute paths, and follows symlinks only if the resolved target stays inside the root. Symlinks pointing outside the root are silently dropped from listings and return `400 outside_root` when accessed directly.\n- **No authentication.** There is no login, no token, no per-file ACL.\n\nBecause there is no authentication, **`--host 0.0.0.0` exposes every file under the served root to anyone who can reach your machine on the network.** Only do this on a network you trust. Do not expose `explorer` to the public internet.\n\n## Development\n\nTwo-process dev workflow: Go server on `:8080` + Vite dev server on `:5173` proxying API/raw paths to the Go server.\n\n```bash\nmake dev-server       # builds and runs the Go binary against ./testdata\nmake dev-web          # starts the Vite dev server on :5173 (run alongside dev-server)\nmake test             # go test ./cmd/... ./internal/...\nmake web-commit       # rebuild the embedded SPA and stage internal/server/ui/dist/\nmake clean            # remove ./explorer and internal/server/ui/dist\n```\n\n`internal/server/ui/dist/` is committed to source control so module-proxy installs (`go install`, `go run`) ship a working SPA. **Run `make web-commit` whenever you change anything under `web/src/`** so the embedded build stays in sync.\n\n## Out-of-scope (v1)\n\nThese are intentionally deferred:\n\n- File watcher / live reload\n- Search across files\n- ~~Syntax highlighting for code~~ ✓ shipped — Go, TypeScript, Python, Kotlin, Swift, Rust, and 35+ more languages plus JSON/TOML/GraphQL/Protobuf; see `web/src/components/syntax/grammars.ts` for the full list\n- README auto-render in folder listings\n- Tree pagination per folder\n- Authentication / multi-user\n- Write / update / delete\n- PDF, Office, video, audio preview\n\n## Troubleshooting\n\n**\"connection refused\" on port 8080 in Docker**\n\nMake sure the `command` in `docker-compose.yml` includes `--host 0.0.0.0`. The default loopback bind is not reachable through Docker's port mapping.\n\n**`GET /` returns a plain-text 404 (`404 page not found`) after a local build**\n\nThe embedded SPA is empty. Run `make build` (not just `go build`) to build the frontend and embed it. If you got the binary via `go install ...@latest` and still see this, the published `internal/server/ui/dist/` is empty — please open an issue, this should not happen.\n\n**Symlink file is missing from listing**\n\nSymlinks whose targets resolve outside the served root are silently omitted from directory listings and return a `400 outside_root` error when accessed directly — this is intentional path-traversal containment.\n\n## Contributing\n\nIssues and pull requests are welcome.\n\n- Run `make test` before submitting a PR.\n- If your PR touches `web/src/`, run `make web-commit` and include the regenerated `internal/server/ui/dist/` in the same commit. The embedded SPA is shipped via the Go module proxy, so a stale `dist/` means `go install` users get an outdated frontend against an updated API.\n\n## License\n\n[MIT](LICENSE) © anantadwi13\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanantadwi13%2Fexplorer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanantadwi13%2Fexplorer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanantadwi13%2Fexplorer/lists"}