Skip to main content

Project structure

After you run swiftpatch init, your project grows a handful of new files and modifications. None of them contain secrets that can't be committed — except for one.

New files

your-app/
├── .swiftpatch/ # gitignored
│ └── keys/
│ ├── private.pem # Ed25519 signing key — NEVER commit
│ └── public.pem # Ed25519 verification key — upload to dashboard
├── .swiftpatchrc # commit-safe project config

Modified files

your-app/
├── .gitignore # adds .swiftpatch/, swiftpatch-artifacts/, swiftpatch-private.pem
├── ios/
│ └── YourApp/
│ ├── AppDelegate.mm # swiftpatch-begin/end block in bundleURL
│ └── Info.plist # SwiftPatchDeploymentKey, BGTaskScheduler, UIBackgroundModes
└── android/
└── app/
└── src/main/
├── java/.../MainApplication.kt # swiftpatch-begin/end block in getJSBundleFile
└── res/values/strings.xml # swiftpatch_deployment_key

.swiftpatchrc

The project's primary config. Commit this. It does not contain secrets.

{
"appId": "app_abc123",
"app": "my-app",
"platform": "ios",
"signingKey": "./.swiftpatch/keys/private.pem"
}

See Configuration for the full field reference.

Signing keys

The Ed25519 private key signs every release. The public key verifies releases on-device.

  • Private key — never commit. .gitignore protects you by default.
  • Public key — safe to share. It's embedded in the app binary (Info.plist / strings.xml) and uploaded to the dashboard.

For CI, store the private key as an encrypted secret (e.g., GitHub secrets.SWIFTPATCH_PRIVATE_KEY) and write it to a file at pipeline time. See CI/CD.

The marker blocks

Every native file Swiftpatch patches is wrapped in // swiftpatch-begin / // swiftpatch-end markers:

AppDelegate.swift
override func bundleURL() -> URL? {
// swiftpatch-begin (auto-generated, do not edit between markers)
if let url = SwiftPatchModule.getBundleURL() {
return url
}
// swiftpatch-end

// Your existing code continues unchanged below
#if DEBUG
...
#endif
}

Editing between the markers manually is safe but will be overwritten on the next swiftpatch init. To remove Swiftpatch cleanly, run swiftpatch unlink — it strips every marked block.

Next steps