A frontend developer with a 4-hour daily commute, two young kids, and zero free time decided to build passive income anyway.
Table of Contents
- Why a guy with no free time started a side project
- The Stack
- The Tool Factory Pattern
- i18n Without next-intl
- SEO That Scales
- Monetization (the honest version)
- What I Got Wrong
- Current Stats (week 2)
- What's Next
Why a Guy with No Free Time Started a Side Project {#why}
My daily schedule looks like this:
- 5:00 AM — Wake up
- 5:00–7:00 — Commute (2 hours one way)
- 7:00–4:00 PM — Work
- 4:00–6:00 — Commute back
- 6:00–9:00 — Dinner, bath time, bedtime for two daughters (ages 6 and 7)
- 9:00–11:00 — The only window I have
I've been a frontend developer for 10 years. I'm not exceptional. I'll never build the next React or invent a new state management library. But I'm fast at copying patterns that work. That's my only real skill.
One day on the train I was searching "퇴직금 계산기" (Korean severance pay calculator) and landed on a terrible website. Slow, full of pop-ups, wrong calculations. I thought: I could build this in a day. And if I build 50 of these...
Two weeks later, rhand.app has 68 free tools in 6 languages.
The Stack
Nothing fancy. I optimized for speed-to-ship, not elegance.
- Next.js 16 (App Router)
- Tailwind CSS 4
- Vercel (free tier)
- Backend: None
- Database: None
- Testing: Vitest + Playwright
Why no backend? Every tool runs in the browser. A loan calculator doesn't need an API. A password generator doesn't need a database. Client-side means:
- Zero server costs at any scale
- Zero privacy concerns (no data leaves the browser)
- Zero DevOps
My total monthly cost is $0.
The Tool Factory Pattern
This is the only clever thing I did. Instead of building 68 unique apps, I built a factory.
Every tool follows the same structure:
src/lib/tools/{slug}/
└── calculator.ts # Pure functions. No React.
src/app/[locale]/tools/{slug}/
├── page.tsx # Server component (SEO, metadata)
└── {Name}Client.tsx # Client component (interactive UI)
src/lib/dictionaries/tools/{locale}/
└── {slug}.json # All text: UI labels, FAQ, meta tags
The logic layer is boring on purpose
// src/lib/tools/compound-interest-calculator/calculator.ts
export function calculateCompoundInterest(input: CompoundInput): CompoundResult {
const { principal, monthlyContribution, annualRate, years, frequency } = input;
const r = annualRate / 100;
const n = frequency;
const t = years;
const amount = principal * Math.pow(1 + r/n, n*t)
+ monthlyContribution * ((Math.pow(1 + r/n, n*t) - 1) / (r/n));
// ...
}
Pure functions. No React imports. No side effects. Testable in milliseconds.
The page layer is copy-paste
// Every page.tsx looks almost identical
export default async function ToolPage({ params }: Props) {
const { locale } = await params;
const dict = await getToolDictionary(locale, SLUG);
return (
<>
<SEOHead ... />
<ToolLayout ...>
<ToolClient dict={dict} />
</ToolLayout>
</>
);
}
By tool #10 I stopped thinking about architecture. By tool #40 it was muscle memory. Adding a new tool takes about 4-6 hours including translations and tests.
The boring repetition is the point. I don't need creativity. I need volume.
i18n Without next-intl
I support 6 languages: English, Korean, Japanese, Chinese, Spanish, German.
I didn't use next-intl. Instead, each tool has its own dictionary:
// src/lib/dictionaries/tools/en/tip-calculator.json
{
"meta": {
"title": "Tip Calculator — Split Bills & Calculate Gratuity",
"description": "Calculate tips for restaurants, taxis, and services...",
"keywords": "tip calculator, gratuity calculator, bill splitter..."
},
"heading": "Tip Calculator",
"inputs": {
"billAmount": "Bill Amount",
"tipPercent": "Tip Percentage",
"splitCount": "Split Between"
},
"faq": [
{ "q": "How much should I tip?", "a": "..." }
]
}
68 tools × 6 languages = 408 JSON files. Sounds insane. But:
- Each file is self-contained (no cross-references)
- Adding a language = copying a folder and translating
- SEO keywords are per-tool, per-language (critical for ranking)
- No runtime overhead — loaded server-side, passed as props
SEO That Scales
Most tool sites ignore SEO. I made it a first-class concern.
Schema.org on every page
// Automatically generated for each tool
{
"@type": "WebApplication",
"name": "Tip Calculator",
"applicationCategory": "FinanceApplication",
"offers": { "price": "0" },
"inLanguage": ["en", "ko", "ja", "zh", "es", "de"]
}
FAQPage schema from dictionary
Every tool has 8-10 FAQ items. These serve double duty:
- Users actually read them
- Google uses them for "People also ask" rich results
// Auto-generated from the faq array in each dictionary
{
"@type": "FAQPage",
"mainEntity": faq.map(item => ({
"@type": "Question",
"name": item.q,
"acceptedAnswer": { "@type": "Answer", "text": item.a }
}))
}
Long-tail keywords > short keywords
I don't try to rank for "calculator." I try to rank for:
- "Korean severance pay calculator 2026 tax rate"
- "tip calculator split bill 4 people"
- "compound interest calculator with monthly contribution"
The FAQ naturally covers these long-tail variations. Each FAQ item is essentially a landing keyword.
hreflang = 6x visibility
alternates: {
languages: {
en: 'https://rhand.app/en/tools/tip-calculator',
ko: 'https://rhand.app/ko/tools/tip-calculator',
ja: 'https://rhand.app/ja/tools/tip-calculator',
// ...
}
}
Instead of one page competing for "tip calculator," I have six pages competing in six different language markets. No cannibalization.
Internal linking with semantic clusters
I don't just link to "tools in the same category." I built a relationship map:
const TOOL_RELATIONSHIPS = {
'loan-calculator': ['compound-interest-calculator', 'rent-vs-buy-calculator', 'take-home-pay'],
'tip-calculator': ['currency-converter', 'tax-free-calculator', 'percentage-calculator'],
// 68 tools mapped
};
Each tool links to 3-4 semantically related tools, not just category neighbors. "Loan calculator" links to "compound interest" and "rent vs buy" — because that's the user's actual journey.
Monetization (the honest version)
I'm making $0 right now.
AdSense is pending review. I built the ad slots into every tool page, but they're empty. The plan:
- Primary: AdSense display ads (2-3 slots per tool page)
- Secondary: Affiliate links where natural (shoe retailers on shoe size converter, etc.)
- Target: $10K MRR (ambitious, I know)
The math I'm betting on:
68 tools × ~5,000 monthly visits each = 340,000 pageviews
340,000 × $3 RPM = ~$1,000/month
Scale to 200 tools = ~$3,000/month
Improve RPM with targeted content = $5,000-10,000/month
This is all projection. Reality could be 10x worse or 10x better. I'll share real numbers when I have them.
What I Got Wrong
1. I built too many tools before validating demand
I should have built 10 tools, gotten traffic, then built 10 more. Instead I built 68 in a sprint. Some of them probably have zero search demand. I won't know which ones until Search Console data matures.
2. I underestimated content quality
Tools are easy. Writing good FAQ content in 6 languages is hard. Some of my Japanese and Chinese descriptions are mediocre. I'll need to revisit these.
3. I ignored community from the start
Building in isolation means no early feedback. I should have posted on dev.to, Reddit, and Twitter from day one. I'm starting now — two weeks late.
4. AdSense approval takes time
I assumed "build it and ads will come." AdSense review is still pending after two weeks. No revenue until that's resolved.
Current Stats (Week 2)
Let me be completely honest:
- 68 tools live
- 6 languages (en, ko, ja, zh, es, de)
- 237 pages indexed by Google
- 263 keywords showing impressions in Search Console
- ~25 visitors/week (yes, that's tiny)
- $0 revenue (AdSense pending)
- $0 costs (Vercel free tier)
- 2 weeks of development
Top Search Console keywords (all 0 clicks, but showing impressions):
- "utm builder" — 38 impressions
- "utm generator" — 31 impressions
- "xml sitemap" — 28 impressions
- "favicon checker" — 19 impressions
It's early. Very early. But 237 pages are indexed and 263 keywords are showing up. The SEO foundation is there. Now it's a waiting game.
What's Next
This month
- Get AdSense approved
- Post on dev.to, Product Hunt, and relevant communities
- Monitor Search Console — double down on tools that get impressions
Next 3 months
- Add 30 more tools based on actual search demand (not guessing)
- Improve content quality for JA/ZH translations
- Build backlinks through content marketing
6 months
- Target: 100+ tools, 50K monthly visits, first $1K month
- Start sharing revenue numbers publicly
The Part Nobody Tells You
I've been a developer for 10 years. I've seen dozens of "I quit my job and built a SaaS" success stories. They make it look like the hard part is building. It's not.
Building is the easy part. I proved that — 68 tools in 2 weeks. The architecture works. The code is clean. The SEO is set up properly. The translations are done.
And yet I have 25 visitors a week.
Nobody is coming.
I think a lot of developers fall into this trap. We're comfortable building. We can always add one more feature, fix one more bug, refactor one more component. It feels productive. But it's actually procrastination disguised as work.
The real challenge — the one I'm facing right now — is everything that happens after you ship:
- Writing about your project (like this post)
- Sharing it in communities without feeling like a spammer
- Waiting months for SEO to kick in
- Accepting that most of your 68 tools might never get traffic
- Doing marketing when your entire career has been engineering
I have a 4-hour daily commute and two young daughters. I get about 2 hours a night to work on this. Some nights I fall asleep before I even open my laptop. The dream of "passive income" and "indie developer freedom" sounds romantic until you're on month 1 with $0 revenue and 25 weekly visitors.
But here's why I'm not stopping:
My commute costs me 4 hours every day. That's 1,000 hours a year of my life spent on trains. If this project — or the next one, or the one after that — eventually generates even $2,000/month, I can work remotely. I get those 1,000 hours back. I get to see my kids in the morning.
That's not a business plan. That's a reason to keep going.
Try It
rhand.app — 68 free tools, 6 languages, no signup.
I'm not going to pretend this is a polished product. I built 68 tools in 2 weeks. There are bugs. Some translations are awkward. Some calculators might have edge cases I haven't found.
But every tool works. Every tool is free. Every tool runs in your browser without sending your data anywhere.
If you've tried to build passive income as a developer and struggled — I'd genuinely love to hear your story. Not the success story. The honest one. What did you try? Where did you get stuck? Are you still going?
Drop a comment below — I read every one.
Top comments (0)