Minimal CLI tool to expose your local dev server to the internet
Expose lets you share your localhost with the world — perfect for testing webhooks, demoing work, or debugging on mobile devices. Built as a lightweight alternative to ngrok, powered by LocalTunnel.
- 🌐 Instant public URLs — Share localhost with one command
- ⚡ Zero signup — No accounts, no registration required
- � Config management — Save port settings per project
- 📦 Single binary — No Node.js, Python, or runtime dependencies
- 🧪 Production-tested — 75%+ test coverage, CI/CD pipeline
# Install
go install github.com/kernelshard/expose/cmd/expose@latest
# Initialize config
expose init
# Start tunnel
expose tunnelgo install github.com/kernelshard/expose/cmd/expose@latestgit clone https://github.com/kernelshard/expose.git
cd expose
go build -o expose ./cmd/expose
./expose --version$ expose init
✓ Config created: .expose.ymlCreates .expose.yml in current directory:
project: expose
port: 3000# Use config port
$ expose tunnel
✓ Tunnel (LocalTunnel) started for localhost:3000
✓ Public URL: https://quick-mammals-sing.loca.lt
✓ Forwarding to http://localhost:3000
✓ Provider: LocalTunnel
✓ Press Ctrl+C to stop
# Override port
$ expose tunnel --port 8080# List all config values
$ expose config list
project: expose
port: 3000
# Get specific value
$ expose config get port
3000
$ expose config get project
expose$ expose --version
expose version v0.1.2 (commit: d30c483, built: 2025-11-10)
$ expose init
✓ Config created: .expose.yml (project: expose, port: 3000)
$ python3 -m http.server 3000 &
Serving HTTP on 0.0.0.0 port 3000...
$ expose tunnel
🚀 Tunnel[LocalTunnel] started for localhost:3000
✓ Public URL: https://ripe-garlics-add.loca.lt
✓ Forwarding to: http://localhost:3000
✓ Provider: LocalTunnel
Press Ctrl+C to stop
$ curl https://ripe-garlics-add.loca.lt
<!DOCTYPE HTML>... # Works!Tested on: Go 1.23, macOS 14, Ubuntu 22.04
expose/
├── cmd/expose/ # CLI entry point
├── internal/
│ ├── cli/ # Cobra commands (thin layer)
│ ├── config/ # YAML config management
│ ├── provider/ # Tunnel provider interface
│ ├── tunnel/ # Service layer (business logic)
│ └── version/ # Version metadata
└── .expose.yml # User config (add to .gitignore per project)
Design principles:
- Interface-driven —
Providerinterface supports multiple tunnel backends - Clean separation — CLI → Service → Provider (no circular deps)
- Testable — Real file tests, injectable service layer
- LocalTunnel only — ngrok/Cloudflare support planned for v0.2.0
- One tunnel per process — Each
expose tunnelcommand runs independently (can run multiple on different ports) - No persistence — Public URLs change on restart
- CLI-only — No web UI or dashboard yet
See GitHub Issues for roadmap.
- Go 1.23+
- Git
git clone https://github.com/kernelshard/expose.git
cd expose
go mod download# Run all tests with race detector
go test ./... -v -race -cover
# Check coverage for specific packages
go test ./internal/config -cover
go test ./internal/tunnel -covergo build -o expose ./cmd/expose
./expose --version# Without installing
go run cmd/expose/main.go tunnel
# Test with live server
python3 -m http.server 3000 # Terminal 1
./expose tunnel # Terminal 2Contributions welcome! See CONTRIBUTING.md for:
- Development workflow
- Branch strategy
- Testing requirements
- Code style guidelines
MIT License - see LICENSE for details.
Made with ❤️ by @kernelshard