Route every Mac connection with intent.
A native VPN and local proxy client built for flexible routes, fast recovery,
and everyday control.
Waypoint brings system-wide VPN, per-app proxy endpoints, traffic policies, tunnel chains, and automatic failover into one focused macOS app. Add a link, a WireGuard profile, or a subscription; then decide exactly where traffic goes.
brew install xray
git clone https://github.com/mrvasil/Waypoint.git
cd Waypoint
make installLaunch the app:
open -a WaypointThe first system VPN connection asks for an administrator password once. Waypoint
installs a narrow privileged service for utun and route management; later launches
reuse it without asking again.
┌─ Direct
Mac ──► Waypoint ──► first-match rules ├─ Block
│ ├─ Tunnel
│ ├─ WG ──► VLESS (chain)
│ └─ WG / VLESS / chain (fallback)
│
├─ System VPN ───────────────► all Mac traffic
└─ SOCKS5 / HTTP :10808 ────► selected apps
Rules are evaluated from top to bottom. Traffic that does not match a policy uses the main VPN route. Local proxies have their own route profiles and can run at the same time as the system VPN.
Waypoint keeps the utun interface and fail-closed routes in place while Wi-Fi,
Ethernet, or a phone hotspot changes underneath it. Xray is rebound to the new
physical path only after that path is ready, so traffic does not briefly escape
through the normal default route.
WireGuard peers receive persistent keepalive, fallback decisions use hysteresis, and ordinary route changes are applied through Xray's local API without restarting the data plane.
| Input | Support |
|---|---|
| WireGuard | Full wg-quick profile with one or more peers |
| VLESS | TCP, WebSocket, gRPC, HTTPUpgrade, XHTTP, TLS, Reality, Vision |
| VMess | v2rayN base64 JSON |
| Trojan | URI import with TLS defaults |
| Shadowsocks | SIP002 and base64 URI forms |
| Upstream proxy | socks:// and http:// |
| Subscription | Plain or base64 link list, grouped and refreshed every 15 minutes |
- SOCKS5 with UDP support
- HTTP proxy
- Loopback-only or LAN listening
- Optional username and password
- A separate route profile for every endpoint
- Add tunnel links, a WireGuard config, or a subscription URL.
- Open VPN and choose a tunnel, chain, or fallback group as the main route.
- Add first-match policies for domains, networks, GeoSite, or GeoIP lists.
- Turn on the system VPN, local proxies, or both from the dashboard or menu bar.
Tunnel latency appears next to each route as soon as its individual check finishes. Subscription nodes stay grouped under their source instead of becoming an unstructured list.
How system VPN works
Waypoint creates a macOS utun interface and two more-specific IPv4/IPv6 routes.
The embedded helper passes TCP and UDP packets to Xray's TUN inbound. Xray itself
runs as the signed-in user; only interface and route lifecycle operations stay in
the restricted root service.
The service validates every file, user, interface, argument, and executable path. If a candidate Xray configuration fails, Waypoint restores the last confirmed one. If Xray exits unexpectedly, the helper attempts recovery before removing protected routes.
ICMP is not supported by Xray's TUN implementation, so the system ping command is
not a VPN connectivity test. TCP and UDP traffic are supported.
How tunnel chains and fallback work
A chain lists hops from the Mac to the final exit. For example, WG SE → VLESS NL
means the VLESS connection is established through WireGuard.
A fallback group may contain tunnels and reusable chains. The first candidate is available immediately during startup. Background observations then choose a healthy route within the configured latency threshold. A new selection must be confirmed, and one transient probe failure does not move traffic to another route.
If every candidate fails, the group either blocks traffic or uses Direct according to its explicit final action. It never silently changes to Direct.
How physical network bypass works
Without an explicit egress interface, a full-tunnel VPN can route Xray's own outbound
sockets back into the same utun. Waypoint avoids that loop by binding outbound
sockets to the active physical interface with IP_BOUND_IF and routing DNS through
the same protected path.
The interface is selected from macOS Network Service Order instead of the current default route, which may already point at a VPN. You can disable this behavior or choose an interface manually in Settings.
Requires macOS 15+, Swift 6, Command Line Tools, and Xray.
make build # debug build
make run # launch from source
make test # deterministic parser, routing, migration, and runtime checks
make live # live Xray and tunnel verification
make app # signed build/Waypoint.app bundle
make install # install into /ApplicationsUseful focused checks:
swift run waypoint-tests --live-latency
swift run waypoint-tests --validate-hot-routing
swift run waypoint-tests --validate-routing
swift run waypoint-vpn-lifecycle-tests
.build/debug/WaypointVPNLauncher --self-testSources/Waypoint/ SwiftUI app and state model
Sources/WaypointCore/ parsers, Xray config, routing, persistence
Sources/WaypointVPNHelper/ privileged utun and route lifecycle
Sources/WaypointVPNLauncher/ one-time service installer and IPC client
Sources/WaypointVPNLifecycle/ transactional Xray reload state machine
Sources/WaypointTests/ deterministic and live checks
Resources/ app icon sources
Persistent state is stored in ~/Library/Application Support/Waypoint/state.json.
On first launch, Waypoint copies the previous app's state automatically and leaves
the original untouched as a fallback.
- Subscription import accepts plain or base64 link lists, not Clash YAML.
- Hysteria2 and TUIC are not available because they are not Xray protocols.
- Local builds use ad-hoc signing; Developer ID packaging and a DMG are not included yet.
- System VPN uses a restricted LaunchDaemon rather than Network Extension, so it does not appear as a separate profile in System Settings → VPN.
Waypoint is available under the MIT License.
Built for people who want routing to stay understandable when the network is not.