May 5, 2014
What Designing Native Mobile Apps Taught Me
Designing a native mobile app is not the same as shrinking a website until it fits inside a phone. It requires thinking about hardware, unreliable connections, platform conventions, performance, measurement, localization, and the many creative ways real users can break software.
A couple of years ago, I read an article claiming that building mobile applications was harder than building web applications. I laughed. Not loudly, but with the quiet confidence of someone who had spent years fixing websites for Internet Explorer. What could be so difficult about a controlled platform? You had a known operating system, a defined set of components, proper documentation, and no mysterious browser from a corporate basement deciding that margins were optional. It sounded almost relaxing. Then I helped design two native applications.
As it turns out, I had been looking at the polite, visible tip of a much larger iceberg. Native mobile development gives you a more controlled environment than the web, but it also gives you access to hardware, platform behavior, background execution, permissions, network transitions, local storage, synchronization, application stores, and devices that users operate while walking into traffic. The browser suddenly seemed quite civilized.
Building a good mobile app is not simply a matter of learning another language or replacing HTML and CSS with native components. It requires understanding the device, the operating system, and the strange conditions in which people use it. A desktop user is probably sitting down, looking at a large screen, and pretending not to read Slack. A mobile user might be on a train, holding the phone with one hand, carrying groceries with the other, losing connectivity, receiving three notifications, and trying to complete the task before the traffic light changes. The context is different. The product has to be different too.
I learned most of this working on Notegraphy, which won a worldwide featured opportunity from Apple. Notegraphy, in a few words, was like the “Instagram for notes.” We gained 1 million downloads in the first week and reached a peak of 300K DAU in the first month. Every day felt like an emergency room. We worked straight 12-14 hours a day fixing things. After one month of incredible hard work, I learned that most of the difficult work falls into a few areas: using the device intelligently, surviving without a network, respecting the platform, making the app feel fast, measuring what matters, writing less, localizing properly, polishing with restraint, and testing everything that seemed too ridiculous to test. Especially the ridiculous things. Users are remarkably committed to discovering them.
The first major difference between designing for the web and designing a native mobile app is that the phone is not merely a screen. It is a collection of sensors, radios, cameras, microphones, storage, location systems, and other hardware carried by a person throughout the day. That creates opportunities to remove work from the user. If the phone can determine a location, asking someone to type it manually may be unnecessary. If the device already knows the user’s language and regional settings, the application should not pretend this information is a fascinating mystery. If a photo can be taken directly, asking the user to leave the application, open the camera, take the picture, find it in the library, and upload it later is not a workflow. It is an obstacle course.
The hardware should help the person complete the task. It should not exist as a catalog of tricks for the product team. Access to a gyroscope does not mean the application needs to rotate dramatically whenever someone moves the phone. Access to location does not mean we should request it during onboarding, before the user has even discovered what the application does. Permissions are not collectibles. Every time the application asks for access to something, it creates a small negotiation with the user. The request should appear when the reason is clear and the benefit is immediate.
“We need your location because you just asked us to find nearby results”
Makes sense.
“We need your location because our onboarding checklist looked empty”
Does not make any sense.
A well-designed native app uses the device to reduce friction without making the person feel monitored, interrupted, or recruited into an experiment involving every available sensor. The phone should work for the user. This is an obvious sentence that many products have treated as an optional interpretation.
The network will disappear too, and the product has to expect it. On the web, we tend to assume that a request begins with a connection and ends with a response, and that without a connection nothing happens at all. Native apps break that assumption. Offline usage is not an edge case; it is a natural consequence of carrying a device around instead of sitting in front of a browser, and every user expects the app to still do something when the signal drops.
On a phone, the connection can vanish halfway through the sentence. People enter elevators, tunnels, garages, airplanes, old buildings, crowded stations, and parts of the countryside that telecommunications companies prefer not to discuss in their advertising. A mobile application must treat connectivity as a changing state, not as a permanent environmental guarantee.
The question is not simply, “Does the app work offline?” The better questions are:
What can the user still read?
What can they still create?
What happens to unfinished work?
Can an action be queued?
Will the application retry automatically?
Can the person tell whether the data is fresh?
What happens if two devices modify the same information before synchronization?
These questions need answers before the connection disappears, not afterward when a developer adds a red banner saying Something went wrong. Something did go wrong. We designed a mobile product as though it lived on an Ethernet cable.
A good application preserves useful local data, stores unfinished work, and synchronizes when connectivity returns. Not every feature can function without the network, but losing a signal should not automatically turn the entire product into decorative glass. Modern offline-first architecture formalizes this idea by treating local and network data as separate sources that must be synchronized deliberately. The hard part is not showing cached information. The hard part is deciding how writes, retries, freshness, and conflicts should behave.
When Notegraphy lost connectivity, I learned how quickly a normal workflow could become a dead end. A person could be halfway through creating something and suddenly become unable to continue. That is the worst possible moment to explain the architecture. The application should preserve the work, explain the state briefly, and let the person move on. When connectivity returns, it should recover without demanding a small ceremony. Do not punish the user because the network failed. They did not install the network.
Designing the states matters as much as designing the screens. A common design mistake is to create the happy path and treat everything else as an engineering detail. The happy path is beautiful. The user opens the app. The data loads instantly. Every request succeeds. Permissions are granted. The server is healthy. Nobody rotates the device, changes language, receives a phone call, or presses the same button twelve times. It is a wonderful place. No customer has ever lived there.
A real mobile product contains many states: loading, empty, partially loaded, offline, synchronizing, failed, retrying, unauthorized, permission denied, outdated, conflicted, interrupted. These are not edge cases placed around the product. They are the product.
The normal screen may be the one shown in the design review, but a significant part of the user experience happens while the system is waiting, recovering, or explaining why it cannot do something. Designers need to work through those states with engineering. Engineers need to expose the real behavior of the system. Product managers need to accept that “the API failed” is not a user interface specification. When an action fails, tell the person what happened in language they can understand and give them a reasonable next step. When the application is waiting, show progress only when it helps. When the data may be stale, communicate that without presenting a legal deposition. When an action is retrying automatically, do not force the user to keep pressing the button like an elevator passenger convinced that enthusiasm improves machinery. The application should feel resilient, not nervous.
Respecting the platform matters just as much. Designing a mobile app also means accepting that the operating system has already taught users how many things work. Navigation, back behavior, gestures, controls, alerts, permissions, sharing, selection, and text input all come with expectations. Ignoring those expectations is expensive. A custom interaction may look original in a design file, but originality is not automatically useful. Sometimes it means that every person must learn a new way to perform an old task because someone on the team had a quiet afternoon.
Apple and Android do not behave identically. Their components, navigation models, and system behaviors have their own conventions. A product can maintain the same identity across platforms without forcing both platforms to behave like reluctant copies of each other. The application should feel like your product.
It should also feel as though it belongs on the device. Apple’s current guidance emphasizes familiar interactions, consistency, and clear feedback. Android’s quality guidance similarly expects applications to support standard navigation behavior and platform components. These recommendations exist because users bring knowledge from the rest of the operating system into every new application. That accumulated knowledge is valuable. Do not throw it away because the creative director dislikes standard buttons.
This does not mean every application should look identical. It means custom design should improve the experience rather than force users to relearn basic behavior. Breaking a convention can be correct when the existing pattern does not serve the product. Breaking conventions because “we wanted something different” is usually how a designer explains a support ticket.
That is not the only thing users have already learned to expect. Content comes before navigation too. One lesson became particularly clear while working on mobile products: people open applications to do or consume something. They do not open them to admire the information architecture. Yet many applications begin with a menu. The user launches the product and receives a list of places they may visit, like entering a restaurant and being shown a diagram of the building instead of the food.
A stronger home screen often presents useful content immediately. It shows what is new, what needs attention, or what action is most likely to matter. Navigation is necessary, but it should support consumption rather than replace it. This is especially important on a small screen. Every persistent control competes with the reason the user opened the application. The product team will naturally want everything visible.
Sales wants its feature visible. Marketing wants the campaign visible. Product wants the new section visible. Legal wants something visible in case anyone becomes happy. The user wants to complete a task. These priorities are not equal.
A mobile interface must establish hierarchy. The primary content and actions deserve immediate access. Secondary actions can remain available without standing in the middle of the screen waving their arms. Not every feature can be equally prominent. Attempting to make everything important produces an interface where nothing is. That is how applications acquire the remote control syndrome: every function has a button, every button has a meeting behind it, and the original product is buried somewhere underneath.
Once the important content is visible, the next problem is confidence. Let people explore, but give them feedback while they do it. There is no user who opens an unfamiliar application and immediately understands every possible action. People explore. They tap things. They swipe. They go back. They open a menu, decide it was a mistake, and close it. Sometimes they press an icon simply to discover whether the designer was being clever. The interface needs to support this exploration safely. The important mechanism is feedback.
When a person taps, drags, saves, deletes, selects, or refreshes something, the product should react in a way that confirms what happened. This reaction may be visual, textual, audible, or tactile. It does not need to include a parade. A small state change, movement, haptic response, or confirmation can be enough. The purpose is to make cause and effect understandable.
Feedback becomes especially important when the application updates information dynamically. Without it, content changes can happen in front of the user without being noticed. The software technically performed the action, which is comforting to the software and not especially useful to anyone else.
Apple’s design guidance recommends clear, consistent feedback and warns that disruptive alerts should be reserved for information important enough to justify the interruption. That is a useful standard. Do not display a modal alert because a background refresh completed. Do not celebrate every saved preference. Do not use vibration to announce that a list opened successfully. The user is operating an application, not defusing a bomb.
Speed is part of the interface too. Performance is not only an engineering metric. It changes how the product feels. A slow application appears less reliable, less polished, and more difficult to use. It interrupts thought. It gives the user time to reconsider why they opened it. Mobile users are already surrounded by reasons to leave: notifications, calls, messages, noise, movement, and the sudden realization that they opened the phone for something completely different. A fast app protects attention. There are two ways to improve speed.
The first is to make the software genuinely faster. Reduce unnecessary work, improve queries, cache intelligently, load the correct assets, avoid blocking the interface, and stop downloading an image large enough for a cinema screen when it will be displayed as a thumbnail.
The second is to improve perceived performance. This does not mean lying. It means structuring the experience so useful feedback appears immediately while slower work continues. Show existing local data while refreshing it. Preserve the shape of content while images load. Update the interface optimistically when the action is safe and reversible. Start fetching the next likely resource before the person requests it, when the prediction is reasonable and the cost is acceptable.
In an early version of Pinterest, I noticed a clever technique. When opening an image, the application first enlarged the smaller version already on the screen, then replaced it with the full-resolution image when it arrived. The result was not magically faster, but it felt continuous.
The user saw a transition instead of a blank space and a spinner having an existential crisis. Loading indicators have their place, but displaying one for every action can make the product feel slower than it is. A message saying Loading for half a second does not reassure the user. It advertises latency. Reserve explicit progress indicators for situations where waiting is long enough to be noticed or where the person needs to understand that work is still happening. The fastest loading screen is the one you never need to show.
Measuring what actually happens matters just as much as speed does. When we started measuring Notegraphy, I initially focused on obvious numbers: section visits, registration choices, and feature usage. Those numbers were interesting, but often insufficient. Knowing that people visited a screen did not explain what they tried to do there. Knowing that they abandoned a flow did not explain where they became confused. Knowing that a feature was rarely used did not tell us whether it was unnecessary or merely impossible to find. We needed better questions.
Which step causes people to stop?
Do they attempt to tap elements that are not interactive?
Do they return to the previous screen immediately?
Does a new feature improve completion or merely generate curiosity?
Are errors concentrated on a device, language, version, or network condition?
Measurement should help the team distinguish between what it believes and what users actually experience. This does not mean recording everything because storage is cheap and curiosity has no adult supervision. Instrumentation needs a purpose. Define the question first, then collect the minimum information required to answer it. Avoid gathering personal information you do not need. Decide how long events remain useful. Document what the team is measuring. A pile of analytics events is not insight. It is a future archaeology project.
Measurement is most valuable when it is designed alongside the feature. Before release, decide what success should look like, which failures matter, and what signals would make the team reconsider the design. Otherwise, analytics becomes something people open after a meeting to find support for the decision they already made. Numbers are very cooperative when tortured correctly.
Analytics is only half the picture. You also have to watch errors, not just engagement. Product analytics explains behavior. Error monitoring explains why the application occasionally turns into smoke. Both matter.
A mobile application runs across different devices, operating system versions, languages, storage conditions, accessibility settings, and network environments. A problem may affect only a small combination of those variables, making it invisible to the team and extremely visible to the unlucky users involved.
At Notegraphy, we once had a bug that blocked the application for people whose iPhones were configured in British English. Not English in general. British English. Apparently the application had developed strong opinions about spelling. We did not discover it immediately because our internal devices did not reproduce that exact configuration. From the team’s perspective, everything worked. From the affected user’s perspective, we had shipped a logo followed by disappointment.
This is why crash reports, structured logs, and error context matter. A report should tell you more than “the app failed.” It should help identify the version, device, operating system, current state, and action that preceded the failure. Of course, this information must be collected responsibly. Debugging does not require recording a user’s entire life story.
The goal is to reduce uncertainty enough to reproduce the problem and fix it. Without monitoring, teams often discover serious bugs through public reviews. That is a monitoring system, technically, but not the one I would recommend.
None of this matters if the application cannot explain itself, because every word is part of the interface. Text inside an application is not decoration. It is part of the interaction. Buttons, labels, empty states, validation messages, permissions, confirmations, onboarding screens, and errors all form a conversation between the product and the user. Most applications talk too much. Teams write long explanations because they do not trust the interface, then add titles that repeat the explanation, followed by a button whose label repeats both.
For example:
Delete files
By accepting this action, each of the files you selected will be permanently deleted.
Delete files
This can usually become:
Delete selected files?
Delete
The application does not need to narrate the button while the button is standing there. Use familiar words. Prefer active verbs. Put the important information first. Explain consequences when they matter. Avoid jargon unless the product is intended for people who use that jargon. Friendly language is useful. Pretending to be the user’s best friend is not. An accounting application does not need to say, “Oopsie! Your quarterly tax submission had a little adventure.” It needs to explain what failed and what the user should do next.
Apple’s writing guidance similarly favors familiar, consistent, and concise language, and recommends reconsidering the interaction when an error requires too much text to explain. Good product copy feels invisible because the person understands it immediately. Bad copy makes the user stop and admire the organization’s internal vocabulary.
Words do not just need to be right. They need to work in every language the product ships in, because localization is part of design. Our original plan for Notegraphy was to launch in English. English felt universal because everyone in the room understood it, which is one of the more reliable ways to misunderstand the world. Apple contacted us because the team was interested in featuring the application. That was excellent news. Then came the list of changes.
Among other improvements, Apple recommended that we localize the product into Spanish, French, German, Italian, and Portuguese. We also added Catalan. The exercise taught me that localization cannot be postponed until the interface is finished. Words change length. Dates change format. Numbers change format. Text may expand beyond the space originally allocated. Some languages require substantially more room than English. Others change the direction of the interface.
Publish is short. The German Veröffentlichen arrives with luggage. A design that only works with carefully selected English labels is not complete. It is a screenshot. Localization also exposes unnecessary language. When every word needs translation, review, implementation, and testing, the cost of redundant copy becomes very visible.
Our Android version of Notegraphy ended up with far fewer words than the earlier iOS version. The difference improved more than translation costs. The interface became easier to scan. Writing less forced us to understand what the user actually needed to know. Apple continues to provide localization support across its platforms and App Store metadata, including region-specific language handling.