Skip to main content

A lightweight proxy that combines your frontend and backend into one link for easy development and sharing.

Project description

Dev Linker

Dev Linker starts your local development stack and routes frontend and backend traffic through one proxy URL, with optional LAN and public sharing.

Features

  • ๐Ÿš€ Unified Dev Proxy: Combines frontend (Vite/React) and backend (FastAPI/Flask/Node/Docker) into a single local and public URL.
  • ๐Ÿ” Auto Detection: Detects frontend/backend ports, runtime, Docker containers, and Vite servers automatically.
  • ๐Ÿ“ก Debug Request Logger: Live API traffic lines (method, path, status, latency) only in debug mode.
  • ๐Ÿงฉ Backend-Only Mode: If no frontend is detected, DevLinker still runs and forwards all traffic to backend.
  • ๐Ÿ” Auto API URL Sync: Updates frontend/.env.local with VITE_API_URL=http://localhost:<proxy-port> using a managed block.
  • ๐Ÿ›ก๏ธ Proxy CORS + Preflight: Handles common CORS/preflight behavior at the proxy layer, including credential-safe Origin handling.
  • ๐Ÿง  Smart Detection & Doctor: Real-time request analysis, backend intelligence, log analyzer, and devlinker doctor for instant diagnostics.
  • ๐Ÿ›ก๏ธ Auto-Fix Engine: devlinker fix applies safe fixes (like VITE_API_URL) and suggests code changes.
  • ๐ŸŒ Public Sharing: Share your local dev environment instantly with --url (startup) or devlinker share (runtime, no restart).
  • ๐Ÿ”„ Dynamic Tunnel Control: devlinker unshare disables public tunnel at runtime.
  • ๐Ÿ“ก WLAN Sharing: Prints LAN URL for same-network device access.
  • ๐Ÿง‘โ€๐Ÿ’ป Interactive CLI: Modern, colorized, emoji-rich terminal UX for all commands.
  • ๐Ÿงฉ Zero Config: Works out-of-the-box for most FastAPI, Flask, Vite, and Docker projects.
  • ๐Ÿงช Runtime Smoke Test: Built-in test for end-to-end proxy validation.
  • ๐Ÿ› ๏ธ Extensible: Modular architecture for future SaaS, dashboard, and team features.

Support DevLinker

If DevLinker helps you ship faster, consider supporting the project:

๐Ÿ’– Support DevLinker UPI Donate

  • ๐Ÿ’– UPI: devlinker@upi
  • ๐Ÿ”— UPI link: upi://pay?pa=devlinker@upi&pn=DevLinker&cu=INR&tn=Support%20DevLinker%20Project%20๐Ÿš€

CLI Commands & Options

  • devlinker โ€” Start proxy (local only, fast)
  • devlinker support โ€” Show UPI support QR code in terminal
  • devlinker --url โ€” Start with public tunnel (Cloudflare/ngrok)
  • devlinker share โ€” Enable public tunnel at runtime (no restart)
  • devlinker unshare โ€” Disable public tunnel at runtime
  • devlinker doctor โ€” Diagnose issues, see categorized problems and fixes
  • devlinker fix โ€” Auto-fix common issues (env, API paths, config)
  • devlinker --frontend 5173 --backend 5000 โ€” Override detected ports
  • devlinker --docker โ€” Auto-start Docker backend
  • devlinker --no-tunnel โ€” Force local-only mode
  • devlinker --no-lan โ€” Hide WLAN sharing URL
  • devlinker --interactive-backend โ€” Prompt to choose backend if multiple found
  • devlinker --proxy-port 18000 โ€” Use custom proxy port
  • devlinker --debug โ€” Enable debug mode (turns on live API request logger)
  • devlinker --version โ€” Show version

Project Structure

devlinker/
โ”œโ”€โ”€ devlinker/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ main.py
โ”‚   โ”œโ”€โ”€ runner.py
โ”‚   โ”œโ”€โ”€ detector.py
โ”‚   โ”œโ”€โ”€ proxy.py
โ”‚   โ””โ”€โ”€ tunnel.py
โ”œโ”€โ”€ setup.py
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ requirements.txt

Install

For local development:

pip install .

For editable local development:

pip install -e .

After publishing to PyPI:

pip install devlinker

Run

devlinker

Direct module run (without installing entrypoint script):

python -m devlinker.main

Typical startup output (TTY with Rich available):

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ โ™พ๏ธ  DevLinker v1.4.1        โ”‚
โ”‚ Smart Local Dev Environment โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

โœ” Detecting project...
โณ Booting local services...

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ DevLinker Ready โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Proxy     http://localhost:8001   โ”‚
โ”‚ WLAN      http://192.168.1.3:8001 โ”‚
โ”‚ Public    disabled (use --url)    โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

โœจ Ready in 5.5s
Powered by DevLinker ๐Ÿš€

Enable debug mode with live API request logging:

devlinker --debug

Debug mode request logger sample:

๐Ÿ›  Debug mode enabled: live API request logger is ON

