---
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?**