Field Notes: Building An App with Claude, Cursor, and a Lot of Google
2023-12-09
·
⏱︎ 13 min read
The Beginning: From Idea to First Lines
I've had this idea bouncing around in my head for a while - an app to help people quit nicotine that actually feels... human? Personal? Not just another clinical tracker that makes you feel worse when you slip up. I'd tweaked enough code in my day job to understand the fundamentals, but this was my first time starting from a blank canvas.
Planning it Out with Claude
My first stop was Claude-3.5. I needed someone to think through this with me, especially since I wanted to understand what I was building, not just cobble together Stack Overflow answers. Those first conversations were mostly me throwing out ideas and Claude helping me structure them into actual components and features:
"Okay, so I want users to feel supported when they log a slip..."
"Let's think about how we can structure that interaction flow..."
The initial planning phase was crucial - we mapped out:
- A clean, simple onboarding flow
- Daily check-ins that didn't feel punitive
- Progress tracking that celebrated small wins
- Profile pages that felt personal
- Overall, simple, because I too, resist complex
Building V1: The Cursor Chronicles
Cursor became my new best friend. Having Claude right there in the editor made a huge difference - especially when I was staring at error messages that made no sense. The first version came together piece by piece.
I got comfortable improving the UI, then coming back and asking questions like this: "I’m creating unpouch, an app to help someone track their nicotine pouch usage and push them to quit. This test UI I made doesn’t really make sense, how would you improve / fix for my MVP?"
It would come back and give reasonable suggestions (some I'd disagree with) such as daily focus over weekly, better progress metrics, and even a novel answer to a burning question: how much money am I about to save?
Starting with the Basics
First up was just getting a basic app structure working with React Native and Expo. Simple screens, navigation between them, nothing fancy. Just making sure I had a foundation that wasn't going to fall apart.
Adding Some Life
Then came the fun part - building out the actual features:
- A simple profile page (just static at first)
- Basic progress tracking with some placeholder charts
- Daily logging interface (though it wasn't saving anything yet)
- A rudimentary dashboard that pulled it all together
The charts were an adventure all their own. Started with some basic React Native chart libraries, fumbled through the documentation, and eventually got something that looked decent. Was it perfect? No. Did it show a line going up when progress was made?
Yes, and that was enough for V1. Even then, I had to continue to fumble around with things like dates/times (to make sure it logged for the right time and the right person) and then also ensure the visualization was correct. It took an enormous amount of trial and errort.
The "This File Is Getting Scary" Phase
About halfway through building all this, I realized my main App.tsx file was becoming an absolute unit. We're talking hundreds of lines of code that made less sense every time I looked at it. This led to my crash course in code organization. Because I began to realize that every change often meant I was manipulating the same file, often resulting in circular solutions.
With something more modular, I would be able to isolate fixes and make quicker improvements. Of course, a simple codebase is a lot of fun, I think Flowy is less than a handful of files.
The conversation with Claude went something like:
"Help, my code is a mess! How do I chunk this into smaller pieces, and ensure they're all referencing each other correctly?""
"Let's break this down into smaller, manageable pieces..."
The real breakthrough came when I started thinking in components instead of pages. Breaking everything down into:
- Layout components (headers, footers, containers)
- Feature components (progress trackers, input forms)
- Utility components (buttons, loading states)
It felt like organizing a messy closet - painful at first, but so satisfying once it was done. And the funny benefit / side-effect, is that it made me so much more knowledgable about what each individual function did, how the code operated, how they were all connected. Finally, I felt like I was that much more in the driverseat.
Enter Supabase: The Database Evolution
After getting the basic app structure working with static data, it was time to make this thing real. I'd worked with databases before, but mostly tweaking existing setups and my other shitty projects.
Database Design: The Foundation
First up was planning the database structure. I spent some time just mapping it out:
- User profiles (the basics plus quit-specific data)
- Daily logs (tracking progress and slip-ups)
- Onboarding (making sure we captured why people were quitting. My marketer brain came alive here, if I could capture this information on the front-end, I could do all sorts of actionable things with this information.)
The conversations with Claude about database design were gold:
"Think about what queries you'll need to run most often..."
"Consider how you'll want to analyze this data later..."
SQL Adventures
I ended up writing more SQL than I expected. Turns out, when you need to query user progress over time with specific date ranges, those pretty Supabase UI buttons only get you so far. Some of my favorite moments were:
-- The query that finally made the progress chart work right
SELECT date_trunc('day', created_at) as day,
count(*) as total_logs
FROM daily_logs
WHERE user_id = ?
GROUP BY day
ORDER BY day;
Learning to write efficient queries was a game-changer. The time spent in the SQL editor testing queries before implementing them in the app? Worth every minute.
The Authentication Saga
Everything was going great until I hit authentication. Supabase seemed like the obvious choice, largely because it was free and who knows if this would go anywhere. Perhaps I'll need to re-evaluate later if I were to actually take this to the app store.
The documentation looked straightforward enough:
- Initialize Supabase client ✓
- Call signUp() function ✓
- Handle the response... wait, why isn't this working?
Turns out there's a whole dance between:
- Setting up the auth providers correctly
- Managing session states (is the user logged in? are they really logged in?)
- Handling token refreshes
There were all sorts of weird issues one will encounter when messing with Auth. Are these issues happening because the user is "still logged in" (enter messing with tokens/logout/login), how long do I need to (or should) keep their state logged in, etc. This was something that cursor wasn't particuarly great with, I was able to work uphill reading docs online, asking questions, but had I just left Cursor to its devices I fear that I would be still fixing all of this.
Expo Go: The Good, The Bad, The "Why Isn't This Working on My Phone?"
Working with Expo Go was actually pretty cool - being able to see changes instantly on my phone felt like magic. Until it didn't. Hot reload would randomly decide to take a break, and sometimes the app would just... disappear.
It was still really awesome to be able to deploy this, scan a QR code to test, and see/demo the application in all its glory. It made the whole thing feel that much more live and real. Honestly speaking, I'm not sure what kind of bloat this added to my experience, and I surely have to do some research, but it felt useful and so I pushed forward.
I learned the sacred art of:
- Close the app
- Stop the server
- Clear metro bundler cache
- Restart everything
- Hope for the best
- Repeat steps 1-5 until it works
The Final Pieces: Making it Production-Ready
The last phase was all about making sure everything worked reliably:
- Error handling that actually made sense to users
- Loading states everywhere (learned this one the hard way)
- Proper data validation
Looking Back
Building this app taught me more than just code. It showed me that you don't need to be a "real developer" to build something real. Sometimes you just need:
- The right tools (thanks, Claude and Cursor)
- The patience to debug (thanks, console.log, my faithful friend)
- The willingness to refactor when things get messy
Next time? I'll definitely:
- Start with a better file structure
- Spend more time on database design upfront
- Set up proper testing from the beginning
- Not underestimate the complexity of auth flows
But for now, I'm just proud that something I built actually works - and hopefully will help some people along the way.