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.
.gitignoreprotects 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:
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
- Quickstart — the three-command flow.
- SDK installation — detailed patch breakdown.
- Configuration — every option.