Prerelease SDK, MIT licence

Connect companion apps.
Your host keeps the data.

Link iOS, Android, macOS, and Windows apps to local services on a paired host. Ship transport alone or add native views; users pick private networks or self-hosted relays.

Prerelease SDK with no managed relay. Your host must stay awake and online.

Your app · connected by TetherIllustrative connection

iOS 18+, macOS 15+, Android API 26+, Windows x64 .NET 10

Source-built Rust core over a C ABI

Transport and UI packaged separately

Architecture

Encrypted between paired devices on chosen routes

Clients verify a pinned host with SPAKE2 and Noise before sending API streams or app-encoded media.

Private or VPN routes cut exposure and send media over Noise-delegated, short-lived QUIC datagrams.

Self-hosting guide
Connection pathPrivate network / VPN
Companion
Paired host
Application data & permissionsYour host
Host identityPinned to the app
Relay seesNo relay on this path

Native modules

Ship transport alone or add native views

Optional UI views match your theme for pairing, switching hosts, offline states, and removing devices.

macOS native fixture showing saved hosts and an offline connection

Native SDK fixture captures with synthetic hosts. These illustrate interface layout, not a live network connection. Capture context and limits

macOS 15+

Swift host and client on Apple Silicon and Intel, with optional SwiftUI views you can embed in AppKit.

iOS 18+

Client on arm64 devices and Apple Silicon simulators, with optional SwiftUI views you can embed in UIKit.

Android API 26+

Kotlin library over JNI with optional Material 3 views; QR scanning stays a callback.

Windows x64 (.NET 10)

Host and client via .NET packages, with optional WinUI controls for existing windows.

How it works

From local service to paired client

01

Allow fixed services

Map named targets like a local HTTP API so clients can't reach arbitrary ports.

02

Pair with an invite

Open a temporary host invite and scan or enter it to pin both app-specific identities.

03

Use the chosen route

Send API streams or media via VPN or containerised relay; route changes re-verify the host.

Start building

Add Tether to your build

Use the integration docs to add TetherKit from GitHub, embed packages/android, or add the Windows NuGets from Releases. Create TetherClient with your app ID, hold TetherConnectionStore for your scene, ViewModel, or window, and close on teardown.

Your app handles signing, Keychain groups, and Apple export-compliance updates when linking Noise.

Swift Package · iOS 18+ / macOS 15+
.package(
  url: "https://github.com/fledgeling-co/tether.git",
  from: "0.1.0-preview.1"
)

let client = try TetherClient(
  appID: "com.example.companion"
)
let connections = try TetherConnectionStore(client: client)
TetherWorkspaceView(store: connections)

// When the scene stops monitoring: connections.stopMonitoring()
Kotlin + Compose · API 26+
// Embed packages/android modules in your build.
val client = TetherClient(
  context.applicationContext, "com.example.companion"
)
val connections = TetherConnectionStore(client)

// Inside your MaterialTheme:
TetherWorkspace(store = connections)

// In ViewModel.onCleared(): connections.close()
.NET + WinUI · Windows x64
// Packages: Fledgeling.Tether.Windows + Fledgeling.Tether.WinUI
var client = new TetherClient(
    "com.example.companion"
);
var connections = new TetherConnectionStore(client);
window.Content = new TetherClientView(connections);

// On window close: await connections.DisposeAsync();
// Then client.Dispose();

Open source

MIT source and clear limits

Public source and platform integration docs live on GitHub with CI checks. The cryptography and lifecycle code haven't had a professional audit, and prerelease APIs may change.

Before you build

A few useful answers.

Do you run a managed relay?

No. You self-host the containerised relay where persistent connections work, unlike serverless Vercel Functions.

What happens when the host sleeps?

Connections stop until it wakes. The relay doesn't hold an offline copy, inbox, or queued writes.

Has the cryptography been audited?

Not professionally. CI and local fixtures check pairing, allowed services, revoked clients, and tampered storage.

Do I need Tether's UI views?

No. Transport ships without UI dependencies on every platform, so you can build custom controls.

How do owners grant and revoke access?

Owners open a temporary host invite that clients enter or scan to pin app-specific identities. Clients only reach fixed local services, and the host can revoke access.

Does Tether supply audio or video codecs?

No. Your app owns capture permissions and encoding, sending bounded packets over QUIC datagrams or relay WebSockets.

Wire up your companion client

Read the platform integration docs, check the security boundaries, and pair with a local service.

Start building