← Work
Case No. 03ConsumerSocialLive

Habit apps trust the checkbox. Habicy asks for the photo.

Habit apps trust the checkbox. Habicy asks for a photo and posts it to a feed your friends actually watch - peer pressure, doing what streaks alone cannot.

iOSAndroid
iOS + Android since 2024 - design, app, and backend, one teamlive
live in both stores - design, app, and backend, one team2024
reminder messages written so the nudge never repeats34
color palettes, one per habit, from our own design system12
ProductHabicy
Engagementconcept to both stores
Tech stackFlutter · Firebase · GetStream · RevenueCat
PlatformsiOS · Android
the product

The product.

Habicy habit screen for Gym at 118: a year heatmap of completions above a June calendar where every done day is that day's photo
Habicy new-habit screen: a Create custom art banner above habit ideas - water, gym, mindfulness, diet - each with its own 3D sticker

gym 118, a year in photos · new habit, the sticker shelf - made to be looked at

the system

Most of Habicy is not the app.

appFlutter
  • HabicyiOS + Android - feed, dual-camera capture, profiles, paywall
  • teal_uiour own design system - 12 habit palettes, squircle kit
capturecamera
  • Dual-camera flowback shot, then front, one post
  • Image pipelinecompress, resize, thumbnail - on device
socialGetStream
  • Activity feedtimeline, likes, comments, mentions, pokes
  • Notificationsten push types over FCM, built in-house
backendTypeScript
  • Cloud Functionstoken exchange, pushes, the daily reminder cron
  • Firebase + RevenueCatauth, Firestore, Storage, the premium tier

The architecture underneath - utopia_arch and utopia_hooks - is the same we publish under BSD-2. Nothing here was rebuilt for Habicy alone.

the hard parts

Three things that made the premise real.

01

The premise was an engineering problem

the problem

Proof only means something if it is hard to fake. A single photo can be shot minutes late, borrowed from a camera roll, or aimed at anything. The product needed a capture flow where the moment itself is the evidence - both cameras, one shot, no gap to cheat in.

what we did
A custom camera screen, not the system picker: the back camera fires first, the front camera follows on a countdown, and both frames land in one post. Before upload, the user stamps the shot with a draggable habit sticker and a streak count, then the pipeline compresses, resizes, and thumbnails everything on device. The commit history is honest about the cost - the feature earned its own branch and a dependency upgrade, and a live Flutter camera plugin bug on Android needed a pinned workaround to keep working at all.
Habicy milestone screen: the app's glossy purple alien mascot over a big 116-day streak count and a Congrats! button
Habicy post: a friend's Daily book check-in photo at streak 72, with a like blooming as a big heart over it

116 days, unfaked · one post, watched

02

A feed is a backend

the problem

The social layer is the retention engine, and the part a mobile team usually underestimates: a timeline, likes, comments, mentions, a follow graph, blocking, and a push notification behind every one of them. None of that is a screen. All of it is infrastructure.

what we did
GetStream carries the feed and the chat layer; Cloud Functions carry everything around it - token exchange, a push for every like, comment, mention, and poke, and cleanup that deletes a user's GetStream identity the moment they delete their Habicy account, so nothing is orphaned in a third-party system. The three habit types the app supports - streaks, elapsed-time counters, and multi-step routines - all write into the same feed and the same proof flow, so the social layer never has to know which kind of habit it's looking at.
Habicy edit-habit screen: Habit, Routine and Anti-Habit types, weekday schedule chips, a three-shade palette and the 3D sticker picker

habit · routine · anti-habit - all write into the same feed

03

Retention with personality

the problem

A daily reminder is easy to build and easy to tune out. Fire the same push every day at the same hour and users learn to swipe it away without reading it - the notification becomes wallpaper, not a nudge.

what we did
A scheduled job runs once a day, checks every habit against its own weekday schedule, and batches everyone's due habits into a single push - one notification per user, never one per habit. What makes it land is the copy: a 34-message bank written so the reminder never repeats, running from a plain nudge to a full roast by the end of the list - "Do the ${habitName} or I'm telling everyone you prefer pineapple on pizza." is one of them. A habit app has to be a little annoying to work. Habicy decided it should also be funny about it.
Habicy welcome screen: a bold illustrated portrait over "Welcome to Habicy - Social media that makes your community better", with Sign up and Sign in buttons

sign up or sign in · social media that makes your community better

the design

The design system.

Habicy design specimen: Tan Nimbus display type over a dark canvas with the habit motive palette
Our own design system, teal_ui, built for the app - a dark-only canvas, twelve per-habit color motives, and Tan Nimbus display type over a Poppins body. Consumer-grade polish, from the same team that wrote the code.
still shipping

Live in both stores since 2024, still built on the architecture we open-sourced.

Habicy runs in production on iOS and Android: Firebase and GetStream underneath, RevenueCat on the premium tier. Every screen follows the same pattern - a hook for state, a widget for view - on utopia_arch and utopia_hooks, the same packages we publish under BSD-2. The Architecture page on this site describes the pattern. This app is the pattern, shipped to real phones, with a mascot who checks in on your streak.
talk to us

Building something with this much surface?

The engineers who run this platform answer the contact form.