What it was like designing a quick-commerce app for a 30-store supermarket chain.
Company
Voltvave Innovations Pvt Ltd, Bangalore
Project
Product Designer
ROLE
Product Designer
Duration
2.5 years (6 months to launch, 2 years refining)
Scope
4 surfaces: User, Driver, Store, Admin
Team
1 Designer · 3 Developers · 1 Product Manage
STATUS
Live on iOS & Android
Overview
TingTing was a quick-commerce app built for Royal-Mart, a supermarket chain with thirty stores across Bangalore.
Designed and shipped a quick-commerce ecosystem for Royal-Mart covering customer ordering, store operations, and admin management.
Built the first version in 6 months, then spent the next 2 years refining operations, scaling systems, and solving real-world delivery problems.
The ecosystem consisted of:
Customer-facing mobile apps (IOS & Android & Web)
Store fulfillment panel (Desktop & Web App)
A desktop operations/admin platform
All built on a shared Flutter architecture.
12K+
Downloads on iOS & Android


4.5/5 Stars
"Fast delivery, great deals and fast response from customer service!"
20k+
Orders has been delivered
The setup
On paper, the flow looked simple:
Customer places an order → store confirms it → picker packs it → rider delivers it.
In reality, the system started breaking almost immediately.
Inventory mismatches were constant. Products shown in the app were often unavailable in-store. Staff struggled to locate items during packing, forcing the system to handle substitutions, cancellations, and missing products dynamically across all interfaces.
Delivery timing became another problem. As order volume increased, stores slowed down, riders waited, and fulfilment queues stacked up. Customers only saw “late delivery,” but internally the issue was operational coordination.
Small inconsistencies quickly felt like product failures. Quick-commerce breaks when systems stop syncing.
Most of the work wasn’t adding features. It was reducing operational gaps so the system could survive real usage.
Building it small
We were a small team. Three developers, one product manager, and me.
One frontend developer and two backend developers. No QA team. Whatever I designed, that same team had to build, test, and ship. That shaped a few decisions early on.
Flutter was one of them. We needed three apps for customers on iOS and Android, store flows, and a desktop admin app. With one frontend developer, building three native apps was off the table. Flutter lets us write one codebase that runs across all of them. Cheaper to build, faster to ship, easier to maintain. That decision was made before I started designing anything.
The other one was Material Design. Flutter renders Material components fastest, and our frontend developer was already fluent in it. So instead of designing freely and then negotiating what could be built, I designed on top of Material from day one. The material's structure became the constraint. TingTing's brand sat on top of it.
Both decisions came from the same place, a small team, short runway. The design system had to do the work that a bigger team would have done with more people.
The design system
Once Flutter and Material were locked, the next challenge was creating a design system that could scale across all three surfaces. It had to cover three apps, customer, store, and admin, and it had to stay in sync with code, because no one had time to translate between Figma and Flutter on every change.
The goal wasn’t aesthetics. It was consistency and speed.
So I went deep on Material first. How its tokens and components are structured and behave, how its theming works. Once I understood that, I built TingTing's system inside the same architecture. Material handled the foundation, TingTing's brand sat on the surface.
Tokens came first. Colours, Type, Spacing, Radius, Shadows, all defined inside Material's structure, all checked against WCAG contrast before anything reached the codebase.
Components came next. Material covers the basics, buttons, inputs, sheets, dialogs, but a quick-commerce app needs more than that. Product cards with quantity steppers. Cart rows. Order timelines. Store cards. Address pickers. I built each new component inside the same token system Material used, so everything stayed consistent even when the component itself was custom.
Tokens fed into components, components into screens. Change one thing in the system, and it carries through everywhere.
The point of all this wasn't elegance. It was sync. When a token changed, every screen across all three apps changed with it. Components are shipped the same way everywhere. It wasn't perfect, but it held things together when everything else started getting messy.
Because the engineering team was extremely small, there was no room for heavy handoff processes or constant translation between Figma and development. If the design system drifted away from implementation, the product would slow down immediately.
So the system was designed less like a brand guideline and more like shared infrastructure between design and engineering.














How We Scaled
We didn’t launch to 30 stores immediately.
We launched:
0 Store -> 1 -> 2 ->… -> 30.
The app went live for users within 5km of a single Royal-Mart. That was the whole audience for the first stretch. The plan was simple. Get one store running cleanly before adding a second.
That first store taught us things we couldn't have predicted on paper. Edge cases in the order flow, friction in the cart that didn't show up in testing, patterns in what people actually bought versus what we'd assumed. Most of those came up in the first few weeks.
Once that store was running well, we added a second. Then a third. Each new store inherited everything we'd already fixed, and added its own learnings on top, usually around inventory edge cases or things specific to how that particular store ran day to day
bundles are always arranged in multiples of three or four. So if an operator added one too many items, the layout still rendered cleanly. They didn’t need to know why; the rule just held
Most of what's on the live app now isn't what we shipped at launch. It's what survived two years of real users across thirty stores. The first six months were about getting something live. The two years after that were about making it actually work.
Most of the current product evolved from real-world operational learning, not assumptions.
A few smaller decisions worth mentioning (Operational Decisions & Product Tradeoffs)
Most of the difficult architectural decisions in TingTing came from one recurring constraint: every workflow had to remain synchronized across three interconnected systems - the customer app, the store fulfilment interface, and the admin operations platform.
Even smaller UX decisions were treated as systems decisions, because introducing friction or inconsistency in one surface immediately affected the others.
A few that mattered.
Phone-first onboarding. Register with OTP, no email, no password. The phone number became the delivery contact, the notification hub, and the same identifier that the store and admin used to track the order. One ID across all three apps.
Guest mode. Browse without signing up. Cart saved locally. Log in later on the same device, and it carried over. A few days of state-management work, in exchange for an unblocked first session.
₹100 reward at sign-up. Share name and gender during onboarding, get a coupon. The data helped us serve users better, and the coupon paid for it.
Location. Default to the current GPS, let users pick from the map, and save multiple addresses. The 5km radius around each store was the same one the admin saw on the desktop and the same one the store flows used to confirm assignment. One geofence, three apps.
Checkout. Front-loaded the delivery promise, "Deliver in 18 min," so the urgency felt earned, not pushed. Free-delivery threshold nudges. Strikethrough pricing. Preset tip amounts. One active coupon at a time, which prevented stacking abuse without needing a separate discount engine on top.
Glimpses of the App
What I'd do differently
Two things, looking back.
The first one is on how I built the design system. I started it after the first version was already in office testing, which sounds late but actually felt right at the time, the screens existed, so I had something to systematize. What I'd change is what came next. Once the system was in place, I tried to retrofit too much of the early work to match it. Some of those early screens were fine the way they were. They didn't need to be redone for consistency's sake. If I were doing it again, I'd be more careful about which old work the new system actually needed to touch, and which it didn't
The other one is on how we measured. The article we published said fulfilment time dropped from 40 to 15 minutes, and the number is real. But most of that gain didn't come from the app. It came from the human chain that was already in place, including calls, WhatsApp, and store-level coordination. The cleaner business metric would have been SLA breach rate per store, directly tied to the admin's job of stepping in before things went sideways. The numbers we shared weren't wrong, but the story behind them was more shared than I gave credit for at the time.
Read the operations writeup → From 40 to 15 Minutes (Medium)

Stay in touch
I write occasionally about design systems, product decisions, and how I work. Less polished, more honest than what's on this page.
© 2026. Made by
@Rahim1845






















