← All Writing
March 12, 20268 min read

How I Built Fruit Exchange, a Neighborhood Fruit Tree Map

A map-based community tool where neighbors list backyard fruit trees and others can find them — styled like a 90s farming game, verified with email, and built across three sessions with Claude Code

YieldA live community fruit tree map at joseandgoose.com/fruit-exchange — neighbors list trees, visitors find free fruit, all on an interactive map
DifficultyIntermediate (Leaflet map integration, Supabase with 4 tables, email verification flow, custom pixel-art CSS)
Total Cook Time~6 hours across 3 sessions, refined over the following 10 days with user feedback

Ingredients

A Note on Format

Earlier posts on this site followed the build session-by-session — “Session 1, evening, 3 hours” — because those projects were built in a weekend or two. The next few posts cover longer arcs: weeks of incremental work, features that grew over time, projects that are still evolving. So the format shifts from build diary to retrospective. Same recipe card, same ingredients, same lessons — just a wider lens.

The Idea: Fruit Trees Are Everywhere and Nobody Knows

In Los Angeles, there are fruit trees in every other front yard. Lemon trees dropping hundreds of lemons. Fig trees with more fruit than a family can eat. Avocado trees that produce year-round. Most of that fruit falls on the ground and rots because the owner doesn’t need it and the neighbors don’t know it’s available.

I wanted a simple tool: a map where you can see which houses near you have fruit trees, what’s growing, and how to connect with the owner. Not a full marketplace. Not an app with logins and profiles. Just a map, a listing form, and a way to say “hey, can I grab some lemons?”

The twist: I wanted it to feel like a game. Specifically, like Harvest Moon on the SNES — pixel fonts, parchment-colored dialog boxes, chunky buttons. If you’re going to build a fruit tree finder, it should feel like walking into a village market, not filling out a government form.

Making It Feel Like a Village Market

The design decision came before any code. I told Claude: “style this like Harvest Moon SNES dialog boxes — pixel font, parchment backgrounds, chunky borders.” That one prompt shaped the entire visual language.

🔧 Developer section: Harvest Moon CSS

The font alone does most of the work. Press Start 2P is a free Google Font that looks exactly like 90s game UI text. Pair it with warm background colors and thick borders and you’re immediately in a different world than a typical web form.

Design constraint as feature

Pixel fonts are hard to read below ~9px. That constraint forced every label and description to be short and direct. The UI ended up cleaner because the font wouldn’t let me be verbose.

Building the Map

Google Maps charges per load. Mapbox needs an API key. Leaflet with OpenStreetMap tiles is completely free, no key required, and looks great. The trade-off is that Leaflet is a client-side library — it only works inside the browser. Next.js, by default, tries to render pages on the server first before sending them to the browser (called server-side rendering, or SSR). Leaflet crashes during that server step because there’s no browser to render into.

🔧 Developer section: Leaflet + Next.js

Each fruit type gets its own marker color on the map. Clicking a marker opens a popup with the tree details, the owner’s Venmo link (if they added one), and an option to record an exchange. The map is the entire interface — there’s no separate list view or search page.

The Trust Problem: Who Can List a Tree?

Anyone can look at the map. But listing a tree means putting an address on a public page. That needs to be a real person with a real email who actually lives there — not someone listing a stranger’s house as a prank.

The solution: email verification for owners only. When you submit a listing, Resend sends a one-time verification link to your email. Click it, and the listing goes live. Don’t click it, and the listing never appears on the map. The token expires after 24 hours.

🔧 Developer section: Verification flow

Requesters, on the other hand, are fully anonymous. If you see an address that doesn’t have a tree listed but you know one’s there, you can submit a request — no email, no account. The request shows up as a different marker style so the community can see where demand exists.

Four Tables, Four Purposes

The data model is intentionally flat. Four Supabase tables, each independent — no complex relationships between them. Each table handles one concern:

Ten fruit types are supported: apple, lemon, lime, orange, grapefruit, fig, avocado, persimmon, stone fruit, and “other” with a free-text field. The list came from walking Goose around the neighborhood and writing down what I saw.

Six Components, One Page

The entire feature lives on a single page at /fruit-exchange. No routing, no sub-pages. Everything is a modal or popup layered on top of the map:

Five API routes handle the backend: listings (GET all / POST new), requests, verification, exchange recording, and a stats endpoint that returns counts for the welcome screen.

Final Output

Fruit Exchange went live on March 1 and has been running since. The map loads, listings appear, verification emails send, and the Harvest Moon styling gets comments every time someone sees it for the first time.

What went fast

What needed patience

The thing I like most about Fruit Exchange is that it’s not a tool for me. The server articles, the Garmin recaps, the alert system — those are all infrastructure I built for myself. This is the first feature on the site that exists entirely for other people. Whether anyone uses it at scale doesn’t matter yet. The fact that it works and it’s live means the idea is testable, and that’s the point.

← Back to all writing