15 Things You Shouldn't Build Yourself (and What to Use Instead)

There's a certain type of developer energy that wants to build everything from scratch. I've been there. Rolling out your own authentication flow, hand-writing SQL migrations, copy-pasting form validation logic between projects like it's a personality trait.
But after 24 years of coding & hundreds of debugging hours behind me, I can tell you with full confidence: the most dangerous words in a developer's vocabulary are "how hard can it be?"
Here are 15 things you should reach for a tool on - not because you can't build them yourself, but because the cost isn't worth it.
1. Don't Reinvent Databases
Use: Prisma + Postgres (Neon / Supabase) — or skip the whole layer with Convex
Writing raw SQL and managing migrations by hand sounds like a rite of passage. It isn't. It's silent suffering dressed up as discipline. Prisma gives you type-safe queries, a clean schema DSL & a migration workflow that won't haunt you at 2am. Pair it with a managed Postgres provider & you're done before you've started crying.
That said - if you're building a modern full-stack app & want to go further, Convex is worth serious attention. It's a reactive backend platform with its own built-in database, real-time subscriptions, server functions & end-to-end TypeScript types baked in from the ground up. No Prisma needed. No migration files. No ORM config to wrestle with. Your queries are just TypeScript functions & the data layer handles the rest. It's one of those tools that genuinely changes how you think about building - less "plumbing the database into my app" & more "my app is the database." I use it on my own projects & it's legitimately cutting edge.
2. Don't Write Forms by Hand
Use: React Hook Form + Zod
Hand-rolled form validation is where confidence goes to die. One missed edge case, one malformed email that slips through, one undefined that breaks your submit handler - and suddenly you've got a support ticket from a user who "just typed their name." React Hook Form + Zod gives you schema-first validation that's composable, reusable & actually readable.
3. Don't Build Payment Flows Yourself
Use: Stripe or Polar (web) / Superwall or RevenueCat (mobile)
Never - and I mean never - touch PCI compliance willingly. It's a labyrinth of liability with a compliance certificate at the end that nobody outside your bank will care about. Use Stripe or Polar. Let them handle the hard bits. Your job is to ship features, not audit trails.
4. Don't Build Search from Scratch
Use: Algolia / Meilisearch / Typesense
Text search is one of those things that looks simple until you're elbow-deep in tokenisation, relevance scoring & edge cases involving special characters. It's way harder than it looks. Hand it off to something built for the job & spend your time on things users will actually feel.
5. Don't Overbuild Backend Infrastructure Early
Use: Serverless / BaaS first
Your app doesn't need Kubernetes on day one. It doesn't need microservices on month one either. Start with serverless functions & a BaaS - Supabase, Convex, Firebase, whatever fits your stack. Scale later. Survive now. The graveyard of startups who over-engineered before finding product-market fit is full of genuinely impressive architecture.
6. Don't Ignore Error Tracking
Use: Sentry / LogRocket
console.log is not observability. It's wishful thinking with a semicolon. You need real error tracking in production - stack traces, user context, breadcrumbs leading up to the crash. Sentry will catch things your users never even bother reporting. That's the feature.
7. Don't Skip Analytics
Use: PostHog / Plausible
If you're not tracking how people actually use your product, you're flying blind. You're building based on assumptions - and assumptions are just educated guesses with better PR. PostHog gives you the product analytics side; Plausible keeps it privacy-friendly & lightweight. Either way, get the data.
8. Don't Design UI Without Components
Use: shadcn/ui / Radix / Mantine
At MVP stage, consistency beats creativity. That's not pessimism - it's just the truth. A coherent, accessible UI built on shadcn or Radix will outperform a bespoke design system that you're still finishing while your launch date passes. Get the thing in front of users first.
9. Don't Hardcode Configs
Use: .env + dotenv + secrets manager
Committing a secret to a public repo is a gift to a stranger you'll never meet. Leaks mean instant regret, potential data breaches & the kind of weekend you don't want. Use environment variables from day one. Use a secrets manager if you're handling anything sensitive at scale. This is non-negotiable.
10. Don't DIY File Uploads
Use: UploadThing / Cloudinary / S3
Multipart form handling, chunked uploads, progress tracking, file type validation, storage management - it's a lot. And it all needs to work on mobile, on slow connections & in the browser. UploadThing is brilliant if you're in a Next.js stack. Cloudinary if you need transformation. S3 if you need control. Just don't build the whole thing yourself.
11. Don't "Just Push to Main"
Use: GitHub Actions + Preview Deploys
Future you will be furious with present you if you never set this up. A basic CI pipeline that runs your tests & lint before merging costs about an hour to set up & saves potentially many hours of debugging broken production builds. Preview deploys mean you can share a link before merging. It's a better workflow full stop.
12. Don't Skip Performance Tools
Use: Lighthouse + Vercel Analytics
Slow apps don't convert. That's not an opinion, it's bounce rate data. Run Lighthouse on your routes, plug in Vercel Analytics & actually look at the Core Web Vitals. Performance is a feature - one that users feel even when they can't name it.
13. Don't Assume Users Understand Anything
Use: Onboarding flows + empty states
You built the thing, so you understand it completely. Your users don't. Empty states that say "No data yet" without telling someone what to do next are a conversion killer. Good onboarding & thoughtful empty states aren't nice-to-haves - they're the difference between a user who activates & one who churns on day one.
14. Don't Wait to Modularise
Use: Clean folder structure from day one
"I'll tidy this up later" is how you end up with a 600-line component, three files called utils.ts & a refactor that costs 10x what it would've if you'd just organised things properly at the start. Good folder structure doesn't slow you down - it's the foundation that lets you move fast without breaking things.
15. Don't Trust "I'll Remember This"
Use: README + Markdown files
You will not remember this. I don't care how obvious it seems right now - six months from now, past you will be a complete stranger. Document your decisions, your env variable names, your deployment process, your gotchas. Future you - or a collaborator - will be genuinely grateful.
The pattern across all of these is the same: use the right tool for the job, ship faster & save your problem-solving energy for the things only you can build.
