03
First Project
How a project starts from scratch. From "I want to build X" to a working app. The real process, not the idealized version.
From ScratchProcessReal Example
Every project I have ever built started the same way: I had a real problem at work and no tool to solve it. Not once did I sit down and say "I want to build an app." It always started with frustration. Something took too long, something was manual, something broke every week. That frustration is the best starting point you can have.
The Problem: Manual QA That Ate 30 Minutes Every Time
Let me walk you through one project from zero to deployed, so you can see exactly how this works in practice. The project is CampaignPulse — a QA tool I built for my team at INFUSE.
Here's the problem: at work, every time we send email campaigns to clients, someone has to manually check 10+ criteria. Are all the links working? Do they have the right UTM tracking parameters? Are DNS records (SPF, DKIM, DMARC) configured correctly for the sending domain? Is the HTML rendering properly? Are there broken images? Is the unsubscribe link present and working?
This process took 30+ minutes per campaign. And we do this dozens of times a day. That's hours of someone's day spent clicking links and checking DNS records by hand. It was tedious, error-prone, and everyone hated it.
Let me walk you through one project from zero to deployed, so you can see exactly how this works in practice. The project is CampaignPulse — a QA tool I built for my team at INFUSE.
Here's the problem: at work, every time we send email campaigns to clients, someone has to manually check 10+ criteria. Are all the links working? Do they have the right UTM tracking parameters? Are DNS records (SPF, DKIM, DMARC) configured correctly for the sending domain? Is the HTML rendering properly? Are there broken images? Is the unsubscribe link present and working?
This process took 30+ minutes per campaign. And we do this dozens of times a day. That's hours of someone's day spent clicking links and checking DNS records by hand. It was tedious, error-prone, and everyone hated it.
The First Prompt — What I Actually Typed to Claude
I didn't plan out a grand architecture. I didn't sketch wireframes. I opened Claude and typed something close to this:
"I spend 30+ minutes doing QA on every email campaign. I manually check links, UTM parameters, DNS records, and HTML rendering. I want a tool where I can paste the HTML of an email campaign, and it automatically runs these checks and gives me a report. Let's start with just link checking — extract all links from the HTML and verify each one returns a 200 status code. Show a simple pass/fail list. Vanilla JavaScript, no frameworks — I want it simple."
Notice what I did: I explained the problem, described the solution I wanted, chose the simplest starting point (just link checking), and specified the tech approach (vanilla JS). That's a prompt Claude can absolutely work with.
I didn't plan out a grand architecture. I didn't sketch wireframes. I opened Claude and typed something close to this:
"I spend 30+ minutes doing QA on every email campaign. I manually check links, UTM parameters, DNS records, and HTML rendering. I want a tool where I can paste the HTML of an email campaign, and it automatically runs these checks and gives me a report. Let's start with just link checking — extract all links from the HTML and verify each one returns a 200 status code. Show a simple pass/fail list. Vanilla JavaScript, no frameworks — I want it simple."
Notice what I did: I explained the problem, described the solution I wanted, chose the simplest starting point (just link checking), and specified the tech approach (vanilla JS). That's a prompt Claude can absolutely work with.
What Claude Generated First — And Why It Wasn't Perfect
Claude gave me a single HTML file with embedded JavaScript. It had a text area where you paste HTML, a button that says "Check Links," and a results section. The JavaScript used regex to extract URLs from the HTML, then tried to fetch each one and check the status code.
Did it work perfectly? No. Here's what went wrong:
- CORS errors: The browser blocked requests to external URLs. Claude's first version tried to check links directly from the browser, which doesn't work because of browser security rules.
- Regex missed some links: The pattern didn't catch links inside CSS
- No visual feedback: While checking 50+ links, the page just sat there with no indication anything was happening.
This is completely normal. The first version is never perfect. But it gave me a working starting point — something I could see, test, and improve.
Claude gave me a single HTML file with embedded JavaScript. It had a text area where you paste HTML, a button that says "Check Links," and a results section. The JavaScript used regex to extract URLs from the HTML, then tried to fetch each one and check the status code.
Did it work perfectly? No. Here's what went wrong:
- CORS errors: The browser blocked requests to external URLs. Claude's first version tried to check links directly from the browser, which doesn't work because of browser security rules.
- Regex missed some links: The pattern didn't catch links inside CSS
url() or background-image attributes.- No visual feedback: While checking 50+ links, the page just sat there with no indication anything was happening.
This is completely normal. The first version is never perfect. But it gave me a working starting point — something I could see, test, and improve.
The Iteration — Real Messages From the Session
Here's approximately how the conversation continued:
Me: The link checking doesn't work from the browser because of CORS. I need a backend that does the actual HTTP requests. Can we use n8n webhooks for this? I already have n8n running on my server.
Claude: *[Rewrites the link checker to send URLs to an n8n webhook, which does the actual HTTP checks and returns results]*
Me: It works now, but I also need UTM parameter checking. Every link should have utm_source, utm_medium, and utm_campaign. If any of those are missing, flag it as a warning.
Claude: *[Adds UTM parameter extraction and validation]*
Me: Good. Now I want DNS checks. When I paste the HTML, extract the sending domain from the links and check if SPF, DKIM, and DMARC records exist. Use Google's DNS API for this.
Claude: *[Adds DNS record checking via Google DNS API]*
Me: Can you add a scoring system? Each check category (links, UTMs, DNS) gets a score out of 100. Then show an overall score as a big number at the top of the page. Green if above 80, yellow if 50-80, red if below 50.
Claude: *[Adds the scoring system with color-coded display]*
See the pattern? Each message added one thing. Each thing was testable. I tested between messages. When something didn't work, I said exactly what was wrong.
Here's approximately how the conversation continued:
Me: The link checking doesn't work from the browser because of CORS. I need a backend that does the actual HTTP requests. Can we use n8n webhooks for this? I already have n8n running on my server.
Claude: *[Rewrites the link checker to send URLs to an n8n webhook, which does the actual HTTP checks and returns results]*
Me: It works now, but I also need UTM parameter checking. Every link should have utm_source, utm_medium, and utm_campaign. If any of those are missing, flag it as a warning.
Claude: *[Adds UTM parameter extraction and validation]*
Me: Good. Now I want DNS checks. When I paste the HTML, extract the sending domain from the links and check if SPF, DKIM, and DMARC records exist. Use Google's DNS API for this.
Claude: *[Adds DNS record checking via Google DNS API]*
Me: Can you add a scoring system? Each check category (links, UTMs, DNS) gets a score out of 100. Then show an overall score as a big number at the top of the page. Green if above 80, yellow if 50-80, red if below 50.
Claude: *[Adds the scoring system with color-coded display]*
See the pattern? Each message added one thing. Each thing was testable. I tested between messages. When something didn't work, I said exactly what was wrong.
From Single Page to Deployed App — How It Grew
The first version was literally one HTML file. Over the next couple of weeks, it grew:
- Week 1: Basic link checking, UTM validation, DNS checks, scoring. Still a single HTML file with vanilla JavaScript.
- Week 2: I split the code into separate files —
- Week 3: Added the ability to check campaigns by URL (not just pasting HTML). Added history so you can see past checks. Made the UI look professional with a proper color scheme, cards, and progress indicators.
At the end of week 3, I had a tool my team could actually use. It wasn't a toy project — it did real work, saving real time, every single day.
The first version was literally one HTML file. Over the next couple of weeks, it grew:
- Week 1: Basic link checking, UTM validation, DNS checks, scoring. Still a single HTML file with vanilla JavaScript.
- Week 2: I split the code into separate files —
index.html, app.js, styles.css, config.js, and a checks/ folder with each check type in its own file. Added AI-powered content analysis using GPT-4o to catch issues like typos, broken personalization tokens, and suspicious content.- Week 3: Added the ability to check campaigns by URL (not just pasting HTML). Added history so you can see past checks. Made the UI look professional with a proper color scheme, cards, and progress indicators.
At the end of week 3, I had a tool my team could actually use. It wasn't a toy project — it did real work, saving real time, every single day.
The Deployment Story — Getting It on a Server
Once CampaignPulse worked on my laptop, I needed to put it somewhere my team could access it. This was its own conversation with Claude:
Me: I need to deploy CampaignPulse to my AWS EC2 server at [IP address]. It's a static site with vanilla JS — no build step needed. I want it available at campaignpulse.infuse.com. The server already has Nginx and Certbot installed.
Claude: *[Gives me step-by-step: create the directory, upload files with rsync, configure Nginx server block, set up SSL with certbot, point DNS to the server]*
The deployment took about 20 minutes. Most of that was waiting for DNS to propagate. Now the team goes to
Once CampaignPulse worked on my laptop, I needed to put it somewhere my team could access it. This was its own conversation with Claude:
Me: I need to deploy CampaignPulse to my AWS EC2 server at [IP address]. It's a static site with vanilla JS — no build step needed. I want it available at campaignpulse.infuse.com. The server already has Nginx and Certbot installed.
Claude: *[Gives me step-by-step: create the directory, upload files with rsync, configure Nginx server block, set up SSL with certbot, point DNS to the server]*
The deployment took about 20 minutes. Most of that was waiting for DNS to propagate. Now the team goes to
campaignpulse.infuse.com, pastes a campaign, and gets a full QA report in under a minute instead of 30+ minutes.How the Team Reacted
The first person I showed it to said: "Wait, this does everything I just spent 30 minutes doing?" Yes. In about 45 seconds.
Within a week, the entire QA team was using it. People started asking for new features: "Can it also check image sizes?" "Can it verify the unsubscribe link goes to the right page?" "Can we save reports to share with clients?"
That's when you know you built the right thing — when people who use it start asking for more. Each request was another conversation with Claude, another feature added, another iteration. The tool kept getting better because real usage generates real feedback.
The first person I showed it to said: "Wait, this does everything I just spent 30 minutes doing?" Yes. In about 45 seconds.
Within a week, the entire QA team was using it. People started asking for new features: "Can it also check image sizes?" "Can it verify the unsubscribe link goes to the right page?" "Can we save reports to share with clients?"
That's when you know you built the right thing — when people who use it start asking for more. Each request was another conversation with Claude, another feature added, another iteration. The tool kept getting better because real usage generates real feedback.
Second Example: RT Helper — Same Pattern, Different Problem
RT Helper came from a completely different pain point. I needed to process Excel files with a specific column structure — standard columns, standard transformation rules, but doing it manually was slow and error-prone.
The first prompt was something like: "I have Excel files with these columns: [list]. I need to apply these rules: [list of transformations]. Output a new Excel file with the processed data."
Claude started with a Python script. It worked, but I realized my teammates needed it too, and they weren't going to run Python scripts. So the next iteration was: "Can we turn this into a web app where someone uploads the Excel file and downloads the processed result?"
That became an n8n-powered web application. Upload through a browser, processing happens on the server, download the result. Same pattern as CampaignPulse: start small, make it work, then make it accessible.
RT Helper came from a completely different pain point. I needed to process Excel files with a specific column structure — standard columns, standard transformation rules, but doing it manually was slow and error-prone.
The first prompt was something like: "I have Excel files with these columns: [list]. I need to apply these rules: [list of transformations]. Output a new Excel file with the processed data."
Claude started with a Python script. It worked, but I realized my teammates needed it too, and they weren't going to run Python scripts. So the next iteration was: "Can we turn this into a web app where someone uploads the Excel file and downloads the processed result?"
That became an n8n-powered web application. Upload through a browser, processing happens on the server, download the result. Same pattern as CampaignPulse: start small, make it work, then make it accessible.
Third Example: Nurturing Report System — Even Simpler Start
The Nurturing Report System started as the simplest possible need: "I need to convert CSV files into formatted Excel reports." That's it. But "formatted" was doing a lot of work in that sentence — specific colors for specific columns, merged header cells, calculated summary fields, conditional formatting rules, and a layout that matched exactly what stakeholders expected to see.
Claude built it as a FastAPI backend (Python) with a Next.js frontend, all containerized with Docker. What started as a CSV-to-Excel converter eventually became a full reporting platform with templates, scheduling, and multi-user access.
The lesson: even the smallest starting point can grow into something substantial. But you have to start small to start at all.
The Nurturing Report System started as the simplest possible need: "I need to convert CSV files into formatted Excel reports." That's it. But "formatted" was doing a lot of work in that sentence — specific colors for specific columns, merged header cells, calculated summary fields, conditional formatting rules, and a layout that matched exactly what stakeholders expected to see.
Claude built it as a FastAPI backend (Python) with a Next.js frontend, all containerized with Docker. What started as a CSV-to-Excel converter eventually became a full reporting platform with templates, scheduling, and multi-user access.
The lesson: even the smallest starting point can grow into something substantial. But you have to start small to start at all.
The Universal Pattern: Problem, First Prompt, Iterate, Deploy, Iterate More
Every single project follows this pattern:
1. Problem — Something at work is manual, slow, or error-prone
2. First Prompt — Describe the problem and the simplest version of a solution
3. Iterate — Build feature by feature, testing each one
4. Deploy — Put it where people can use it
5. Iterate More — Real users give real feedback, which drives more features
CampaignPulse: manual QA -> link checker -> full QA tool -> deployed on AWS
RT Helper: manual Excel processing -> Python script -> web app with file upload
Nurturing Report: CSV to Excel -> formatted reports -> full reporting platform
The pattern never changes. The projects get more complex, but the process stays the same.
Every single project follows this pattern:
1. Problem — Something at work is manual, slow, or error-prone
2. First Prompt — Describe the problem and the simplest version of a solution
3. Iterate — Build feature by feature, testing each one
4. Deploy — Put it where people can use it
5. Iterate More — Real users give real feedback, which drives more features
CampaignPulse: manual QA -> link checker -> full QA tool -> deployed on AWS
RT Helper: manual Excel processing -> Python script -> web app with file upload
Nurturing Report: CSV to Excel -> formatted reports -> full reporting platform
The pattern never changes. The projects get more complex, but the process stays the same.
The First Session Is a Conversation, Not a Command
The first session with Claude on a new project should feel like a brainstorm. You describe your problem. Claude suggests an approach — maybe a Python script, maybe a web app, maybe something simpler than you expected. You respond with corrections and additions: "Yes, but I also need it to handle multiple files at once" or "Actually, the tricky part is that the date format changes between files."
You go back and forth. Claude adjusts its approach. Within 30 minutes you usually have something that actually runs. Not finished — but running. Something you can look at, click on, test. That first working version, no matter how rough, is the foundation everything else is built on.
The first session with Claude on a new project should feel like a brainstorm. You describe your problem. Claude suggests an approach — maybe a Python script, maybe a web app, maybe something simpler than you expected. You respond with corrections and additions: "Yes, but I also need it to handle multiple files at once" or "Actually, the tricky part is that the date format changes between files."
You go back and forth. Claude adjusts its approach. Within 30 minutes you usually have something that actually runs. Not finished — but running. Something you can look at, click on, test. That first working version, no matter how rough, is the foundation everything else is built on.
Your First Prompt Should Never Be "Build Me an App"
That is too abstract and Claude will make a hundred assumptions you probably disagree with. Start with the problem.
"I have an Excel file with these columns: name, email, status, date. I need to filter rows where status is active and date is within the last 30 days, then generate a summary report as a new Excel file."
That is specific. Claude can work with that immediately. It knows the input format, the filtering logic, and the output format. Compare that to "build me a data processing tool" — Claude would have to guess every single detail.
Another good first prompt: "Every morning I manually check 5 websites to see if they're running. I open each URL, wait for it to load, and note down whether it's up or down. I want a script that does this automatically and sends me a Slack message if any site is down."
Problem. Input. Expected behavior. Output. That's the formula.
That is too abstract and Claude will make a hundred assumptions you probably disagree with. Start with the problem.
"I have an Excel file with these columns: name, email, status, date. I need to filter rows where status is active and date is within the last 30 days, then generate a summary report as a new Excel file."
That is specific. Claude can work with that immediately. It knows the input format, the filtering logic, and the output format. Compare that to "build me a data processing tool" — Claude would have to guess every single detail.
Another good first prompt: "Every morning I manually check 5 websites to see if they're running. I open each URL, wait for it to load, and note down whether it's up or down. I want a script that does this automatically and sends me a Slack message if any site is down."
Problem. Input. Expected behavior. Output. That's the formula.
When to Stop Adding Features and Ship
This is something I learned the hard way. You will always think of one more thing to add. One more check, one more button, one more nice-to-have. If you keep adding features, you never ship.
My rule: ship when it solves the core problem. CampaignPulse was useful with just link checking. That alone saved 10 minutes per campaign. I could have spent two more weeks adding every feature I eventually built — but instead, I shipped the link checker and let my team start using it while I added features on top.
The best feature request is one that comes from a real user after they've used your tool. Those requests are always better than the ones you imagine at your desk.
This is something I learned the hard way. You will always think of one more thing to add. One more check, one more button, one more nice-to-have. If you keep adding features, you never ship.
My rule: ship when it solves the core problem. CampaignPulse was useful with just link checking. That alone saved 10 minutes per campaign. I could have spent two more weeks adding every feature I eventually built — but instead, I shipped the link checker and let my team start using it while I added features on top.
The best feature request is one that comes from a real user after they've used your tool. Those requests are always better than the ones you imagine at your desk.
Common First-Project Pitfalls
1. Trying to build too much: Your first project should solve ONE problem. Not three. Not five. One. You can always expand later.
2. Not testing early: Don't write code for two hours and then test. Build one thing, test it, build the next thing, test it. If you wait too long, you won't know which part broke.
3. Ignoring errors: When you see a red error in the terminal or browser console, don't ignore it and keep going. Stop. Copy the error. Paste it to Claude. Fix it before moving on. Errors compound — one unfixed error leads to three more.
4. Picking a project you don't care about: "I'll build a to-do app because that's what tutorials say." No. Build something you actually need. The motivation to push through problems comes from wanting the solution. If you don't care about to-do lists, build something else.
5. Not deploying: A project that only runs on your laptop is a toy. Deploy it — even if it's just to a free tier somewhere. The act of deploying teaches you things you can't learn any other way, and it forces you to make the project robust enough for real use.
6. Perfectionism before launch: Your first version will be ugly. The code will be messy. Some edge cases won't be handled. That's fine. Ship it. Clean it up later. A working ugly tool is infinitely more useful than a perfect tool that doesn't exist.
1. Trying to build too much: Your first project should solve ONE problem. Not three. Not five. One. You can always expand later.
2. Not testing early: Don't write code for two hours and then test. Build one thing, test it, build the next thing, test it. If you wait too long, you won't know which part broke.
3. Ignoring errors: When you see a red error in the terminal or browser console, don't ignore it and keep going. Stop. Copy the error. Paste it to Claude. Fix it before moving on. Errors compound — one unfixed error leads to three more.
4. Picking a project you don't care about: "I'll build a to-do app because that's what tutorials say." No. Build something you actually need. The motivation to push through problems comes from wanting the solution. If you don't care about to-do lists, build something else.
5. Not deploying: A project that only runs on your laptop is a toy. Deploy it — even if it's just to a free tier somewhere. The act of deploying teaches you things you can't learn any other way, and it forces you to make the project robust enough for real use.
6. Perfectionism before launch: Your first version will be ugly. The code will be messy. Some edge cases won't be handled. That's fine. Ship it. Clean it up later. A working ugly tool is infinitely more useful than a perfect tool that doesn't exist.
The Confidence Snowball
Your first project does not need to be impressive. It needs to be useful to you. If it saves you 10 minutes a day, that is a win. If it replaces a manual copy-paste workflow you do three times a week, that is a win.
The confidence you get from building something real — something you actually use at work — is what carries you to the next project and the one after that. Every project I built made the next one easier, not because the tools got simpler, but because I got better at describing what I needed. By project five, I could look at a problem and immediately know: what the first prompt should be, how to break it into steps, and roughly how long it would take. That instinct only comes from building.
Your first project does not need to be impressive. It needs to be useful to you. If it saves you 10 minutes a day, that is a win. If it replaces a manual copy-paste workflow you do three times a week, that is a win.
The confidence you get from building something real — something you actually use at work — is what carries you to the next project and the one after that. Every project I built made the next one easier, not because the tools got simpler, but because I got better at describing what I needed. By project five, I could look at a problem and immediately know: what the first prompt should be, how to break it into steps, and roughly how long it would take. That instinct only comes from building.
What You Should Build — Your Assignment
Think about your work week. What do you do repeatedly that's manual? What takes too long? What involves copying data from one place to another? What involves checking things by hand?
That's your first project. It doesn't have to be a web app. It could be a script that processes files. A tool that generates reports. A checker that validates data. Whatever your version of "I spend 30 minutes doing QA on campaigns" is — that's where you start.
Open Claude. Describe the problem. Describe the simplest version of a solution. And start building. The first project is the hardest — not because the technology is hard, but because you haven't done it before. After this one, you'll know the process, and every project after it will be easier.
Think about your work week. What do you do repeatedly that's manual? What takes too long? What involves copying data from one place to another? What involves checking things by hand?
That's your first project. It doesn't have to be a web app. It could be a script that processes files. A tool that generates reports. A checker that validates data. Whatever your version of "I spend 30 minutes doing QA on campaigns" is — that's where you start.
Open Claude. Describe the problem. Describe the simplest version of a solution. And start building. The first project is the hardest — not because the technology is hard, but because you haven't done it before. After this one, you'll know the process, and every project after it will be easier.