Build Your Own
When CGI was king, the concept of a framework was barely born.
Writing the GET and POST encoding logic inside your CGI script was ritual. Check the Content-Type, decode the parameters, handle multipart. The same code, every time. Naturally you wanted to share it. You had no choice but to build a framework. There was nothing else.
Engineers today almost never write their own framework. Not unless they've made peace with the consequences.
At some point CGI on httpd fell out of fashion, gave way to mod_perl, and then frameworks began embedding httpd itself. Around this time, multicore characteristics of languages started becoming a real problem. Process model to thread model to async I/O. The surface area a framework had to cover kept expanding.
I built several of my own. Every time a new framework appeared, I'd cherry-pick the good parts and stitch together a chimera. Reinventing the wheel, sure. But designing a car without knowing what a wheel is made of felt worse.
Modern web frameworks hide an astonishing amount. Routing, middleware, template engines, ORMs, session management. TypeScript hides the transpilation to JavaScript. Next.js hides the boundary between server and client. Stay on the rails and the app runs without you ever knowing what's underneath.
The moment you step off the rails, everything that was hidden bares its teeth. The HTTP spec. Socket behavior. Character encoding traps. Process lifecycles. The world outside the framework's protection is no different from the CGI era.
Building those chimeras back then is why I stopped being afraid to look under the rails. Good era to have started in. Ask me to do it again and I'll pass.