What it is
reState is a property browsing app built with Expo and React Native — browse listings, filter them, open a property and look through its detail and images. I built it to find out how much of what I know about building for the web actually transfers to a phone, and where the assumptions quietly stop holding.
By the numbers
- 2
- Platforms, one codebase
What does not transfer from the web
There is no hover, so every affordance that leaned on it has to be redesigned as something visible at rest. There is no cursor, so touch targets have to be sized for a thumb rather than a pointer, and the reachable part of a large phone screen is the bottom half, not the top.
The bigger shift is list performance. A web page can render a few hundred rows and get away with it. On a mid-range Android, a list that renders everything eagerly drops frames while scrolling, and dropped frames on a scroll are the single most obvious way an app feels cheap.
What I built
Listings render through a virtualised list so only what is on screen is mounted, with image loading deferred and sizes fixed so rows do not resize as photos arrive. Search and filtering narrow the same underlying collection rather than re-fetching, which keeps interaction immediate.
Styling is NativeWind, which gives React Native the same utility-class model I use on the web. That was a deliberate choice to keep one styling vocabulary across both targets instead of context-switching between Tailwind and StyleSheet objects.
Why it is in this portfolio
Most web developers are web-only. Having shipped a real React Native application means I can take a feature that spans web and mobile without treating the mobile half as somebody else's problem.
It also made me better on the web. Building against a slow device with a small screen and no hover is a useful corrective to developing on a fast laptop, and several of the performance habits in the other projects here started on this one.
Decisions
Four calls I would make the same way again
01
Expo rather than bare React Native
Expo removes the native build toolchain from the critical path, which for a solo project is the difference between shipping features and maintaining Xcode and Gradle configurations.
02
NativeWind to keep one styling model
Using the same utility vocabulary on both targets means moving between web and mobile does not mean relearning how to express a layout. Consistency across contexts is worth more than any single platform's idiomatic API.
03
Virtualise the list from day one
Retrofitting virtualisation means rewriting how rows measure themselves. Starting with it costs nothing and avoids the rewrite entirely.
04
Design for thumbs
Primary actions sit in the lower half of the screen, where a hand holding a phone can actually reach them. It is a small decision that changes how usable the app is one-handed.
Stack
Application
- React Native
- Expo
- TypeScript
Interface
- NativeWind
- Virtualised lists
- Expo Router
Next case study
DocQuery