๐Ÿ“ก Requests (Live)
GET    /api/users               200  45ms
POST   /api/login               401  120ms

Version check:

devlinker --version

Optional overrides:

devlinker --frontend 5173 --backend 5000

Backend override alias:

devlinker --backend-port 3001

Enable Docker auto-start explicitly:

devlinker --docker

Tunnel and Sharing Modes

By default, DevLinker starts fast local proxy only (no tunnel). To enable a public tunnel, use the --url flag:

devlinker --url

This will start the proxy and open a public tunnel (Cloudflare or ngrok). The output will show:

๐ŸŒ Enabling public tunnel...
โœ” Tunnel provider: Cloudflare
โœ” Public URL:
     https://xxxx.trycloudflare.com
โ„น Tip: Ctrl+Click to open link
โ„น Share this link with collaborators.

To force tunnel off (even if --url is passed):

devlinker --no-tunnel

When running without --url, youโ€™ll see:

โšก Skipping public tunnel (use --url to enable)

๐Ÿ’ก Need to share outside network?
๐Ÿ‘‰ Run: devlinker --url

Disable WLAN URL output:

devlinker --no-lan

Smart Detection & Auto-Fix System

DevLinker now includes an AI-powered detection and auto-fix engine:

  • Request Inspector: Real-time analysis of proxy traffic for common mistakes (missing /api prefix, 404s, CORS risks, upstream failures)
  • Backend Intelligence: Probes backend endpoints and type at startup for smarter routing and hints
  • Log Analyzer: Converts error messages (CORS, 404, connection refused) into human-readable explanations and actionable fixes
  • Smart Warning Engine: Prints clean CLI warnings and suggestions, e.g.:
