Transfer files between machines through the web, through a CLI, or both.
Goto https://e2ecp.com and enter a room. Have another peer enter the same room to transfer files between the two.
You can use the command-line tool, e2ecp, as a client that can send/receive from the website or from another command-line:
Sending a file:
e2ecp send <file>Receiving a file:
e2ecp receiveUploading to your account:
Register at https://e2ecp.com to store files in your encrypted account. Your files are end-to-end encrypted - the server never sees the plaintext.
Authenticate from CLI:
e2ecp authUpload encrypted files:
e2ecp upload <file>Access your files anytime from the website or CLI. Share them with generated links that include the decryption key. The password you enter must match your account password.
The command-line tool, e2ecp, is available as a single binary for Windows, Mac OS, or Linux. Simply download the latest release or install with:
brew install schollz/tap/e2ecpparu -S e2ecp
# or
yay -S e2ecpcurl https://e2ecp.com | bashMake sure you have node (>=v24) and Go installed, then clone and build:
git clone https://github.com/schollz/e2ecp
cd e2ecp && makeYou can run your own relay server if you want to self-host, using the command-line tool.
e2ecp serve --port 8080By default, the relay only serves WebSocket rooms. To enable the profile, login, and encrypted file storage APIs, create a .env file:
ALLOW_STORAGE_PROFILE=yes
# Database configuration
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASSWORD=your_password
DATABASE_NAME=e2ecp
# Email configuration (for registration/verification)
MAILJET_API_KEY=your_api_key
MAILJET_API_SECRET=your_api_secret
MAILJET_FROM_EMAIL=noreply@yourdomain.com
MAILJET_FROM_NAME=YourAppNameRequires PostgreSQL for user accounts and file storage. Get Mailjet credentials at https://www.mailjet.com. If ALLOW_STORAGE_PROFILE is not yes, profile endpoints stay disabled and neither database nor Mailjet are required.
You can also run the relay server using Docker. There are two options:
First, build the binary locally:
make buildThen build and run the Docker container:
# Build the Docker image
docker build -t e2ecp-relay .
# Run with default settings (port 3001)
docker run -p 3001:3001 e2ecp-relay
# Run with custom settings
docker run -p 8080:8080 e2ecp-relay --port 8080 --max-rooms 50 --max-rooms-per-ip 5 --log-level debugUse the multi-stage Dockerfile that builds both the web assets and Go binary:
# Build the Docker image from source
docker build -f Dockerfile.build -t e2ecp-relay .
# Run with default settings
docker run -p 3001:3001 e2ecp-relay
# Run with custom settings
docker run -p 8080:8080 e2ecp-relay --port 8080 --max-rooms 50 --max-rooms-per-ip 5 --log-level debugAvailable options:
--port: Port to listen on (default: 3001)--max-rooms: Maximum number of concurrent rooms (default: 10)--max-rooms-per-ip: Maximum rooms per IP address (default: 2)--log-level: Logging level - debug, info, warn, error (default: info)
compose.yml
services:
e2ecp-relay:
pull_policy: build
build:
context: https://github.com/schollz/e2ecp.git#${VERSION:-main}
dockerfile: Dockerfile
labels:
- x-e2ecp-relay-version=${VERSION:-main}
ports:
- ${PORT:-3001}:${PORT:-3001}
command:
- --port
- ${PORT:-3001}
- --max-rooms
- ${MAX_ROOMS:-10}
- --max-rooms-per-ip
- ${MAX_ROOMS_PER_IP:-2}
- --log-level
- ${LOG_LEVEL:-info}.env
VERSION=v3.0.5
PORT=8080
MAX_ROOMS=50
MAX_ROOMS_PER_IP=5
LOG_LEVEL=debug
ALLOW_STORAGE_PROFILE=yes
compose.yml
services:
e2ecp-relay:
pull_policy: build
build:
context: https://github.com/schollz/e2ecp.git#${VERSION:-main}
dockerfile: Dockerfile.build
labels:
- x-e2ecp-relay-version=${VERSION:-main}
ports:
- ${PORT:-3001}:${PORT:-3001}
command:
- --port
- ${PORT:-3001}
- --max-rooms
- ${MAX_ROOMS:-10}
- --max-rooms-per-ip
- ${MAX_ROOMS_PER_IP:-2}
- --log-level
- ${LOG_LEVEL:-info}.env
VERSION=v3.0.5
PORT=8080
MAX_ROOMS=50
MAX_ROOMS_PER_IP=5
LOG_LEVEL=debug
ALLOW_STORAGE_PROFILE=yes
This project is created and maintained by Zack. If you find it useful, please consider sponsoring me on GitHub Sponsors.
It works by using a simple peer-to-peer connection through a knowledge-free websocket-based relay server. All data transferred is encrypted using end-to-end encryption with ECDH P-256 key exchange and AES-GCM authenticated encryption, meaning the relay server does not have access to the data being transferred.
e2ecp includes comprehensive test suites to ensure reliability:
Run Go tests for the core functionality:
go test -v ./...Playwright tests verify web-to-web and web-to-CLI file transfers:
cd tests
./run-tests.shSee tests/README.md for detailed testing documentation.
MIT — see LICENSE.
