# NEAXCE
**Repository Path**: xhea/NEAXCE
## Basic Information
- **Project Name**: NEAXCE
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-08-14
- **Last Updated**: 2026-08-14
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
**A Swift/C VPN engine for iOS and macOS that speaks Xray-compatible protocols straight through Apple's [`NEPacketTunnelProvider`](https://developer.apple.com/documentation/networkextension/nepackettunnelprovider) — without [`gomobile`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile) or an embedded Go core.**
[](https://github.com/pinusmassoniana/NEAXCE/actions/workflows/ci.yml)
[](https://swift.org)
[](https://developer.apple.com/documentation/networkextension)
[](LICENSE)
[](#transport-status)
[Why](#why-neaxce) · [Features](#features) · [Install](#install) · [Integrate](#integrate-in-three-files) · [Transport status](#transport-status) · [Limits](#known-limitations)
> [!WARNING]
> **Alpha.** The engine has run on real iOS devices with VLESS+gRPC and VLESS+XHTTP. Reality and Shadowsocks are partial (see [Transport status](#transport-status)). The public API is not stable yet.
## Why NEAXCE?
Apple runs a Packet Tunnel in an app extension with a hard memory ceiling — historically **15 MB**, raised to at most **50 MB** on recent iOS. Cross the line and the system kills the tunnel process. To the user that reads as *"the VPN keeps dropping every few minutes under real traffic."*
Most iOS Xray clients embed `xray-core` through `gomobile`, and that is where the budget goes:
- the Go runtime reserves a large slice of resident memory before a single byte of user traffic flows;
- Go's garbage collector spikes under bursty load and pushes the extension past the ceiling;
- connection state and DNS caches grow because the Go stack was never tuned for this sandbox.
NEAXCE takes Go out of the picture. Protocols and transports are plain Swift. The userspace TCP/IP stack that bridges the TUN device into per-flow streams is plain C ([lwIP](https://savannah.nongnu.org/projects/lwip/)). The engine idles at a few MB and keeps headroom for dozens of concurrent connections inside the 50 MB budget — so the tunnel stays up and flows stop tearing.
## Features
**🧠 Memory-first by design**
Idles at a few MB, with room for dozens of flows inside the 50 MB NE budget.
|
**🔌 No Go, anywhere**
Swift for protocols and transports, C (lwIP) for the stack. No `gomobile`, no Go runtime.
|
**🕳️ No DNS leaks**
DNS-over-TCP rides the active encrypted transport, on every transport including Reality.
|
**🔀 Real Xray transports**
VLESS over gRPC and XHTTP (HTTP/2 + TLS). Shadowsocks and Reality are landing.
|
**🧱 Userspace TCP/IP**
Vendored lwIP with a NAT-rewrite trick terminates TUN TCP flows in userspace.
|
**🍎 Drop-in provider**
Subclass one base class; three small files wire up a working tunnel.
|
## Requirements
- **Swift 5.9+** to build the library. Running the test suite needs **Swift 6 / Xcode 16** (the tests use [swift-testing](https://github.com/swiftlang/swift-testing)).
- **Apple platforms:** iOS 15+, macOS 12+, tvOS 15+.
- **Entitlement:** the host app needs `com.apple.developer.networking.networkextension` with the value `packet-tunnel-provider`. Apple grants it on request; it is not on by default.
## Install
Add the package to your **Packet Tunnel Extension** target with Swift Package Manager:
```swift
// Package.swift
.package(url: "https://github.com/pinusmassoniana/NEAXCE.git", branch: "main")
```
```swift
.target(
name: "MyPacketTunnel",
dependencies: [
.product(name: "NEAXCE", package: "NEAXCE")
]
)
```
## Integrate in three files
The [`Examples/BasicIntegration`](Examples/BasicIntegration) folder has copy-paste reference code for all three.
### 1. Packet Tunnel extension entry point
Subclass `NEAXCETunnelProvider` and hand it your App Group. This is the only code the extension needs:
```swift
import NEAXCE
final class PacketTunnelProvider: NEAXCETunnelProvider {
override var configuration: NEAXCEConfiguration {
NEAXCEConfiguration(
appGroupIdentifier: "group.com.yourcompany.YourVPNApp",
loggerSubsystem: "com.yourcompany.vpn"
)
}
}
```
Set `NSExtensionPrincipalClass` in the extension's `Info.plist` to `$(PRODUCT_MODULE_NAME).PacketTunnelProvider`.
### 2. App-side manager
[`TunnelManager.swift`](Examples/BasicIntegration/TunnelManager.swift) is a `NETunnelProviderManager` wrapper that creates or loads the VPN profile, encodes a `VPNConfig` into `providerConfiguration`, and starts, stops, and observes status.
### 3. Feed a config
`VPNConfig` is the wire format. Build it by hand, or parse a subscription URI with the bundled [`URIParser.swift`](Examples/BasicIntegration/URIParser.swift) (handles `vless://` and `ss://`).
```swift
let config = VPNConfig(
serverHost: "vpn.example.com",
serverPort: 443,
serviceName: "vless-grpc",
uuid: "4c4c6842-0000-0000-0000-000000000000",
transportType: .grpc,
path: nil
)
try await tunnelManager.connect(config: config)
```
## Transport status
| Transport | Status | Notes |
| ------------------- | ----------- | --------------------------------------- |
| VLESS + gRPC + TLS | ✅ working | Primary exercise path |
| VLESS + XHTTP + TLS | ✅ working | HTTP/2 POST+GET split |
| Shadowsocks (AEAD) | 🚧 partial | chacha20-ietf-poly1305, aes-256-gcm |
| Reality (XTLS) | 🚧 partial | Handshake + record layer; no XTLS flow |
> [!TIP]
> On `.reality` and `.shadowsocks`, DNS is tunnelled through the encrypted transport by default. Plaintext DNS forwarding is opt-in only, behind `allowInsecureDNS` — so DNS fails closed rather than leaking if no encrypted path exists.