โš ๏ธ  Detected direct backend call (localhost:5000)
๐Ÿ‘‰ Use /api/* instead of direct URL

All detection and fixes are modular, async-compatible, and production-ready. See devlinker/proxy.py, devlinker/detector_ai.py, and devlinker/logger.py for implementation.

Interactive backend selection (when local and Docker are both detected):

devlinker --interactive-backend

Disable interactive backend selection (keeps local-first behavior):

devlinker --no-interactive-backend

If port 8000 is already in use:

devlinker --frontend 5173 --backend 5000 --proxy-port 18000

Default behavior also tries fallback ports automatically when 8000 is busy:

โš  Port 8000 in use
โ„น Using proxy port: 8001

By default it scans the next 10 ports after the requested one, then tries 18000.

Frontend detection behavior:

  • Scans Vite defaults and fallback ports (5173 through 5190)
  • Also checks common alternatives (3000, 4173, 8080)
  • Retries during startup to catch slow boot cases
  • Performs readiness gating before proxy startup (waits until frontend looks like Vite and backend responds)

Important Frontend Rule

Frontend requests must use relative API paths:

fetch("/api/endpoint")

Do not hardcode backend host URLs in frontend code.

DevLinker also writes/updates a managed block in frontend/.env.local:

# devlinker-managed:start
VITE_API_URL=http://localhost:8001
# devlinker-managed:end

This keeps frontend API calls consistently routed through the proxy.

Use the proxy URL as your single entry point during development:

http://localhost:<proxy-port>

Avoid direct backend calls like http://localhost:5000 from browser-facing code.

Configuration File

DevLinker loads config from the first file found in this order:

  1. devlinker.yaml
  2. devlinker.yml
  3. devlinker.json

Example:

frontend: 5173
backend: 5000
proxy_port: 8001
tunnel: false

Backend Auto-Detection

Backend port detection runs in this order:

  1. Check localhost port 5000
  2. If not found, query Docker via Docker SDK (docker.from_env()) for published host-to-container port mappings
  3. Prioritize containers using labels when present (devlinker.role=backend, optional devlinker.port=<container-port>)
  4. Otherwise rank containers by likely backend identity (name hints like backend/api plus project-name hints)
  5. Use the best mapped host port automatically, even when internal port is not 5000
  6. If nothing is found, print next-step guidance and exit

If Docker SDK is unavailable, Dev Linker falls back to Docker CLI parsing as a compatibility path.

When both Local and Docker backends are available, Dev Linker prompts you to choose one (TTY mode) unless --no-interactive-backend is used.

If backend detection fails, Dev Linker prints a clear checklist showing what it checked and how to recover.

Detection messages include source labels, for example:

[OK] Backend detected (Local) -> port 5000

Example Docker dynamic-port message:

[WARN] Backend not found on port 5000
[INFO] Checking Docker containers...
[OK] Backend detected (Docker) -> port 32768

Dev Linker checks backend runtime in this order:

  1. Docker Compose (backend/docker-compose.yml, docker-compose.yaml, compose.yml, or compose.yaml)
  2. Docker (backend/Dockerfile)
  3. Node (backend/package.json)
  4. Python (backend/requirements.txt or backend/app.py)

Backend startup commands:

  • Docker Compose (default): manual run docker compose up --build in backend/
  • Dockerfile (default): manual run docker build -t devlinker-backend . then docker run --rm -p 5000:5000 devlinker-backend
  • Docker Compose/Dockerfile with --docker: Dev Linker runs those Docker commands for you
  • Node: npm run dev (or npm start when dev is missing)
  • Python: python app.py

For containerized Flask backends, ensure:

  • App binds to all interfaces: app.run(host="0.0.0.0", port=5000)
  • Port mapping is present: -p 5000:5000

Notes

  • runner.py expects frontend project in frontend and Python app in backend/app.py.
  • If those paths do not exist, Dev Linker skips launch and only tries to detect already-running services.
  • If frontend is missing but backend is available, DevLinker continues in backend-only mode.
  • Tunnel selection order is: cloudflared (TryCloudflare), then ngrok.
  • If cloudflared is unavailable and ngrok is not configured, Dev Linker prints one-time setup guidance.
  • You may need to set ngrok auth once on your machine using ngrok config add-authtoken .
  • Dev Linker prints a public URL with ngrok-skip-browser-warning=true only when ngrok is used.
  • Startup output includes selected tunnel provider (cloudflare or ngrok).
  • Proxy layer now supports WebSocket upgrades, including Vite HMR over shared links.
  • Proxy handles common CORS/preflight behavior and adds camera/mic permissions policy headers.
  • Live API request logging is disabled by default and only enabled with devlinker --debug.
  • Proxy listens on 0.0.0.0 and can print a WLAN URL for same-network sharing.
  • If WLAN access fails on Windows, allow the proxy port in firewall and confirm devices are on the same network.

Runtime Smoke Test

Run this test to validate proxy behavior end-to-end (frontend HTTP route, backend API forwarding, and WebSocket pass-through):

python -m unittest tests.test_proxy_runtime

The test spins up lightweight local frontend and backend apps, starts Dev Linker proxy, and verifies:

  • GET / is routed to frontend
  • POST /api/login is routed to backend
  • ws://.../hmr round-trip works through proxy

Troubleshooting Links

If local or shared links show blank pages, connection refused errors, or 404s, check these common causes:

  1. Docker backend binding
  • Symptom: http://localhost:<backend-port> refuses connection.
  • Cause: backend process inside container is bound to 127.0.0.1 instead of 0.0.0.0.
  • Fix: run backend with host 0.0.0.0 (example FastAPI/Uvicorn: uvicorn app.main:app --host 0.0.0.0 --port 8000).
  1. API prefix mismatch
  • Symptom: frontend loads through Dev Linker but API calls return 404.
  • Cause: frontend calls /api/..., but backend routes are mounted without /api prefix.
  • Fix: expose backend routes under /api (or adjust frontend paths to match backend routes).
  1. Vite host restrictions
  • Symptom: direct Vite URL works, Dev Linker proxy URL is blank or blocked.
  • Cause: Vite host protections reject proxied host/port.
  • Fix: set Vite server.host and server.allowedHosts to allow proxy use.

Quick isolate sequence:

  1. Open http://localhost:<backend-port>/docs (or /health) directly.
  2. Open Dev Linker local proxy URL and verify UI loads.
  3. Use browser network tab to check API status codes for /api/* requests.

Real-Time Development

  • Run devlinker to share one combined frontend/backend URL.
  • Vite HMR and other WebSocket flows are proxied end-to-end through Dev Linker.
  • Keep using relative frontend API paths (for example, /api/endpoint) so routing stays consistent locally and over tunnel.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devlinker-1.4.1.tar.gz (38.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devlinker-1.4.1-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

Details for the file devlinker-1.4.1.tar.gz.

File metadata

  • Download URL: devlinker-1.4.1.tar.gz
  • Upload date:
  • Size: 38.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for devlinker-1.4.1.tar.gz
Algorithm Hash digest
SHA256 271844c2a297dcc29e4e58542d6a12e34c110a47775f49200aca5d92f153b5e5
MD5 3899af916ef2093fb402cfc3a3ced955
BLAKE2b-256 e8e7d668736831055a19858fbd88c58da1712b74f2363f7f72b912b1fed4c158

See more details on using hashes here.

Provenance

The following attestation bundles were made for devlinker-1.4.1.tar.gz:

Publisher: publish.yml on mani1028/devlinker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file devlinker-1.4.1-py3-none-any.whl.

File metadata

  • Download URL: devlinker-1.4.1-py3-none-any.whl
  • Upload date:
  • Size: 39.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for devlinker-1.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1f8a2101aaca09e8b0a66290bb087a4cb57c9e68b2e9fee84d06b26265313c56
MD5 4d5dde916e05553986303340d117316f
BLAKE2b-256 69274777e86a670a8c997247dcdf72411f20fa1b91b175b8ec5eb15b0abfe81a

See more details on using hashes here.

Provenance

The following attestation bundles were made for devlinker-1.4.1-py3-none-any.whl:

Publisher: publish.yml on mani1028/devlinker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page