The jQuery Era
This story starts back in college. I took a web development class and got my first taste of building for the web. It was still the golden age of jQuery. HTML, CSS, and JavaScript in three separate files, linked together through classes. I hated it.
It was just tedious.
The instructor talked about the benefits of "separation of concerns," and I couldn't come up with a clever counterargument, so I let it go. But I wasn't convinced at all. I understood the philosophy of separating structure, style, and behavior. But jumping between three files just to change how a button looks—is that really "good design"? I didn't think so.
Meeting Vue.js
In my second year as a professional developer, I started doing frontend work seriously. It was Vue.js (v2).
I thought it was fantastic. Not because of reactivity or the virtual DOM or anything like that. It was the fact that HTML, CSS, and JavaScript lived in a single file. That alone made me happy.
I knew it. We never needed to split things into three files.
I liked Scoped CSS too. That massive, deeply nested, fundamentally unmaintainable mess (or so I firmly believe) known as global CSS—I could finally leave it behind.
Moving to React
It didn't take long to learn that Vue, as great as it was, wasn't the global market leader.
React was.
JSX, the newly introduced Function Components, Hooks—these new concepts intimidated me a bit, but I figured I'd give it a shot and see what the fuss was about.
It was fantastic. A sense of unity I'd never experienced before.
The rule that Hooks must be called in the same order every time made me think, "How is this design even allowed?" But the elegance of building small, focused components and reusing them everywhere genuinely moved me. CSS-in-JS had its critics, but I personally liked it.
At the end of the day, I just want everything about a component to live in one file.
The Redux Cloud
The winds shifted when Redux entered the picture.
Absurdly long, incomprehensible boilerplate. Countless restrictions I can barely remember now. I struggled through it all, thinking, "This is not the development experience I signed up for."
But Redux was the standard back then. Everywhere I went, it was "we use Redux." That's when I started hating frontend development again. When job hunting, I began avoiding frontend roles and prioritizing backend work. It started around this time.
The Pain Eased, But
When useContext came along, the pain eased a bit. The era of Redux dominance was coming to an end.
But I still couldn't bring myself to like frontend.
The boilerplate was disappearing. That wasn't the problem. Data and logic were merging with components—components that should be nothing more than a View layer for display. That bothered me.
Sure, most pages just render whatever the backend returns, so it's not a big deal. But that's exactly why, when you build complex features on top of that foundation, it's so easy to end up writing data management and business logic directly inside components.
Tailwind CSS: A Ray of Light
When Tailwind CSS came out, I was genuinely excited.
CSS, Sass, PostCSS, Vue Scoped CSS, CSS-in-JS. After all that wandering, I thought, "Finally, the right answer." Yes, classes tend to get long. But compared to CSS finally being manageable, that's not a problem at all.
I Still Avoid Frontend
Even now, I tend to avoid frontend work.
The reason is simple: there are too many traps.
Are they using Redux? Are they using something other than Tailwind for CSS? In complex features, is the logic tightly coupled with the view? Is the codebase stuck in an eternal transition period where all of the above coexist? Most of the time, you don't find out until you're already on the project. And more importantly, I'm the type of person who feels real pain when I encounter these problems.
Of course, you could say "just fix it." But the key decision-makers might not agree with my views, and there might not be time allocated for refactoring.
Backend, on the other hand, still feels relatively civilized.
There are traps there too—over-engineered layered architecture, raw SQL everywhere, DDD enthusiasts, homegrown framework advocates. By the way, when it comes to DDD, I agree with the domain modeling philosophy in the first half of the book, but I don't agree with the technical implementation patterns in the second half.
But backend traps are easier to spot in advance. Frontend traps require careful probing to uncover, while backend issues are relatively easy to assess. On top of that, Rails—my main battlefield—tends to be less accident-prone.
So honestly, I haven't had the courage to join a team focused primarily on frontend. If I'm going to do it, I need at least a full-stack environment where I can touch the backend too. That's been my honest take for years now.
That said, I do think the AI era might change things.
Shameless plug: I'm building Pockode—code with Claude Code on your home PC from your phone.
Original text: https://sijiaoh.com/en/posts/why-i-avoid-frontend/
Top comments (1)
Thank you for sharing your experience!
As a backend engineer currently learning React, I found your post very interesting.