A modern desktop and web application for connecting to the El Tor network - a privacy-focused network that allows users to share bandwidth as relays or consume bandwidth as clients, with built-in payment capabilities.
This project supports dual deployment modes:
- 🖥️ Desktop App: Native Tauri application with system tray integration
- 🌐 Web App: Browser-based application with standalone Rust backend
┌─────────────────┐ ┌─────────────────┐
│ React Frontend │ │ Rust Backend │
│ │ │ │
│ • UI Components │◄──►│ • Tor Control │
│ • State Mgmt │ │ • Eltord Mgmt │
│ • Routing │ │ • Process Ctrl │
└─────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Web App │ │ Tauri App │
│ (HTTP APIs) │ │ (IPC Calls) │
└─────────────┘ └─────────────┘
- Node.js 18+ with pnpm
- Rust 1.70+
- Eltord project at
~/code/eltord/
# Terminal 1: Start Rust backend
cd backend
cargo run
# Terminal 2: Start React frontend
cd frontend
pnpm dev:web
cd frontend
pnpm dev:tauri
eltor-app/
├── frontend/ # React Frontend (Vite + Tauri)
│ ├── src/
│ │ ├── components/ # UI Components
│ │ ├── services/ # API abstraction layer
│ │ ├── utils/ # Platform detection
│ │ └── hooks/ # Custom React hooks
│ ├── src-tauri/ # Tauri desktop app
│ └── package.json
├── backend/ # Standalone Rust server
│ ├── src/
│ │ └── main.rs # HTTP API server
│ └── Cargo.toml
└── README.md
- Tor Network Control: Connect/disconnect from Tor
- Eltord Process Management: Start/stop eltord client processes
- Dual Mode Support: Web browser OR native desktop app
- System Tray Integration: (Desktop mode only)
- Real-time Status Updates: Process monitoring and notifications
The app automatically detects whether it's running in web or desktop mode and uses the appropriate API layer:
- Desktop: Direct IPC calls to embedded Rust backend
- Web: HTTP requests to standalone Rust server
# Quick start
npm i
npm run tauri # quick start to run the tauri app with rust invoke backend
npm run web # quick start to run web frontend with rust rest backend
# Frontend
cd frontend
pnpm dev:web # Web development mode
pnpm dev:tauri # Desktop development mode
# Backend
cd backend
cargo build # Build binary
cargo run # Start HTTP server
# Docker
npm run docker
Web Development:
- Frontend runs on
http://localhost:5173
- Backend API on
http://localhost:5174
- Supports hot reload for both frontend and backend
Desktop Development:
- Single command starts both frontend and embedded backend
- System tray integration with menu controls
- Native file system access
# Build frontend
cd frontend && pnpm build:web
# Build backend
cd backend && cargo build --release
# Deploy frontend to static hosting (Vercel, Netlify)
# Deploy backend to cloud service (Railway, Fly.io)
cd frontend
pnpm build:tauri
Outputs platform-specific installers:
- Windows:
.msi
,.exe
- macOS:
.dmg
,.app
- Linux:
.deb
,.rpm
,.AppImage
# Development mode (separate frontend/backend)
npm run web
# Production mode (integrated backend serves frontend)
npm run prod
# Build and start production server
npm run prod
# Or run steps separately:
npm run build:prod # Build frontend + backend
npm run start:prod # Start integrated server
Copy .env.example
to .env
and configure:
cp .env.example .env
# Edit .env with your configuration
Key Environment Variables:
BIND_ADDRESS
:127.0.0.1
(localhost) or0.0.0.0
(all interfaces)BACKEND_PORT
orPORT
: Port number (default: 5174)BACKEND_URL
: Base URL for API calls
Mult Arch Build Prereqs
docker buildx create --name mybuilder --driver docker-container --use
docker buildx inspect --bootstrap
docker run --privileged --rm tonistiigi/binfmt --install all
# if you get errors you might need to turn off (or on) rosetta
orb config set rosetta false
# Build and run with Docker Compose
npm run docker
# Or manually:
docker-compose up --build
# Localhost only (secure)
npm run prod
# External access on port 80
BIND_ADDRESS=0.0.0.0 PORT=80 BACKEND_PORT=80 BACKEND_URL=https://yourdomain.com npm run prod
# Behind reverse proxy
BIND_ADDRESS=127.0.0.1 PORT=3000 BACKEND_URL=https://api.yourdomain.com npm run prod
Configure Tor Browser to use the El Tor network:
macOS:
curl -L https://bitbucket.org/eltordev/eltor-app/raw/master/scripts/mac/install.sh | bash
Linux:
curl -L https://bitbucket.org/eltordev/eltor-app/raw/master/scripts/linux/install.sh | bash
Connectivity Check:
- Open Tor Browser
- Navigate to Circuit info (lock icon in URL bar)
- Look for IP
170.75.160.21
in the circuit
Hidden Service Test:
http://3zlcerfvzmmdj2zv5j2lnz32762dwukcznrimbxllve4dzbjhmxkc4id.onion
Linux Relay Setup:
curl -L https://bitbucket.org/eltordev/eltor-app/raw/master/scripts/linux/relay.sh | bash
Start Relay:
./tor -f torrc
Run as Systemd Service:
sudo tee /etc/systemd/system/tor.service << EOF
[Unit]
Description=ElTorRelay
After=network.target
[Service]
User=root
ExecStart=/home/root/eltor/tor -f /home/root/eltor/torrc
PIDFile=/var/run/tor/tor.pid
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable tor
sudo systemctl start tor
Monitor Relay:
sudo apt install nyx
nyx -i 127.0.0.1:8061
- No data collection: All processing happens locally
- Tor integration: Built-in privacy protection
- Process isolation: Eltord runs in separate processes
- System tray: Minimal UI footprint
- Fork the repository
- Create a feature branch
- Make your changes
- Test in both web and desktop modes
- Submit a pull request
MIT License - see LICENSE file for details
El Tor: Privacy-first networking with economic incentives 🚀
To copy local phoenix conf folder over to umbrel via ssh for testing:
scp ~/.phoenix/* umbrel@umbrel.local:~/umbrel/app-data/eltor-app/data/phoenix