Share local dev servers on your LAN, with optional Cloudflare tunnel. TCP proxy with QR code, HTTP log, token auth.
Project description
localnet-control
Instantly share local dev services with anyone on your network.
LAN first, with optional Cloudflare Tunnel for public access.
Platform: This version targets Linux first. macOS may work. Windows is not yet supported.
What is it?
localnet-control creates a lightweight TCP proxy that exposes your local dev service to every device on your LAN — no internet required.
Your app (localhost:3000)
↓
localnet proxy → http://192.168.1.42:3000
↓
Anyone on your Wi-Fi can open it instantly
Install
pip install localnet-control
Or install from source (for development):
git clone https://github.com/hoysengleang/localnet.git
cd localnet
pip install -e .
Quick Start
# 1. Start your app (e.g. React, FastAPI, etc.)
npm run dev # running on localhost:3000
# 2. Share it on your network
localnet share 3000
# → Prints: http://192.168.1.42:3000
# → Shows a QR code for mobile devices
Commands
share — Expose a local port
localnet share 3000 # share port 3000
localnet share localhost:8080 # share a specific host:port
localnet share 3000 --name my-api # give it a friendly name
localnet share 3000 --port 9000 # listen on a different port
localnet share 3000 --no-qr # skip the QR code
localnet share 3000 --http-log # show live HTTP request log (method, path, status, latency)
localnet share 3000 --token myteam123 # require token for access (see Token Auth below)
localnet share 3000 --tunnel # create a public URL via Cloudflare Tunnel
--tunnel will auto-download cloudflared on first use if it is not already installed.
Access control:
localnet share 3000 --allow 192.168.1.10 # allow only this IP
localnet share 3000 --allow 10.0.0.0/24 # allow a subnet
localnet share 3000 --deny 192.168.1.50 # block a specific IP
localnet share 3000 --allow 192.168.1.0/24 --deny 192.168.1.99 # combine rules
Token auth — How clients provide the token
When you share with --token SECRET, clients must send the token in one of these ways:
1. URL query parameter (browsers, simple clients):
http://192.168.1.42:8100/?token=myteam123
2. Authorization header (API clients, curl, fetch, axios):
curl -H "Authorization: Bearer myteam123" http://192.168.1.42:8100/
Share the full URL with ?token=... for easy access, or tell your team to add the header for API calls.
list — Show active shares
localnet list
stop — Stop a share
localnet stop 3000 # stop by port number
localnet stop my-api # stop by name
scan — Discover other shares on your network
localnet scan
Finds other localnet-control instances running on your LAN. Great for teams.
info — Show network info
localnet info
Displays your hostname, primary LAN IP, and all network interfaces.
How it works
- Detects your LAN IP automatically using a UDP socket trick (no traffic sent)
- Binds to
0.0.0.0on the chosen port so all network interfaces are reachable - Proxies TCP traffic bidirectionally between LAN clients and your local service
- Prints a shareable URL and QR code so anyone can connect instantly
- Saves state to
~/.localnet-control/services.jsonto track active shares - Broadcasts presence via UDP so
localnet scancan discover other instances
Options Reference
| Flag | Description |
|---|---|
-p, --port |
Custom port to listen on (default: same as target) |
-n, --name |
Friendly name for this share |
--expose |
Use the exact same port as the target |
--no-qr |
Disable QR code output |
--tunnel |
Create a public URL with Cloudflare Tunnel (auto-downloads cloudflared if missing) |
--http-log |
Live HTTP request log (method, path, status, latency) |
--token SECRET |
Require token; clients use ?token=SECRET or Authorization: Bearer SECRET |
--allow IP/CIDR |
Whitelist an IP or subnet (repeatable) |
--deny IP/CIDR |
Blacklist an IP or subnet (repeatable) |
Requirements
| Dependency | Purpose |
|---|---|
| Python 3.9+ | Runtime |
| Linux | Primary target platform |
rich |
Terminal UI (tables, panels, colors) |
qrcode |
QR code generation |
Publish to PyPI (for maintainers)
- Create a PyPI account: https://pypi.org/account/register/
- Set up Trusted Publishing: PyPI → Account Settings → Publishing → Add pending publisher:
- PyPI project:
localnet-control - Owner:
hoysengleang, Repo:localnet - Workflow:
release.yml
- PyPI project:
- Bump version in
pyproject.tomlandsrc/localnet_access/__init__.py - Push a tag:
git tag v0.2.0 git push origin v0.2.0
- The GitHub Action will build and publish to PyPI.
Project Structure
src/localnet_access/
├── cli.py # Commands and argument parsing
├── proxy.py # Async TCP proxy engine
├── network.py # LAN IP detection and port utilities
├── display.py # Terminal UI with rich
├── acl.py # IP/CIDR access control rules
├── scanner.py # LAN discovery (broadcast + scan)
└── Policy/ # Policy enums (discovery port, magic, etc.)
MIT License · Built for local development workflows on Linux
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file localnet_control-0.2.0.tar.gz.
File metadata
- Download URL: localnet_control-0.2.0.tar.gz
- Upload date:
- Size: 23.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
260a22ffaa732cb3eefe2505ebeb93df786b914b3aa07a0420626f1d82b704cf
|
|
| MD5 |
cf92d4d812e5171c47aaa850c9104bf1
|
|
| BLAKE2b-256 |
8aaf00ec6b464a969a2cd2ead82b494b4db1370bfa188a470121b5035f71fedd
|
Provenance
The following attestation bundles were made for localnet_control-0.2.0.tar.gz:
Publisher:
release.yml on hoysengleang/localnet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
localnet_control-0.2.0.tar.gz -
Subject digest:
260a22ffaa732cb3eefe2505ebeb93df786b914b3aa07a0420626f1d82b704cf - Sigstore transparency entry: 1029668204
- Sigstore integration time:
-
Permalink:
hoysengleang/localnet@b7145e64454c8d16307281dc5482c0b20db3f887 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hoysengleang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b7145e64454c8d16307281dc5482c0b20db3f887 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file localnet_control-0.2.0-py3-none-any.whl.
File metadata
- Download URL: localnet_control-0.2.0-py3-none-any.whl
- Upload date:
- Size: 22.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe7663ed8949940b4637fc3d13d9eb53bb5e5429d33df5aa7da9cdf993dab495
|
|
| MD5 |
c8247273aecd6e4ac4e03f0a04de95c0
|
|
| BLAKE2b-256 |
99c88959218b76f362d7f9fd14d6a8b9f328f36a10877b8d011aad3b67066ebb
|
Provenance
The following attestation bundles were made for localnet_control-0.2.0-py3-none-any.whl:
Publisher:
release.yml on hoysengleang/localnet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
localnet_control-0.2.0-py3-none-any.whl -
Subject digest:
fe7663ed8949940b4637fc3d13d9eb53bb5e5429d33df5aa7da9cdf993dab495 - Sigstore transparency entry: 1029668211
- Sigstore integration time:
-
Permalink:
hoysengleang/localnet@b7145e64454c8d16307281dc5482c0b20db3f887 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hoysengleang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b7145e64454c8d16307281dc5482c0b20db3f887 -
Trigger Event:
workflow_dispatch
-
Statement type: