A lightweight, secure WebRTC-based screen sharing application built with Go and Fiber. StreamTab enables real-time browser tab/screen sharing between a broadcaster and viewer using peer-to-peer WebRTC connections.
- WebRTC Screen Sharing: Real-time screen/tab streaming with audio support
- Secure Authentication: Password-protected access with AES-GCM encryption
- WebSocket Signaling: Efficient peer connection establishment
- Modern UI: Clean, responsive interface built with Templ templates
- Docker Support: Easy deployment with Docker and Docker Compose
- Hot Reload: Development mode with Air for automatic recompilation
- Security Headers: Built-in Helmet middleware for enhanced security
- Backend: Go 1.23+ with Fiber v2 web framework
- Frontend: Vanilla JavaScript with WebRTC API
- Templates: Templ for type-safe Go templates
- WebSocket: Real-time bidirectional communication
- WebRTC: Peer-to-peer media streaming with STUN/TURN support
- Encryption: AES-GCM for secure cookie authentication
- Go 1.23 or higher
- Docker and Docker Compose (for containerized deployment)
- Modern web browser with WebRTC support
-
Clone the repository
git clone <repository-url> cd streamtab
-
Install dependencies
go mod download
-
Install Templ CLI (for template generation)
go install github.com/a-h/templ/cmd/templ@latest
-
Configure environment variables
Fill a
.envfile in the project root:APP_PASSWORD=your-secure-password APP_PASSWORD_KEY=your-32-character-encryption-key
-
Generate templates and build
templ generate go build -o main main.go
-
Run the application
./main
The server will start on
http://localhost:3000
Install Air for automatic recompilation:
go install github.com/cosmtrek/air@latestRun with hot reload:
air-
Build and run with Docker Compose
docker-compose up -d
-
Configure environment variables in
docker-compose.yml:environment: - APP_PASSWORD=your-secure-password - APP_PASSWORD_KEY=your-32-character-encryption-key
- Navigate to
/streamafter logging in - Click "Start Streaming" to share your screen/tab
- Select the screen or browser tab you want to share
- The stream will be available to viewers
- Navigate to
/viewerafter logging in - Wait for the broadcaster to start streaming
- Click "Play" when the stream becomes available
- View the shared screen in real-time
streamtab/
├── main.go # Main application entry point
├── go.mod # Go module dependencies
├── go.sum # Dependency checksums
├── .env # Environment configuration
├── .air.toml # Air hot reload configuration
├── Dockerfile # Docker container definition
├── docker-compose.yml # Docker Compose orchestration
├── public/ # Static assets
│ ├── streaming.js # Broadcaster WebRTC logic
│ └── viewer.js # Viewer WebRTC logic
└── views/ # Templ templates
├── IndexPage.templ # Home page template
├── LoginPage.templ # Login page template
├── StreamerTemplate.templ # Broadcaster interface
└── ViewerTemplate.templ # Viewer interface
| Variable | Description | Default | Required |
|---|---|---|---|
APP_PASSWORD |
Application access password | q;j,6rDk |
No |
APP_PASSWORD_KEY |
32-byte encryption key for cookies | test-key |
No |
The application uses the following STUN/TURN servers:
- Google STUN servers (stun.l.google.com)
- Cloudflare STUN server
- OpenRelay TURN servers (for NAT traversal)
- Password Authentication: Constant-time password comparison to prevent timing attacks
- Cookie Encryption: AES-GCM encryption for authentication cookies
- Secure Cookies: HTTPOnly and Secure flags enabled
- Helmet Middleware: Security headers for XSS, clickjacking protection
- 7-Day Session: Automatic session expiration
| Method | Path | Description | Auth Required |
|---|---|---|---|
| GET | / |
Home page | Yes |
| GET | /login |
Login page | No |
| POST | /login |
Authentication | No |
| GET | /stream |
Broadcaster interface | Yes |
| GET | /viewer |
Viewer interface | Yes |
| GET | /ws |
WebSocket signaling | No |
| GET | /static/* |
Static file serving | No |
The WebSocket endpoint (/ws) handles WebRTC signaling messages:
{
"type": "offer|answer|candidate",
"data": { /* SDP or ICE candidate data */ }
}Message Types:
offer: SDP offer from broadcasteranswer: SDP answer from viewercandidate: ICE candidate for NAT traversal
# Generate Templ templates
templ generate
# Build the binary
go build -o main main.go
# Run
./maingo test ./...- Set strong passwords: Use secure, randomly generated passwords
- Use HTTPS: Deploy behind a reverse proxy (Traefik, Nginx) with TLS
- Configure TURN servers: For reliable NAT traversal in production
- Resource limits: Set appropriate Docker resource constraints
- Monitoring: Implement logging and monitoring solutions
The included docker-compose.yml has Traefik labels configured:
- Automatic HTTPS with Let's Encrypt
- Domain:
stream.hubku.com(update to your domain) - Network:
traefik-network(external network required)
- WebSocket fails: Check firewall rules for port 3000
- WebRTC connection fails: Ensure STUN/TURN servers are accessible
- No audio: Browser may require user interaction before audio playback
- Chrome/Edge: Full support
- Firefox: Full support
- Safari: Requires HTTPS for WebRTC
"Screen sharing permission denied"
- User declined browser permission prompt
- Retry and accept the permission request
"Connection to viewer lost"
- Network connectivity issues
- Firewall blocking WebRTC traffic
- TURN server unavailable
MIT Licensed
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and questions, please open an issue on the repository.
