The API is the contract
Two codebases means two sets of hand-written types, and only one of them gets updated.
Most mobile projects begin as a second codebase against an API that was never designed for them. Stacks builds native iOS and Android apps and desktop binaries from the same project, against the same typed API client, so a field rename breaks the build instead of the app store release.
The work that arrives whether you planned for it or not.
Two codebases means two sets of hand-written types, and only one of them gets updated.
Tokens, refresh, biometrics, and deep links do not behave like a browser session.
Certificates, tokens, and per-platform payloads outlive whoever set them up.
Signing, notarising, and store submission is where a hobby project stalls.
All of it in the same install, typed against the rest of your application.
The Craft bridge produces iOS and Android apps and desktop binaries from the project, driven by buddy commands.
The generated API client is typed from the same models the server uses, so the compiler catches contract drift.
Token auth, passkeys, and two-factor come from the same auth package as the web session.
APNs and FCM are notification channels beside mail and SMS, with one class per notification.
Queue-backed sync jobs and realtime channels keep a device current without a bespoke protocol.
Build and release steps live in the same CI workflow as the web deploy.
Every one of these ships in the same install. Follow one to see what it covers.
Buddy scaffolds, runs, and ships this the same way it does the rest of the app.
Projects of this shape usually grow into one of these.