--- layout: "@/layouts/BlogPostLayout.astro" title: "All This Tinkering... For What? Engineering Reflections from a Full-Stack Developer" description: "An honest reflection on tech stack selection paralysis. One developer's journey from chasing 'best practices' to realizing that technology is a tool, not a totem—how to avoid over-engineering and find the right fit for your actual needs." date: "2026-01-08" image: "https://images.unsplash.com/photo-1518770660439-4636190af475?q=80&w=1470&auto=format&fit=crop" tags: ["Reflections", "Full-Stack", "Engineering", "Personal Reflection"] tagId: ["reflections", "fullstack", "engineering", "development-reflection"] category: "Engineering" categoryId: "engineering" readTime: "8 min read" --- > *A log of the soul-crushing details I encountered during a recent project setup. This is a summary of my own internal tug-of-war—lessons learned the hard way through endless trial and error. It might not be the "correct" way, but every word was paid for in lost time.* I recently set out to build a simple bookmarking tool. It only needed about 30 endpoints, yet I spent nearly a month agonizing over the tech stack. I felt like I was wandering through a dark forest, sprinting toward every glimmer of light only to find a new pitfall waiting for me. ### Step 1: Chasing the "Mainstream" and Feeling the Friction It started because I wanted to build a side project. In my day job, I use Vue; it’s second nature to me. But everywhere I looked online, the consensus was: **"Next.js + React + shadcn-ui"** is the gold standard. Great ecosystem, endless components, future-proof. I told myself: *Don’t get stuck in your comfort zone. Try something new.* So, I benched Vue and picked up React. I was immediately hit by **choice paralysis.** It wasn't just a choice between A and B; it was a choice between five different ways to do everything. I spent more time reading docs and comparisons than writing logic: * Do I fetch data with **SWR** or **TanStack Query**? * Is global state better in **Zustand**, **Redux**, or **Jotai**? * How do I bridge the gap between server and client data? Instead of building features, I was researching "how to build." To make matters worse, I kept hitting those cryptic **"Hydration Errors."** One refresh, one error, and an hour gone trying to find the mismatch. The most draining part was tagging everything with `"use client"`. I felt less like a developer and more like a clerk labeling boxes. I kept thinking: **"If most of this ends up running on the client anyway, why am I using a framework that splits the stack so aggressively and demands such high mental overhead?"** ### Step 2: Retreating to Comfort—and the Fear of Missing Out I went back to my familiar Vue ecosystem and fired up Nuxt. Suddenly, I could breathe. My productivity skyrocketed. But the peace didn't last. I’d see another post praising the Next.js ecosystem and start doubting myself: **"Am I choosing the wrong path? Am I falling behind?"** I gave Next.js another shot for a few days, and like clockwork, all those petty, nagging frustrations returned. That’s when I realized: **Tech isn't about "better" or "worse"; it’s about fit.** Trust your "handfeel." That sense of flow (or lack thereof) doesn't lie. ### Step 3: The "Professionalism" Trap Once the frontend was settled, I moved to the backend. I chose **NestJS** because it’s billed as the most "Enterprise-grade" option. To make it even more "professional," I forced it into a **Monorepo**. I effectively built myself a prison: * **Immense Friction:** Changing a single shared enum or type meant re-building, waiting for workspace syncs, and restarting services. A 10-second change turned into a 1-minute wait. * **Compatibility Hell:** NestJS is still clinging to CommonJS. Trying to use a pure ESM library or running a TS Worker thread resulted in config errors that made me question my career choices. * **Ceremony Over Substance:** For 30 endpoints, I was writing endless Controllers, Services, Modules, and DTOs. The lines of code tripled, but the core logic stayed exactly the same. * **The Swagger Tax:** I wanted to use Zod for validation, but Swagger only recognizes decorators (class-validator). I ended up maintaining two nearly identical data definitions just to have an API doc. **I traded my immediate efficiency for the "advantages of a large team" that I don't actually have.** I wanted speed; the framework demanded "maintainability" for a scale I'll likely never hit. ### Step 4: Stripping it Down and Losing My Way I ditched the heavy frameworks for **Fastify**, thinking I’d keep it lean. But I quickly discovered that the problem wasn't just "weight"—it was **"the anxiety of absolute freedom."** Fastify is liberating, but for someone used to structure, freedom is a burden: * "Where should this file go?" * "How do I organize this into a plugin?" * Logging, queues, auth—everything NestJS gave me for free now required me to find, integrate, and debug a third-party library. I hated the rules of heavy frameworks, yet I craved their structure. My mindset was completely torn. ### The Epiphany: Tech is a Tool, Not a Totem One night, working late, I asked myself: **"Why am I doing this? I just wanted to build a simple tool."** Everything clicked. I was applying "Long-term Enterprise Maintenance" standards to a "Solo Rapid Prototype." It was like trying to build an eight-lane highway just to go to the grocery store around the corner. I set a new, simple rule for myself: 1. **For Prototypes & Small Tools:** Use **Nuxt (or a monolithic framework) exclusively.** Frontend and backend in one repo, natural type synchronization, no CORS issues, no sync friction. The goal is to *ship*. 2. **For Complex Systems & Large Teams:** *Then* consider **Nuxt + NestJS + Monorepo.** The complexity is a fair trade for the architectural guardrails. ### A New Contender: AdonisJS During this spiral, I stumbled upon **AdonisJS**. It’s often called the "Laravel of Node.js." From a quick look, it seems to hit the sweet spot: it has the structure I crave (ORM and Auth built-in) but feels modern and supports ESM natively. I might give it a spin next time. ### Final Thoughts 1. **Don’t blind-follow the hype:** What works for Vercel might not work for your weekend project. 2. **Trust your "handfeel":** If a tool makes you feel productive, that's worth more than any "State of JS" ranking. 3. **Ship first, optimize later:** For a solo project, an un-launched architecture is just expensive fan fiction. 4. **Watch out for "Config Friction":** If you spend more time in `.json` and `.config.js` files than in your logic, your tools are failing you. This was my journey through the weeds. **My approach might be "wrong" or even a bit clumsy.** I’d love to hear how you handle the "stack anxiety." **Do you have a go-to setup that just works, or are you still searching for the "perfect" balance?**