Skip to content
All work
In progress

2026

CannyCart

A shared shopping-list app for web and mobile, built on one Amplify Gen 2 backend.

Problem

Household shopping lists live in group chats and get lost. The hard part isn't the list — it's keeping web and mobile genuinely in sync without maintaining two backends.

My role

Sole engineer and designer: schema, backend, both clients, design system.

Outcome

An npm-workspaces monorepo where a Next.js web app and an Expo mobile app share a single Amplify Gen 2 backend, a single auth model and a single set of design tokens.

CannyCart is a monorepo with three moving parts: an Amplify Gen 2 backend (Cognito, AppSync, DynamoDB), a Next.js web app, and an Expo mobile app. All three share one schema and one design token file, which is the whole point — a change to the data model lands in both clients at once.

The interesting constraints were mobile-side. DynamoDB has no GROUP BY, so ranking a user's most-added items had to become a client-side aggregation. Reusable list templates turned out to need one boolean on an existing model rather than a new table. Offline behaviour meant mutations had to survive an app kill and replay on reconnect.


Stack

Next.js
Expo
TypeScript
AWS Amplify Gen 2
AppSync
DynamoDB
Cognito
MUI
NativeWind