SDKs
Embed ForestVPN, from source.
Source SDKs for Apple and Android, a stable C ABI for everything else, and generated API clients for TypeScript, Rust and Swift. Add a package, build it from source, and ship mesh and tunnel inside your own app.
// Apple — source Swift package (UniFFI). Add the package, import the kit.
// Package.swift → dependencies:
// .package(url: "https://github.com/forestvpn/forestvpn-apple", from: "1.0.0")
import ForestVPNKit
// ForestVPNKit + ForestVPNFFI compile into your app target.
// Nothing prebuilt to vendor — iOS 18 / macOS 14 / tvOS 17.// Android — JNI bindings, built from source alongside your Gradle build.
// The forestvpn-android-jni crate compiles as part of your build; nothing prebuilt to drop in.
val engine = ForestVpnEngine(context) // client-core under the hood/* C ABI — the shipped header forestvpn_client.h. */
#include "forestvpn_client.h"
FvpnClient* client = NULL;
if (fvpn_client_open(app_data_dir, &client) == FVPN_OK) {
char* status_json = NULL;
fvpn_client_status_json(client, &status_json);
/* … use the JSON … */
fvpn_string_free(status_json);
fvpn_client_close(client);
}// Generated client for the /platform/v1 plane.
import { Configuration, ProjectsApi } from "@forestvpn/console-api";
const config = new Configuration({
basePath: "https://api.fvpn.net",
accessToken: process.env.FORESTVPN_API_KEY, // fvpn_…
});
const { data } = await new ProjectsApi(config).listMyProjects();// Generated client for the /platform/v1 plane.
use forestvpn_console_api_client as platform;
// Point the configuration at https://api.fvpn.net and authenticate
// with your fvpn_… key, then call the projects API.Apple ships as a source Swift package built with UniFFI; Android as JNI compiled from source. Nothing prebuilt to vendor — you build the engine alongside your app.
The SDK family
One engine, wrapped for every platform.
Apple — ForestVPNKit
source SwiftPMA Swift package built with UniFFI. Add the package URL, import ForestVPNKit, and the mesh and tunnel engine compiles straight into your app target — nothing prebuilt to vendor.
- ForestVPNKit + ForestVPNFFI product family
- UniFFI-generated Swift bindings (UniFFI 0.31)
- iOS 18 · macOS 14 · tvOS 17
- Consumer, Console and Admin API clients included
| Platform | Minimum OS | Product |
|---|---|---|
| iOS | iOS 18 | ForestVPNKit |
| macOS | macOS 14 | ForestVPNKit |
| tvOS | tvOS 17 | ForestVPNKit |
Android — JNI bindings
JNI · from sourceJNI bindings compiled from source alongside your Gradle build. The platform-agnostic client-core engine runs under the hood — there is no prebuilt package to drop in.
- forestvpn-android-jni bindings crate
- Built from source in your own build
- client-core engine under the hood
- Kotlin-facing surface
C ABI + Dart — forestvpn_client.h
C ABI · shipped headerA stable C ABI with a shipped header, forestvpn_client.h. Bind it from Dart, Go, or any language that speaks C: open a client, read status as JSON, drive the tunnel, subscribe to events.
- forestvpn-client-ffi — the C ABI
- Shipped header: forestvpn_client.h
- fvpn_client_open · fvpn_client_status_json · fvpn_client_close
- Dart FFI bindings via fvpn_init_dart_api
Generated API clients
generated from OpenAPIOne typed client per role plane, regenerated from the committed OpenAPI specs. Point it at the API origin and authenticate with a project-scoped key.
- TypeScript — @forestvpn/consumer, console and admin-api
- Rust — consumer, console and admin api-client crates
- Swift — ForestVPN Consumer, Console and Admin API clients
- Regenerated with task gen:api-clients
client-core — the engine
platform-agnosticThe platform-agnostic Rust engine every SDK wraps — the socket layer, the userspace network stack, MagicDNS, and the transport ladder that adapts to the network it is on.
- forestvpn-client-core
- magicsock socket layer + userspace netstack
- MagicDNS resolver
- Adaptive transports (direct UDP, DERP, QUIC-DERP)
Pick a language and start building.
Every SDK wraps the same engine and talks to the same Infrastructure API. Read the docs, add a package, and make your first call.