Build a website first, then add mobile apps later. Launch an iOS-only app, then expand to Android and/or the web. These are strategies as old as time in software development. They even predate the world of iOS and Android—desktop applications, too, often start with support for one operating system before expanding to multiple.
If you find yourself at this juncture in your business’s growth, preparing to expand from one platform to many, congrats! I’ve had a front-row seat to this process several times. I saw LinkedIn go from web plus hybrid to web plus native mobile apps. As a former consultant, I worked with clients as they moved from iOS to iOS plus Android, or from desktop to iOS. At Gusto, where I currently lead a mobile engineering team, we expanded from web apps to web plus mobile apps not all that long ago.
Here, I’ll walk you through some of the phases you’ll experience on the exciting—but also nerve-wracking—journey from web to mobile, or from one mobile platform to the next: picking your tech stack, expanding your infrastructure, and evolving your feature development process.
Selecting your stack
What tech stack will you use to build your new app (or apps)? This stage-setting question will determine a lot of what’s to come on the road to supporting multiple platforms. It will also influence another early question: Who are you going to hire to help get you there?
The debate over native versus non-native development is a contentious one, and trying to determine which is “better” can consume valuable time and energy. Companies often seek to adopt non-native solutions to save on time, cost, and overhead. In theory, non-native frameworks enable you to hire one set of engineers, with one set of skills, to build just one app. In practice, though, it’s often impossible to avoid writing at least some native code, and this can wind up being just as expensive as native development, if not more so.
I saw this play out with a client: They were using a non-native framework to build common functionality for both iOS and Android, while the rest of the app was built natively. When they ran into issues, they needed to hire people who understood how those two frameworks intermingled—which is usually an expensive solution.
Technology choices are rarely forever choices.
With that in mind, it’s no surprise that deciding between native and non-native can feel overwhelming. Here’s a quick suggestion: If you’re making something highly complex, like a game engine or an editor, and you have a small team, it can make sense to implement that complex logic just once in a non-native framework. That’s especially true if the framework is optimized for your use case, like using Unity for an AR app. (One caveat: Apps built using non-native frameworks are generally slower or glitchier, and tend to have other tells like awkward navigation and not supporting OS gestures.) For most other apps—especially if you plan to access OS-level features like the camera, OS widgets, or Apple or Google Pay—you’re likely better off building native apps.
Regardless of the stack you choose, you’ll need people with some platform-specific expertise, so start by hiring at least one engineer with experience in the platform(s) you’re considering before drawing your line in the sand. And if you’re concerned about being locked into a stack, remember that technology choices are rarely forever choices. As we’ve seen at company after company (take Airbnb and Dropbox, for instance), this decision doesn’t have to be permanent.
Building the foundations
You’ve hired some engineers and decided on the broad strokes of your development strategy. Now for the fun part: analyzing your infrastructure and considering what will scale to support your new apps, what you’ll need to build in the future, and what you’ll need to add right away.
Your ultimate goal should be to build a solid and scalable foundation for your mobile apps while avoiding scope creep.
The answers to these questions will largely depend on the leap you’re making. Going from iOS to Android (or vice versa) means you probably already have a lot of the tooling you need for mobile development, and your main concern will be whether any past infrastructure decisions don’t scale to your new platform. For example, if you already have an Android app, you’ve probably set up CI/CD pipelines that support mobile development, but there will still be some additional lift to support iOS. On the other hand, if any of your infrastructure was built using single-platform technology, such as CloudKit, you’ll have a much larger task ahead of you.
Going from web to mobile apps is a different ball game entirely. Your current CI/CD pipeline may not work for mobile apps, or you may not have a push notification system built yet. Infrastructure like this will be net new. To get started, take stock of everything you’ll need for production-ready mobile apps, from authentication to beta testing to continuous deployment, then ruthlessly prioritize what you’ll need before and during development. (The must-haves will include mobile-friendly CI/CD, token-based authentication, and a staging environment accessible from a mobile app.)
Your priorities will vary depending on your existing tech stack and the size of your engineering team, but the ultimate goal should be to build a solid and scalable foundation for your mobile apps while avoiding scope creep.
Making development API-centric
When you’re on just one platform, you can play a little fast and loose with things like versioning, where the business logic lives, and assumptions about the data types returned by the API. When you’re building across multiple platforms, you need to be much more intentional about your API and data modeling strategy.
In the past, I’ve built iOS-only apps where much of the business logic lived in the app itself, and expanding to another platform would have required a significant refactor. If you’re moving from web to mobile, you might experience something similar: Along comes platform number two, and you suddenly start to notice all the places where the backend isn’t doing the work it should be. Plus, with mobile apps you want to be extra mindful of the size of the payload, and reusing your existing web APIs on mobile could cause your apps to over-fetch data they don’t need.
I’ve seen two helpful approaches to designing APIs for multiple clients in the wild. The first used REST, but also involved a lot of custom libraries and tooling to auto-generate strongly typed data models from the API. Versioning was still a bit of a pain, and this approach would be hard to swing if you don’t already have an established mobile app and mobile infrastructure team.
We took a different approach at Gusto, adopting GraphQL for our mobile apps. GraphQL offers strongly typed data, client control over the data requested, and a well-defined schema, all of which is especially helpful when you’re supporting more than one platform. However, there’s a migration cost if you’re moving from REST to GraphQL, and engineers will have to learn how to build and manage a well-designed schema.
Whatever tactic you choose, think carefully about your strategy for versioning and backward compatibility. If you’re moving from iOS to Android, you’ll likely have thought this through already, but if you’re moving from web to mobile, it’s a brand-new muscle you’ll need to build. Once an app version is out in the world, it can be out there for a really long time; at any given moment, your API might be accessed from many different app versions.
Building a feature for a new platform can sometimes feel like building from scratch. For one thing, different platforms have different capabilities and quirks, so a feature designed for iOS may not immediately translate to Android. For another, it will take your team time to determine how to port the feature to that new platform and figure out all of its user stories. Plus, you may not have the exact same team working on the feature the second time around, so new engineers might need time to get up to speed.
All this means you’ll have to ask yourself what feature set you truly need to bring over to the new platform in order to launch. At Gusto, we call this building the “minimum lovable product” (MLP) for the user.
Once you’ve launched your MLP, you’ll have to get into the swing of developing features across multiple platforms. This can be one of the hardest steps for a team used to building for just one. If you want a new feature to live across platforms, try to build it concurrently; if you stagger your build cycles, you’ll relive building the feature over and over again, and if you made a platform-centered decision the first time around, you might pay the price when building for the second or third platform.
An exception to this concurrent, cross-platform approach is running experiments, because it can sometimes make sense to choose just one platform to learn on. If you want to test an approach to increase sign-ups, for example, you can validate it on one platform before deciding whether to bring it to the others. Just keep in mind that user behavior may differ across platforms—users might be willing to go through a longer sign-up flow on web than on mobile, for instance—so your learnings may not be universally applicable.
Once you’ve decided to go multi-platform, questions about what your team should do and change first will loom large. Luckily, there’s a straightforward path to follow as you weigh these considerations. Start with the tech stack, scrutinize your infrastructure, emphasize API-centered development, and get comfortable building features across more than one platform. Moving from one platform to multiple is a major investment, but the reward is a growing ecosystem for your products that users old and new will appreciate.