Inspiration
Most photo apps treat memories as a feed you scroll past and forget. We wanted something that felt alive, a living visual object that grows when you add to it, and naturally changes over time. The therapeutic concept of letting go of a memory without losing it shaped the core loop: leaves fall on their own, you rake them, the fertilizer feeds new growth. That cycle mirrors how we actually process experiences, and it gave us a mechanic no other wellness or photo app has.
What it does
Leaflet is a real-time social memory garden built as a web app. You sign in with Google and get a personal tree. Posting a memory means sharing a picture that becomes a photo leaf on one of your tree's branches. Over time, the app runs a gravity tick: any leaf on the tree has a chance of falling to the ground. Fallen leaves can be raked by clicking or dragging them to the bottom of the screen, converting them to fertilizer. Once you've accumulated 5g of fertilizer, the Nurture button activates and levels up your tree, unlocking deeper branch geometry. You can visit any other user's tree through the Connections panel and watch their canopy in real time.
How we built it
The frontend is React with TypeScript, bundled with Vite. The tree itself is rendered entirely on a Konva canvas via react-konva, a recursive branch generation algorithm computes geometry from a configurable depth tied to tree level, with a wind animation updating on every animation frame. Leaf state lives in Firestore under each user's /users/{uid}/leaves subcollection, and all clients subscribe via onSnapshot listeners for live sync. Auth is Google OAuth through Firebase Auth. When you plant a memory, we immediately write to Firestore so the leaf appears, then fire a non-blocking call to Gemini (gemini-3-flash-preview) to classify the image into NATURE, PEOPLE, FOOD, PLACES, or OBJECTS; the result remaps the leaf's branchIndex, placing it in a semantically grouped region of the canopy. The gravity loop runs on a set interval on the tree owner's client only, keeping mutation authority with the host. Confetti fires on every Nurture via canvas-confetti.
Challenges we ran into
Our first hurdle was that authentication was tricky. When we dug deeper, we found that the Firebase backend handled everything for us, which worked against us. We wanted to be able to control where the data was being stored and not require online verification, but we were locked into the Firebase ecosystem. We ended up disabling the authentication and created a temporary mock user and permissions, so we have something to bring to the table for our demo.
Accomplishments that we're proud of
We shipped a working real-time multiplayer experience where you can visit another user's tree and watch it change live. The core gameplay loop, incorporating the post, fall, rake, nurture and fertilize functions, is demonstrated as implementations on the home screen. People who try it have the immediate satisfaction of seeing all of their uploaded memories as one collective representation that promotes reflection.
What we learned
Firebase rules and authorization setup truly deserve real time at the start of a project, not at the end. Every shortcut we took there ended up costing us later - especially where time was of the essence. On the design side, building around a metaphor (the tree, falling leaves) made product decisions easier because we could ask intuitive questions such as "what would actually happen naturally in this scene?" instead of inventing the rules and variables from scratch.
What's next for Leaflet
Next we plan to implement seasonal photo recalls, presenting seasonal memories from the past to foster nostalgia and keep a more active user experience. We also plan to improve the UI and User interface to make the tree leaf animation and creation mechanics more dynamic, which also serves to provide our users with more visual feedback as per the values of our project.

Log in or sign up for Devpost to join the conversation.