{"id":50928999,"url":"https://github.com/iluxav/xgate","last_synced_at":"2026-06-17T02:04:10.116Z","repository":{"id":350370735,"uuid":"1206420423","full_name":"iluxav/xgate","owner":"iluxav","description":"A tiny local reverse proxy for developers. Runs as a system service on port 80, manages /etc/hosts entries for you, and ships with a CLI that adds/removes routes live","archived":false,"fork":false,"pushed_at":"2026-04-10T02:38:20.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-10T04:26:03.702Z","etag":null,"topics":["developer-tools","localhost-management","proxy"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iluxav.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-09T22:38:37.000Z","updated_at":"2026-04-10T02:51:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/iluxav/xgate","commit_stats":null,"previous_names":["iluxav/xgate"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/iluxav/xgate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iluxav%2Fxgate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iluxav%2Fxgate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iluxav%2Fxgate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iluxav%2Fxgate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iluxav","download_url":"https://codeload.github.com/iluxav/xgate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iluxav%2Fxgate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34430691,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-tools","localhost-management","proxy"],"created_at":"2026-06-17T02:03:57.281Z","updated_at":"2026-06-17T02:04:10.110Z","avatar_url":"https://github.com/iluxav.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xgate\n\nA tiny local reverse proxy for developers. Runs as a system service on port 80, manages `/etc/hosts` entries for you, and ships with a CLI that adds/removes routes live — no restart needed.\n\n```\nsudo xgate add api.localhost http://localhost:8081\nsudo xgate add app.localhost http://localhost:5173\nsudo xgate ls\n```\n\nThat's it. `http://api.localhost` now proxies to `localhost:8081`.\n\n## Features\n\n- **Host-based routing** — map `app.localhost`, `api.localhost`, etc. to different upstream ports.\n- **Wildcard hosts** — `*.app.localhost` matches any subdomain.\n- **Live reload** — `xgate add`/`rm` mutate the running daemon; no restart, no dropped connections.\n- **`/etc/hosts` management** — entries are added/removed automatically.\n- **One-liner install** — on Linux (systemd) and macOS (launchd).\n- **Config-file driven** — routes persist in `/etc/xgate/config.yaml`.\n\n## Install\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/iluxav/xgate/main/install.sh | sudo bash\n```\n\nThe installer:\n\n1. Detects your OS (Linux or macOS) and arch (amd64 or arm64).\n2. Downloads the latest release binary from GitHub.\n3. Verifies the SHA-256 checksum.\n4. Installs the binary to `/usr/local/bin/xgate`.\n5. Creates `/etc/xgate/config.yaml` with a default config (if missing).\n6. Writes a systemd unit (Linux) or launchd plist (macOS).\n7. Enables and starts the service.\n\nAfter install, `xgate` is running on port 80 with an empty route table.\n\n### Pin a specific version\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/iluxav/xgate/main/install.sh | sudo XGATE_VERSION=v0.1.0 bash\n```\n\n### Uninstall\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/iluxav/xgate/main/uninstall.sh | sudo bash\n```\n\nThis stops and removes the service and the binary. Your `/etc/xgate/` directory is left in place so your routes aren't silently destroyed — remove it manually with `sudo rm -rf /etc/xgate` if you're done for good.\n\n## Build from source\n\nRequires Go 1.25+.\n\n```bash\ngit clone https://github.com/iluxav/xgate.git\ncd xgate\nmake build\nsudo ./xgate serve\n```\n\n## Usage\n\nAll mutating CLI commands require `sudo` (the admin socket is root-owned, mode `0600`).\n\n### Add a route\n\n```bash\nsudo xgate add gateway.localhost http://localhost:8081\n```\n\nOutput:\n```\nadded gateway.localhost -\u003e http://localhost:8081 (1 routes)\n```\n\n### Wildcard subdomains\n\n```bash\nsudo xgate add '*.app.localhost' http://localhost:5173\n```\n\nNow `http://anything.app.localhost` proxies to `localhost:5173`. Exact matches always beat wildcard matches, so you can mix them freely.\n\nOn macOS, `*.localhost` resolves to `127.0.0.1` automatically. On Linux, you need either individual `/etc/hosts` entries (xgate manages these for exact hosts) or a local resolver like `dnsmasq` configured for `*.localhost`.\n\n### List routes\n\n```bash\nsudo xgate ls\n```\n\nOutput:\n```\nHOST                 TARGET\ngateway.localhost    http://localhost:8081\n*.app.localhost      http://localhost:5173\n```\n\nIf the daemon isn't running, `ls` falls back to reading `/etc/xgate/config.yaml` directly — this works without `sudo` because the config file is `0644`.\n\n### Remove a route\n\n```bash\nsudo xgate rm gateway.localhost\n```\n\n### Reload config from disk\n\nIf you hand-edit `/etc/xgate/config.yaml`, tell the daemon to re-read it:\n\n```bash\nsudo xgate reload\n```\n\n## Configuration\n\nThe config file lives at `/etc/xgate/config.yaml`:\n\n```yaml\nlisten: \":80\"\nmanage_hosts: true\nroutes:\n  - host: gateway.localhost\n    target: http://localhost:8081\n  - host: \"*.api.localhost\"\n    target: http://localhost:8081\n  - host: app.localhost\n    target: http://localhost:5173\n```\n\n- **`listen`** — address to bind the HTTP server. Default `:80`. Change to `:8080` (or similar) if you don't want to run as root. Changing this requires a service restart: `sudo systemctl restart xgate` / `sudo launchctl unload … \u0026\u0026 sudo launchctl load …`.\n- **`manage_hosts`** — whether xgate should add/remove entries in `/etc/hosts` automatically. Wildcard routes are skipped. Default `true`.\n- **`routes`** — list of `host → target` mappings. Prefer managing these via `xgate add`/`rm` rather than editing by hand, because writes from the CLI drop YAML comments on rewrite.\n\n## How it works\n\nxgate is a single Go binary that plays two roles:\n\n- **`xgate serve`** — the daemon. Runs the HTTP reverse proxy on `:80` and an admin Unix socket at `/var/run/xgate.sock` (mode `0600`). This is what the service unit launches.\n- **`xgate add|rm|ls|reload`** — the CLI. Dials the admin socket, sends one JSON command, prints the response.\n\nLive reloads work via an `atomic.Pointer[Router]` inside the daemon: when a route is added or removed, the daemon builds a fresh routing table in memory and atomically swaps the pointer. In-flight requests finish on the old table, new requests see the new one — no locks on the hot path.\n\n## Flag and environment overrides\n\nUseful for running a non-root dev daemon against a local config without clobbering your installed instance:\n\n```bash\nxgate --config /tmp/dev.yaml --socket /tmp/xgate.sock serve\nxgate --config /tmp/dev.yaml --socket /tmp/xgate.sock add test.local http://localhost:3000\n```\n\n| Flag         | Env var          | Default                   |\n|--------------|------------------|---------------------------|\n| `--config`   | `XGATE_CONFIG`   | `/etc/xgate/config.yaml`  |\n| `--socket`   | `XGATE_SOCKET`   | `/var/run/xgate.sock`     |\n\nPriority: flag \u003e env var \u003e default.\n\n## Logs\n\n**Linux:**\n```bash\njournalctl -u xgate -f\n```\n\n**macOS:**\n```bash\ntail -f /var/log/xgate.log\n```\n\n## Troubleshooting\n\n**\"xgate daemon not running\"** — the CLI couldn't reach `/var/run/xgate.sock`. Start the service:\n\n- Linux: `sudo systemctl start xgate`\n- macOS: `sudo launchctl load /Library/LaunchDaemons/com.xgate.daemon.plist`\n\n**\"bind: permission denied\" in logs** — the daemon can't bind to port 80. On Linux the systemd unit grants `CAP_NET_BIND_SERVICE`; if you're running outside the unit, use `sudo` or change `listen` in the config to an unprivileged port.\n\n**\"no route for host: …\"** — you requested a hostname that doesn't match any route. Check `sudo xgate ls`. Remember that exact matches beat wildcards, and wildcards need a `*.` prefix.\n\n**Routes don't resolve** — the browser might be resolving the hostname directly instead of going through xgate. Check `/etc/hosts` — for exact-match hosts the installer keeps a marker block there. For wildcards on Linux you need a DNS-level solution (dnsmasq).\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filuxav%2Fxgate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filuxav%2Fxgate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filuxav%2Fxgate/lists"}