Skip to content

Building from source

This guide is for developers building Trace locally from the Trace repository.

Requirements

  • macOS with Xcode 26.2 (Swift 6 toolchain)
  • iOS 16.0 deployment target
  • An Apple Developer account with Network Extension entitlements
  • A physical iPhone or iPad for full-tunnel testing

Clone the repository

Trace uses git submodules for quiche (QUIC/HTTP3) and hev-socks5-tunnel. Clone with submodules:

bash
git clone --recurse-submodules https://github.com/your-org/Trace.git

If you already cloned without --recurse-submodules:

bash
git submodule update --init --recursive

Build with Xcode

  1. Open the project:
open Trace.xcodeproj
  1. Update signing for all targets:
  • Trace (app)
  • TraceVPN (packet tunnel extension)
  • TraceWidget (widget extension)
  1. Set the App Group identifier:
  • Set APP_GROUP_IDENTIFIER in Build Settings (e.g., group.com.yourteam.trace)
  • Ensure entitlements for the app and all extensions reference the same App Group
  1. Update bundle identifiers if needed:
  • Main app: e.g., com.yourteam.trace
  • VPN extension: e.g., com.yourteam.trace.vpn
  • Widget extension: e.g., com.yourteam.trace.tracewidget
  1. If you change the VPN extension bundle ID, update the providerBundleIdentifier in TraceFeatures/VPN/VPNManager.swift to match.

  2. Build and run on device.

First run checklist

  • Accept the VPN configuration prompt when starting capture for the first time.
  • Confirm the VPN status indicator appears when capture is active.
  • Verify App Group access by starting a capture session and checking that requests appear.

SwiftPM-only workflow (optional)

You can open Package.swift in Xcode 26.2 to work on library modules without the .xcodeproj. Note:

  • VPN and widget extension bundles still need Xcode for signing and entitlements.
  • Set bundleIdentifier and optional teamIdentifier in the .iOSApplication declaration.
  • This workflow is useful for working on TraceCore, TraceProxy, TraceFeatures, and other modules.

Common issues

  • VPN permission prompt never appears: delete the existing VPN configuration in Settings → General → VPN & Device Management and run again.
  • App Group container unavailable: verify entitlements and that APP_GROUP_IDENTIFIER matches across all targets.
  • No traffic on simulator: packet tunnels do not run in the simulator. Use a physical device for end-to-end testing.
  • Submodule build errors: run git submodule update --init --recursive and ensure quiche.xcframework is present in build/quiche/.

Signing tips

  • All targets must use the same Team ID and App Group identifier.
  • The Network Extension entitlement must be enabled for the TraceVPN target.
  • Keychain access groups must include the app's bundle ID prefix.