A small mobile budget tempts CTOs to “own the stack” with a lean in-house team. I think that is usually backward: buy the boring parts, keep architectural control, and build only the product-specific layer. Building cheaply in-house often creates permanent maintenance debt, because mobile release work punishes understaffed teams more than backend work does.
Cheap in-house mobile usually costs more because the missing roles still exist
The uncomfortable truth is that a mobile app is not a two-developer side quest once it touches customer identity, payments, analytics, incident response, app-store review, and release signing. A CTO may save cash by hiring one React Native engineer and one backend engineer, but the work of release manager, QA lead, observability owner, security reviewer, accessibility checker, and store-operations specialist does not disappear; it lands on people who are already context-switching.
I would treat the colleague’s checklist, How to Plan, Build, Launch, and Scale Successful Mobile Apps, as a backlog to cut rather than a mandate to staff, because a small company should not imitate the operating model of a mature mobile organization before the app has proved retention.
My position is deliberately opinionated: a CTO with a constrained budget should buy delivery infrastructure, authentication, crash reporting, feature flags, and subscription plumbing before hiring a full in-house mobile platform team, because those components are standardized enough that vendor leverage beats internal heroics. The part worth owning is the domain model, API contract, release decision, and customer experience, because those determine whether the app creates defensible value.
I would not build a bespoke CI/CD pipeline, custom crash ingestion, homegrown remote-config service, and internal app distribution portal for a first commercial mobile release, because the maintenance burden arrives before the business learns whether the app deserves that investment. I would also not let an agency own the repository, signing keys, analytics taxonomy, or release train, because outsourced delivery without technical control makes every future negotiation more expensive.
The minimum proper setup is not extravagant. Use GitHub Actions on ubuntu-24.04 or Bitrise for CI, Fastlane 2.220 or later for store automation, Sentry or Firebase Crashlytics for crashes, OpenTelemetry 1.35 conventions for traces where the backend participates, LaunchDarkly or Firebase Remote Config for flags, RevenueCat for subscriptions if the product sells entitlements, and OWASP MASVS v2.1.0 as the security checklist. Those names matter because they let you hire from a known labor market instead of training people on a private stack.
The build-versus-buy decision should be about ownership boundaries, not developer pride
The wrong question is “Can we build this?” because most capable teams can build almost anything slowly. The better question is “Which ownership boundary would make us faster in twelve months?” because the first version of a mobile app is rarely the expensive part; the expensive part is changing it safely after customers, support, compliance, and marketing depend on it.
Here is the explicit comparison I would put in front of a CFO and CTO:
- Option A: Internal Mobile Platform Team. Staff one senior iOS engineer, one senior Android engineer, one mobile QA/release engineer, and half of a DevOps engineer. This wins when mobile is the core product surface, offline behavior is complex, security review is frequent, or the company already releases weekly. A realistic planning figure is about $55,000 per month fully loaded in many US/EU hiring markets, because salary, payroll burden, tooling, devices, management time, and recruiting overhead all count.
- Option B: Managed Delivery Stack. Use Expo EAS Build or Bitrise, Firebase Crashlytics, Sentry, RevenueCat, LaunchDarkly, GitHub Actions, and a small external delivery partner while an internal staff engineer owns architecture and review. This wins when the app is a new channel rather than the whole company, because the team buys mature release mechanics and spends its scarce internal time on product decisions. The first-year cash cost can often stay below $8,000 to $25,000 in tools before partner labor, because many mobile SaaS products price by seats, build minutes, events, or monthly active users rather than by headcount.
Option B is not “cheap and sloppy” if the CTO owns the architecture, because buying commodity services does not require surrendering code quality. Option A is not “proper” by default, because an understaffed in-house team can still skip test automation, release notes, alerting, and dependency maintenance under deadline pressure.
Use native Swift 5.10 and Kotlin 2.0 when device capability, animation performance, or platform-specific UX is a differentiator, because native teams can exploit Apple and Android APIs earlier. Use React Native 0.74 or Expo SDK 51 when the business needs one product team to learn quickly across platforms, because shared UI and release conventions reduce coordination cost. This is not the old native-versus-cross-platform debate; it is an ownership-budget debate.
There are a few costs that should be treated as facts rather than estimates. Apple publishes the App Store developer fee at $99 per year, and Google lists the Play Console registration fee at $25 one time; those numbers are small, but they signal that store operations are not where the real budget goes. Apple’s Small Business Program commission is 15% for eligible developers, a published commercial term, so subscription-margin planning should include platform fees before anyone celebrates gross revenue. A crash-free sessions target of 99.5% is a threshold to tune, not a universal law, because some beta cohorts tolerate instability that paid subscribers will not.
Proper on a small budget means automating the release path before hiring more people
A small team becomes expensive when releases require tribal knowledge, because every urgent fix becomes a meeting. The most useful early investment is a repeatable release path with signing, build numbers, tests, artifact retention, staged rollout, and rollback strategy, because it reduces the number of people needed to ship safely.
The release advice in our colleague’s note, Mobile App Development Insights for Faster Releases, is useful after ownership is settled, because faster releases are only valuable when the team can explain who approves risk and who watches production.
A thin but serious pipeline can be boring. For Android, Gradle 8.7 with Android Gradle Plugin 8.5, minSdk set deliberately, targetSdk kept current, and dependency locking enabled gives more protection than a heroic release manager. For iOS, Xcode Cloud or Fastlane with explicit provisioning profiles is safer than a laptop-only archive, because a single developer’s machine should not be the release system.
The following shell step is intentionally plain; it runs in a typical React Native Android repository with Node, Java, and Gradle available, and it shows the kind of repeatability a CTO should require before adding headcount:
set -euo pipefail npm ci npm test -- --watch=false npx react-native bundle --platform android --dev false \ --entry-file index.js \ --bundle-output android/app/src/main/assets/index.android.bundle \ --assets-dest android/app/src/main/res cd android ./gradlew :app:assembleRelease --no-daemon --stacktrace ls -lh app/build/outputs/apk/release/*.apk
This is not a complete production pipeline, because signing, Play App Signing, artifact retention, and staged rollout are omitted. It is still a useful baseline because a build that cannot run from a clean checkout is not ready for either an internal team or an external partner.
Measure DORA lead time for changes, deployment frequency, change-failure rate, and time to restore service, because those metrics expose whether the team is getting safer or just busier. Add mobile-specific measures: p95 cold start, crash-free sessions, app-not-responding rate, store-review rejection count, binary size, and percentage of sessions on the latest supported version. A p95 cold-start goal of 2.5 seconds on a midrange Android device is a value to tune, because premium-device benchmarks hide the delays that drive bad reviews.
Buying is proper only if contracts preserve future in-house control
Buying badly can be worse than building, because a vendor-owned architecture can turn every product change into a statement of work. The CTO should separate “buying services” from “outsourcing judgment.” Buy commoditized execution, but keep decisions about state management, API versioning, event taxonomy, security posture, and release gates inside the company.
A practical contract should require repository access from day one, branch protection, pull-request review by the internal technical owner, dependency manifests, build documentation, and export rights for observability data. It should name standards rather than vibes: OAuth 2.1 or OpenID Connect Core 1.0 for user authorization where appropriate, TLS 1.3 for transport, WCAG 2.2 AA for accessibility acceptance, semantic versioning for API clients, and CycloneDX SBOM output for dependency visibility. These requirements are worth writing down because “we follow best practices” has no operational meaning during an incident.
Do not accept a black-box “monthly app maintenance” package without source-level acceptance criteria, because the vendor can optimize for ticket closure while your company accumulates architectural risk. Do not let the same partner both define the scope and approve completion, because the incentive conflict becomes visible only after the budget is committed.
Buying also needs technical due diligence. Ask whether the partner pins CocoaPods and Gradle dependencies, whether Renovate or Dependabot opens upgrade pull requests, whether Sentry releases are tied to Git SHAs, whether Firebase Crashlytics has symbol upload enabled, whether feature flags have owners and expiry dates, and whether TestFlight and Play Console staged rollouts are documented. Those details matter because they are the difference between a supplier delivering screens and a supplier delivering an operable product.
The best small-budget model I have seen is a hybrid: one internal staff-level engineer owns architecture and code review, a product manager owns release priority, and an external team handles implementation under a written definition of done. This model works because the company buys capacity without renting its technical memory. It fails when the internal owner has no time, because unattended vendors will make local optimizations that look reasonable in isolation.
You should build in-house only after the app has earned the fixed cost
In-house hiring is the right move when mobile becomes a strategic system rather than a distribution channel, because permanent teams are better at compounding product knowledge. The trigger should be evidence, not anxiety. Evidence can include a sustained release cadence, a roadmap full of platform-specific work, customer support volume that requires deep debugging, or revenue exposure that makes vendor scheduling risk unacceptable.
A reasonable transition plan is to keep the bought stack while hiring the first mobile lead, because replacing tooling and people at the same time multiplies risk. Hire for ownership of architecture, observability, and release discipline before hiring for raw feature velocity, because the app will already have enough feature code by the time the company brings work inside.
The CTO should also budget for unglamorous inventory: at least one low-end Android device, one current iPhone, one previous-generation iPhone, and a tablet only if the app genuinely supports tablet layouts. A device-lab target of 6 to 10 physical devices is a tuning range for early teams, because emulator-only testing misses battery, radio, biometric, camera, and memory-pressure failures. BrowserStack App Live or Firebase Test Lab can supplement that lab, but they should not replace it entirely because some failures are easiest to reproduce with a real cable, a real network, and a tired engineer.
The handoff from bought capacity to in-house capacity should be planned like a migration. Require architecture decision records, onboarding scripts, release calendars, threat-model notes, and incident runbooks before reducing vendor involvement. Keep the vendor for overflow or specialized platform work for one or two release cycles, because immediate cutover creates a single point of failure around the new hires.
Start with a one-page ownership map before approving either a hiring plan or a vendor contract. Mark each capability as “own,” “buy,” or “rent,” and put a named person beside release approval, signing keys, analytics events, incident response, and dependency upgrades. If nobody can own those five lines internally, buying more tooling or hiring more developers will not fix the budget problem.


