Top
Best
New

Posted by Bogdanp 9/2/2025

Next.js is infuriating(blog.meca.sh)
1026 points | 578 comments
YuukiRey 9/2/2025|
I 100% agree. I've ran into the same issues, and I would never use Next.js for anything, and I will encourage every team at work to use something else.

In general Next.js has so many layers of abstraction that 99.9999% of projects don't need. And the ones that do are probably better off building a bespoke solution from lower level parts.

Next.js is easily the worst technology I've ever used.

throwaway77385 9/2/2025||
I'm so glad I'm not the only one thinking this. I built a medium-complexity, money-making, production-grade app in Next.js and started out on Vercel's hosting (and Google Firebase) and then moved to hosting myself and stripping out Firebase, replacing it with Pocketbase.

Pocketbase was the ONLY good thing about this journey. Everything else sucked just so terribly.

Infinite complexity everywhere, breaking changes CONSTANTLY, impenetrable documentation everywhere.

It is just so, so awful. If we rewound the last five years of FE trends and instead focused on teaching the stuff that existed at the time properly, we'd be in a much better position.

I've also built a very complex React frontend (few thousand users, pretty heavy visual computation required in many places). And while I don't particularly like React either, Next.js was even worse.

And lastly, built a CMS in Go, with vanilla JS. And while the DX sometimes feels lacking, I just can't help but feel that I actually know wtf is going to happen when I do something. Why is that so hard?

In React and Next.js I am STILL, AFTER SIX YEARS constantly guessing what might happen. Yes, I can fix just about anything these frameworks throw at me, thanks to all the experience I've gathered about their quirks, but it all just feels to messy and badly designed.

In Go, the last time I guessed what might happen was in the first six months of learning it. No surprises since. Codebases from years ago are still rock-solid.

Why can't we do this at the frontend, goddammit?

fourseventy 9/2/2025|||
" Codebases from years ago are still rock-solid." This is the biggest thing for me. I recently pulled down an 8 year old hobby Java/Maven project I had and it compiled and ran perfectly on the first try. Imagine trying to get an 8 year old javascript project to work...
port11 9/3/2025|||
At my previous startup (co-founder who made all technical decisions) we were unfortunately stuck with React Native. I had Mondays that started with the project not building after some dependency changes. Imagine something failing to build 3 days after you've last touched the codebase…
c-hendricks 9/2/2025||||
Just did, I installed the version of node specified somewhere, codified it into mise, and was up and running in no time.
elbrian 9/3/2025||||
You mean like this?

nvm use && npm i && npm run dev

Aeolun 9/3/2025|||
Does NPM work for you in the first place? Much less after 5 years? They’ll have gone through 2 major revisions on their lock file format, and it’ll complain you don’t have the exact version of node specified in your package.json
parasti 9/3/2025||||
Oops, one of the dependencies is a C++ library that doesn't compile on your less-than-five-years old arch.
vrighter 9/3/2025||||
That only works if the project is constantly maintained. Otherwise it can and will break in time.
chipsrafferty 9/3/2025|||
Ok, 50 packages have critical vulnerabilities now
techpression 9/3/2025||
And another 30 didn't use versioning correctly so they installed new dependencies of their own that broke things three levels deep. Yes, based on a true story.
fatata123 9/2/2025|||
[dead]
ecshafer 9/2/2025||||
I think the big complex FE frameworks are going to go away. After doing work with HTMX and Alpine JS, and Ruby on Rails with Turbo + Stimulus, I am all in on this paradigm. Basic JS, or a micro front end framework is all you really need.
tankenmate 9/2/2025|||
it might be a bit over the top but there is Cogent Core[0]; it supports apps on desktop, mobile apps, and the web. it even supports 2d and 3d. and it's all in go, backend and frontend (using WASM).

[0] https://github.com/cogentcore/core

Voultapher 9/2/2025|||
As much as I hate Next.js as the next guy, let's please not push full canvas rendering approaches. They SUCK. Their https://www.cogentcore.org/core/ own site is slow to load, scrolling is visually painful since it render at what I assume is 60Hz and not my native much higher monitor refresh rate. They are expensive in terms of computation, wasting resources on the machine, to display text. Want to select text, better hope the developers want you to be able to select text or didn't forget to do so, case in point text inside buttons. Accessibility is also usually much weaker, screen readers often suffer and if they don't something else will.

Canvas instead of DOM -> :(

EDIT: Gave it another try and more issues appear, within seconds of using. The left side has a rendering bug where the selected areas are cut off sometimes, ctrl+zoom does not zoom the page as it does on all normal websites. I can still zoom via menu. Middle mouse open link in new tab doesn't work. Z layer bugs everywhere. I expect more the longer I'd look.

manchmalscott 9/3/2025||
Oh my god, I thought you were exaggerating at least a little.

The “static preview” it shows while it loads (for like 10-15 seconds!) is so much smoother and nicer to scroll around than the actual thing. On mobile, every third scroll attempt actually opens the right click context menu. It’s a stuttering mess on my high refresh rate phone. Nobody should ever make websites like this.

blinkbat 9/2/2025||||
wow this is bad! like truly bad UX. please don't recommend this.
agent327 9/2/2025||||
I typed "0" into the scaling field to see how it handled it, and couldn't recover from there...
chipsrafferty 9/3/2025|||
it's completely shit
jbreckmckye 9/2/2025|||
My experience with Next.js are that its rough edges are a feature, not a bug. Everything is geared towards you giving up and just using Vercel's hosting
a2tech 9/2/2025|||
Working with a client just last month that hired an African engineering group to build a tool for them. What they got delivered was a Next.js train wreck that was so coupled to Vercel's hosting that I couldn't make it run successfully anywhere else. The customer was a non-profit and didn't want to/couldn't afford Vercel's hosting so asked if I could try and make it run and I (naively) thought 'its just javascript, it should run anywhere!' and I took a run at it.

After a week of futzing with it I just threw up my hands and said 'no can do'. I couldn't untangle the spaghetti JS and piles of libraries. 'Compiling' would complete and if you looked at the output it was clearly missing tons of bits but never threw an error. Just tons of weirdness from the toolchain to the deployment platform.

Kye 9/2/2025|||
I haven't heard anything about trends, stereotypes, positives, and negatives regarding IT and development in Africa. Following HN's guideline to increase curiosity as topics get more divisive (as this subthread has), and looking for "the strongest plausible interpretation of what someone says" I'm going to assume the best:

What's the story here? I assume this group was chosen for a reason and didn't meet expectations.

a2tech 9/2/2025|||
The non-profit works in Africa and is all about using local resources when at all possible. They knew some people that worked with a group out of Nairobi that talked a good game and they liked the people they met and the non-profit folks are NOT technical, they jumped on it. It's a classic story really--I've been on this side of the table many times before with outsourced work.

If they had brought me in before hand I could have saved them a lot of work by asking the hard questions and reigning in the tech overspend.

arcfour 9/2/2025||
"We don't know a lot about this, what could go wrong?!" Sigh...
a2tech 9/2/2025|||
They're sweet well meaning people. They're very familiar with the realities of working in Africa, but they always assume people will try and do the right thing at the end of the day.
BobaFloutist 9/2/2025|||
"We don't know a lot about this, let's hire some experts to handle it for us"
snickerdoodle12 9/2/2025||||
Why accept the result? Send it back and have them deliver something usable.
a2tech 9/2/2025||
It was running when they accepted it. However they didn't realize that the group was running the Django/Postgres 'backend' on a managed Digital Ocean instance, then there were two different Vercel 'projects'. It was costing hundreds and hundreds of dollars a month to run for a project that was VERY lightly used.

They paid them on the strength of seeing it working, but then the consulting group basically ghosted when the customer asked to adjust it to run on cheaper hosting (probably because they couldn't), then the site got shut off because the hosting was all in the consulting groups name and they stopped paying it. Digital Ocean nuked the database for non-payment and they lost tons and tons of manual work putting in data.

snickerdoodle12 9/2/2025||
Damn, what a horror story
a2tech 9/2/2025||
I felt really bad for them. They're super nice people and I don't think the contractors set out to take advantage of them, it ended up being an bad experience for everyone.
_kblcuk_ 9/2/2025|||
[flagged]
dkarl 9/2/2025|||
When I read "African engineering group" I felt an instant "ugh" of recognition, based on my experience with software created by external consultants on other continents. My experiences were with groups in Asia and Europe, not Africa, so I think what the poster successfully evoked was the experience of dealing with differences of distance, culture, time zone, and commercial interest (engineers answerable to different management and a different bottom line,) all of which tend to produce inferior software compared to what gets produced for in-house use or sale in the SaaS market.
a2tech 9/2/2025||
Exactly--bad work can be from anywhere. However working with contractors at this kind of distance, through a language barrier, with different societal norms (for example, the US project manager was a woman, and the programmers just completely ignored things she said. If myself or another man was present, they completely changed their tone and would immediately act on things we said. Our project manager was pretty much ignored or steam rolled at every turn) is extremely difficult.
snickerdoodle12 9/2/2025||||
Yup, we do. Mind you, I'm not an american. But we often say something like "the americans" or other less flattering terms.
throwaway2562 9/2/2025|||
Here come the police, ever-vigilant for perceived or potential slights. Bless you, Officer.
chamomeal 9/2/2025||||
Fun anecdote: last time I needed to build a quick full stack app for a silly little project that my friend needed, I thought “it only needs to be up for a few months, so I’ll just use the next.js starter and throw it on vercel and be done”. I’d used vercel + next once before and thought it was easy.

Open up vercel, point it at my repo, and environment variable, it starts building and… build error. I search up the strange error log on the next issues page, and find a single issue from 3 years ago with one upvote and no response or resolution.

So I threw it on a VPS and just built it with whatever the “prod build” command is, and it totally worked fine.

So in my limited anecdotal experience, hosting it on vercel won’t save you either lol

motorest 9/2/2025||||
> My experience with Next.js are that its rough edges are a feature, not a bug. Everything is geared towards you giving up and just using Vercel's hosting

That is my opinion as well. Things like SSR are forced onto users with a very smooth onboarding, but I'm concerned that in practical terms this perceived smoothness can only persist if the likes of us pay the likes of Vercel for hosting our work.

In some degree I feel the whole React ecosystem might have ended up being captured by a corporation. Hopefully it wasn't. Let's see.

WD-42 9/2/2025|||
It’s already been captured. Check out the docs for creating a new React app on react.dev:

https://react.dev/learn/creating-a-react-app

It throws you straight at Next.js

jbreckmckye 9/2/2025||||
Might have? The official React docs recommend Next.

That capture happened... two years ago? (Perhaps there's a good blog post there, if it doesn't exist already)

acemarke 9/2/2025|||
Hi! I maintain Redux and am deeply involved in the React community, and have spent a lot of time both critiquing the React team's decisions and explaining their decisions to the community.

I actually wrote exactly that blog post and did a conf talk on it earlier this year. I covered why the React team switched to directing users to use "frameworks" to build React apps, the development influences behind React Server Components, why the React docs didn't list tools like Vite as viable options until just a couple months ago, and various other related topics:

- https://blog.isquaredsoftware.com/2025/06/react-community-20...

- https://blog.isquaredsoftware.com/2025/06/presentations-reac...

seattle_spring 9/3/2025||
Thank you for the writeups. I learned a lot reading those.
Silhouette 9/2/2025|||
Yes - there's been a very obvious shift in the "official" React positions over the last 2-3 years. It's regrettable that they have moved so sharply away from the simplicity and "doing one thing well" philosophy that made React so successful in the first place. I've used React since those early days and built successful, long-lived projects with it so I'm genuinely sad to see it fall so hard.

Objectively that sadness does not change reality however. At least within my own professional network no-one seems comfortable starting a new project using React today. Almost 100% of the paid front end work I've been involved with myself or discussed with others recently is now using alternatives - most often Vue though I've seen other choices at least seriously considered. I've even had a couple of recruiters I haven't worked with for years suddenly reappear desperately looking for someone to take on React work and openly admit it's because they are struggling to find anyone good who wants to go near it. All of this is a sharp contrast with the market of the early 2020s when React was clearly the preferred front end choice. And all of this is surely a direct response to the push to make React a full stack framework, the added complexity that has introduced, and the apparent capture of official React development by Vercel.

lubujackson 9/2/2025|||
Looking at history, many popular frameworks have been "captured by a corporation" or in the case of React (FB) and .NET (MS), created by one. We mere SEs ride the wave of corporate whims, but everyone knows if and when they tighten the noose too hard everyone will move on to the next hot new thing.
Imustaskforhelp 9/2/2025||||
Which is why I actually love sveltekit considering that its really easy to self host it / host it anywhere serverless. I hosted it on cloudflare. Though I do feel that everyone is pushing nextjs in the llm space and llm's are more comfortable with next instead of sveltekit but they can still do some mind boggling things in sveltekit and I love them while using sveltekit itself
tommica 9/2/2025||
Svelte is financed by vercel, so who knows if sveltekit drifts in the same direction.
Imustaskforhelp 9/2/2025|||
Yes I know but the way I see sveltekit is that there are adapters for cloudflare etc. and I doubt how sveltekit can drift into such direction without immense blacklash

I don't know much about the nextjs and whether it was open like sveltekit currently is.

To me, nextjs (I think) was always meant to favour vercel but sveltekit has a rich history of managing multiple adapters.

Now, that being said there are still some chances of a rugpull that might happen but if that ever happens, I am staying on the last sveltekit that worked with cf and other cloud providers.

benmccann 9/2/2025|||
Only 3/40 Svelte maintainers work at Vercel and they mainly finance work on Svelte core. SvelteKit day-to-day is primarily maintained by folks outside Vercel
gigatree 9/2/2025||
A little disingenuous to say “only 3/40” maintainers. Which 3? And how percentage of the total work hours invested per month do those 3 represent?
benmccann 9/2/2025||
The number 3, 4, and 5 contributors to SvelteKit in the past year work at Vercel: https://github.com/sveltejs/kit/graphs/contributors?from=8%2...

Rich and Simon are incredibly important, but they're in it for Svelte and the community more so than a paycheck from Vercel. Tee has been doing most of the maintenance on SvelteKit currently funded by community donations. And this isn't counting other infrastructure like vite-plugin-svelte or the Svelte CLI which are entirely maintained by volunteers. I don't think Vercel funds a majority of the work on Svelte even if it might be close to it.

emn13 9/2/2025||||
The author's examples of rough edges are however no better when hosted on vercel. The architecture seems... overly clever, leading to all kinds of issues.

I'm sure commercial incentives would lead issues that affect paying (hosted) customers to have better resolutions than those self-hosting, but that's not enough to explain this level of pain, especially not in issues that would affect paying customers just as much.

jbreckmckye 9/2/2025||
I agree, but I suspect the cleverness is part proprietary behaviour, part having a monstrosity that only runs as intended on their own infra
taneq 9/2/2025||||
I feel like that describes a whole bunch of "FOSS-project-backed-by-consulting-company" packages. You want it to be good enough to become industry standard, but painful enough to figure out on your own that anyone with the budget will just pay the developer to do it for them.
hoppp 9/2/2025||||
Same. Feels like it's a lure into a vendor lock

Better use something else

Aurornis 9/2/2025||||
Not a web developer, but I do small web projects from time to time.

I heard this excuse for Next.js and thought I’d get around it by using Vercel, which was fine for my project. It didn’t seem to make a difference.

leric 9/3/2025|||
[dead]
motorest 9/2/2025|||
> I 100% agree. I've ran into the same issues, and I would never use Next.js for anything, and I will encourage every team at work to use something else.

Things will get far worse before they get better. Right now, online courses such as the ones in PluralSight are pushing Next.js on virtually all courses related to React. I have no idea what ill-advised train of thought resulted in this sad state of affairs but here we are.

felipeccastro 9/2/2025||
The train of thought is “what is everyone using? I’ll use that too”
koonsolo 9/2/2025|||
This coupled with the fact that "web development" now means anything going from a content rich website like a blog, towards some e-shop, all the way to complex applications like ux design, video editing, etc.

It's pretty absurd to have such a broad range of web solutions, and think the same solution can cover everything.

fragmede 9/2/2025||
Why? Microsoft's GUI framework as well as Apple's covered plenty of use cases before the rise of the web browser.
koonsolo 9/2/2025||
Then why did HTML became so popular if win32 or MFC were so great?
motorest 9/3/2025|||
> Then why did HTML became so popular if win32 or MFC were so great?

One of the factors is that web dev pushes for a complete separation of concerns, and thus allows frontend developers to specialize in front end development. Therefore it becomes far easier to hire someone to do frontend work with a webdev background than a win32/MFC background.

Number of applicants is also a big factor. There is far more demand for webdev than pure GUI programming. You can only hire people who show up, and if no one shows up then you need to scramble.

Frontend development is also by far the most expensive part of a project. In projects which use low-level native frameworks you are forced to hire a team for each target platform. Adopting technologies that implement GUIs with webpages running in a WebView allow projects to halve the cost. This is also why technologies like React Native shine.

Also, apps like Visual Studio Code prove that webview-based apps can be both nice to look at and be performant.

It's not capabilities. It's mainly the economics.

koonsolo 9/3/2025||
In the win32/MFC days, there was no "front-end developer". There was only HTML and content creators writing it.

Then there came small web applications, and still no "front-end developers", since functionality could only work on the server.

It's only when AJAX was introduced in the mid 2000's that you could start to talk about "front-end developers".

By that time, win32 and MFC was old. We had Java, C# with .net framework, etc.

fragmede 9/2/2025|||
Because it solved different problems. CSS is terrible, but deployment simplicity and distribution channel were more powerful than how shitty HTML is for making GUIs. The fact that MFC was owned by Microsoft didn't help either.
koonsolo 9/2/2025||
Why would you make GUI's with HTML? Its main use was for content, not applications. Hyper Text Markup Language.

So you agree both solve different problems. Well, those are 2 use cases of front-end right now.

motorest 9/2/2025||||
> The train of thought is “what is everyone using? I’ll use that too”

I'm not so sure about that. We're seeing Next.js being pushed as the successor of create-react-app even in react.dev[1], which as a premise is kind of stupid. There is something wrong definitely going on.

[1] https://react.dev/learn/creating-a-react-app

whstl 9/2/2025|||
It was interesting handling frontend interviews recently.

We do a 30-min tops exercise where you create a React project to show how to use useState and useEffect, etc. I help with whatever command they want to use and allow Google/ChatGPT.

More than half of the candidates had no idea how to use React without Next.js, and some argued it was impossible, even after I told them the opposite.

nikole9696 9/2/2025|||
This surprises me a lot. I spin up new react apps with vite often to replicate issues with 3rd party libs we use. Like how do they not know you can just spin something up over on CodePen or CodeSandbox and there's not a hint of a server side paradigm required? (sure, vite has a little server but you don't really need to know anything about it)
whstl 9/2/2025||
Some devs have worked exclusively in feature mills where expectations are rock bottom and some senior setups the project for them. When recruiters don't filter them, a basic React test has to.
fragmede 9/2/2025|||
What are you really testing for? That sounds like a bad interview.
recursive 9/2/2025||
Basic react experience presumably. As a first approximation, it seems like every possible interview sounds like a bad interview to someone. What has worked well for you?
fragmede 9/2/2025||
Seems more like a test on random React minutiae. Like, let's take some framework, take away some random piece. How well do you know the area around that random piece we just removed? Frameworks are large and gnarly (or there isn't enough to them). Expecting a candidate to be lucky and know random implementation details in the area that happened to be picked doesn't seem like you'd select for anything other than luck.

For me, lately, the interview question is "here's code that ChatGPT generated for (previous interview question as related to the role we're hiring for that we could do)", what's wrong with it? What do now? (ChatGPT may or may not have actually generated the code in question.)

chipsrafferty 9/3/2025|||
It's not React "minutiae". It's incredibly basic concepts, that if you don't know, you cannot in good faith say you know react.

It's like not knowing how to write a for loop or how to access an object's property in JavaScript.

seattle_spring 9/3/2025||
I remember one of the first technical interviews I conducted about 15 years ago, I asked the candidate the difference between == and ===. She had the same answer as gp, claiming the doesn't "memorize minutiae like that."
9rx 9/2/2025||||
> Seems more like a test on random React minutiae.

It is more like test on whether or not you can figure out random React minutiae (with Google/ChatGPT, if needed) when presented with a need. Which isn't a bad approximation for how well you will do at finding any random minutiae as needs present themselves. React-based development doesn't require much original thought — the vast majority of the job really is just figuring out the minutiae of your dependencies to fit your circumstantial need.

For fun, I asked ChatGPT for an answer and it gave a perfectly good one back without hesitation. Even if you had no idea what React was beyond knowing it is a library for developing web components, you should still be able to answer that particular question with ease.

fragmede 9/2/2025||
I was assuming that particular interview was not open ChatGPT. If all you want to test for is can you understand the words that are coming out of my mouth, type that into ChatGPT, and then read it to me, yeah, it seems fine.
9rx 9/2/2025|||
Why would one random part of the interview disallow ChatGPT when it is otherwise accepted for answering other random React minutiae?
fragmede 9/2/2025||
Because humans have to interact with other humans in conversations, and if you can't read social cues as to when something is and isn't acceptable, you're boned. I have trouble with that, so it's not surprising to me when others do as well.

When you're in a work meeting, do you just put ChatGPT up on one laptop and Claude on another and just sit back for 30 minutes to an hour?

9rx 9/2/2025||
It was deemed acceptable to use ChatGPT to discover the minutiae of useState and useEffect. What is special about createRoot that makes it off limits?
whstl 9/2/2025|||
The most basic React functionality isn't "React minutiae".
hungryhobbit 9/2/2025|||
You have to remember, Next is the only framework that can support some of the features in the latest version of React.

To many people, it's just basic logic: "everyone must want the latest React features, and the only way to get those is with Next, so everyone must want Next".

johnnypangs 9/2/2025|||
Vite is coming along with rsc at least. https://github.com/vitejs/vite-plugin-react/tree/main/packag...
motorest 9/2/2025|||
> You have to remember, Next is the only framework that can support some of the features in the latest version of React.

That is extremely fishy, isn't it?

hombre_fatal 9/2/2025||
Not necessarily since they have to do with the inherently complex niche features like unified server/client rendering (e.g. RSC, streaming SSR with selective hydration, server actions).

Next.js is essentially the reference and test bed impl.

Where people go wrong is thinking they need to default to the inherently complex niche feature of client hydration which is a niche optimization enabled by a quirk of web tech.

motorest 9/2/2025||
> Not necessarily since they have to do with the inherently complex niche features like unified server/client rendering (...)

My point is that it's fishy how they push features that just so happen to be the value proposition of the only corporation that just so happens to be able to implement them.

gigatree 9/2/2025||||
If everyone made decisions for themselves instead of following everyone else we’d be so much better off, in all areas.
nightski 9/2/2025||
This is a little disingenuous because unfortunately you can't make decisions on technical merits alone. It takes a lot of resources to keep these projects thriving and up to date. You almost have to go with options where these resources have been deployed, even if they are terrible sometimes.
port11 9/3/2025|||
This is only partially true. For example, with React Native even the core team now tells you to "just use Expo", as if relegating all responsibility to a project maintained by a for-profit that thinks 2 weeks is enough time to beta test a Major release.

It's also dismissive of market forces, i.e. developers have to pay bills and therefore are easier to hire if they know the skillset that is in wide use.

I've never worked or interviewed a single senior that wanted to use Next.

christophilus 9/2/2025|||
Second worst for me. I’ve used Sharepoint.
mcny 9/2/2025|||
Third worst if you have used Lotus Notes mail. I still don't understand how an email and calendar client can slow down a computer like that (going by memory, the last time I used it was at work in 2013 so pre-SSD days).
nailer 9/2/2025|||
Everyone at IBM when I worked where used Fetchnotes (internal tool that leaked onto the internet that wraps Lotus notes .so file and allows you to use normal email / contact / calendaring programs and formats).
marcosdumay 9/2/2025||||
Well... I don't know exactly what the OP meant by "technology", but Notes at least wasn't supposed to be a development platform.

It surely was a development platform, but wasn't supposed to be one.

YuukiRey 9/2/2025||
I should have been more specific here indeed. I meant more library or framework, not technology in the broader sense. My apologies.
codegeek 9/2/2025|||
You just reminded me of the nightmare Lotus Notes was.
Etheryte 9/2/2025||||
What do you mean you don't want to step through scripts with a debugger just to understand how to use the official APIs? I'm sure it's better these days, but Sharepoint was one of the platforms I worked with when I was younger and it still gives me bad flashbacks whenever it comes up.
jermaustin1 9/2/2025||
I remember a few early projects that revolved around SP, but one that stands out as "special" was using the SOAP APIs to update a WordPress site. It was a special hell, every hour it would fetch any updates, and push them to the specific WP content-type (iirc - content-types might not have existed yet - this was 2008).

The reason for this, IT had contracted for a content management system from a Microsoft shop, because the CIO was a former Accenture/Avanade consultant. But the brochure-ware website had already been contracted to some random NYC-based web firm, but the CIO didn't want multiple usernames/passwords, so after the WordPress site hand been build, they hired the SharePoint consultants to build out the CMS that the employees would use, but it still didn't hook up to wordpress, so then it became another contractor's job (me) to join the two.

I had worked on Word Press, I even had a few decently popular plugins, but I had never seen the absolute hellscape that was SharePoint before. I wrote a codegen tool that would read the WSDL and create a library with all the classes and calls needed to use it without any SharePoint experience, and wrote some simple ETLs for the handful of "buckets". It was a 2-3 month long journey, but those libraries and my code are still in place today, where they still use wordpress for front-end, and sharepoint as backend (or at least did in 2022 still, the last I talked to anyone still working there).

hinkley 9/3/2025||||
Some people get my hatred for Teams, and some people don't. Most of the ones who do had to use Sharepoint at some point, and can see its pointy little horns sticking out of Teams.
rhubarbtree 9/2/2025||||
No one will understand until they’ve seen it with their own eyes.
VenturingVole 9/2/2025||||
You have my sympathy.
Sohcahtoa82 9/2/2025|||
To me, Sharepoint feels like it's not sure what it's supposed to be, so it tries to be everything, and so feature creep has run so rampant that it's just an utter mess with awful performance.
christophilus 9/2/2025||
To me, Sharepoint feels like it was vibe coded by the first primitive coding agent, and then made worse over time.
rozenmd 9/2/2025|||
I've been running a SaaS on Next.js + GraphQL for 4.5 years now, sticking to Pages router has eliminated most of the complexity.

I recently rewrote my auth to use better-auth (as a separate service), which has allowed me to start moving entirely off Next.js (looking at either React Router 7 or Tanstack Router).

Back when I started, Next.js made server side rendering incredibly easy, but it turns out I didn't need it. My marketing site is entirely static, and my app is entirely client rendered.

bodhi_mind 9/2/2025|||
I also use next and use the pages router. Makes for a development friendly react front end.

And I have some use cases where I want to have a headless crm/api “hidden” behind the front end. So in these cases using next as a backend proxy works well for me.

rustystump 9/2/2025||||
I regret “upgrading” my personal site to app router. Big mistake esp for is an almost purely static site.

Sadly tan stacks releases a new version every other day and react router was complete 5 versions ago but cannot seem to keep changing the api to stay relevant in the never ending js relevancy ending war.

16mb 9/2/2025||||
I would recommend React Router over Tanstack. I tried both and RR was so much easier and more reliable.

Tanstack seems to be following Next.js in that they’re just over complicating everything and their docs felt lacking for the most of their features.

eYrKEC2 9/2/2025||
I've only ever used Tan's React-Query and I absolutely love it inside of a React codebase.

https://tanstack.com/query/v5/docs/framework/react/overview

fragmede 9/2/2025|||
Why're trying to move off next? What makes the opportunity cost worth it?
rozenmd 9/2/2025||
Looking for full control over where the frontend is hosted. Sure, I can run Next.js elsewhere, but I could also run React Router elsewhere and have a much better overall experience in the process.
fragmede 9/4/2025||
Hm could you explain further? Why is React Router going to lead to a better experience?
rozenmd 9/5/2025||
You don't understand why being able to freely pick your vendors might lead to a better experience?
coffeefirst 9/2/2025|||
Yes, and even if you manage to work around its profoundly silly limitations—seriously who designed the new routing nonsense and have they ever made a website before—every time you go to upgrade the new version breaks everything.

By comparison, DIY SSR with Express takes a few days to get working and has run quietly for multiple projects for years on end.

berkes 9/2/2025|||
Many of the abstractions and nextjs tools do things that my OS does better, cleaner and more predictable too.

I suppose the overly complicated ENV/.env loading hierarchy is (partly) needed because Windows doesn't (didn't?) have ENV vars. Same for inotify, port detection, thread management: *nix does it well, consistent ish. But when you want an interface or feature that works on both *nix and windows, in the same way, you'll end up with next.js alike piles of reinvented wheels and abstractions (that in the end are always leaking anyway)

rcxdude 9/2/2025|||
>Windows doesn't (didn't?) have ENV vars

Nope, windows has had perfectly standard environment variables since the DOS days

colejohnson66 9/2/2025||
What's "missing" is the ability to launch things the "Bash" way: `KEY=value ./myApp`. Where the variable is scoped to the single execution.

Windows' command prompt requires two separate invocations:

    set KEY=value
    ./myApp
PowerShell also:

    $env:KEY='value'
    ./myApp
Or more "verbosely/explicitly":

    [System.Environment]::SetEnvironmentVariable('KEY', 'value')
    ./myApp
Regardless, all those methods aren't "scoped".
amonith 9/2/2025||
eh `cmd /C "set KEY=value && ./myApp"` isn't that bad if you really need complete isolation.
RaptorJ 9/2/2025||
or directly in powershell, `Start-Process myproc.exe -Environment @{ FOO = 'bar' }`
Sohcahtoa82 9/2/2025||
What an absolutely awful syntax.

How Powershell ever got popular is beyond me.

amonith 9/2/2025|||
Because it's objects, not text. It "scales" a lot better in your brain because in general you need to know a lot less than in bash. No more awkward sed and awk scripts, manipulating objects is a breeze. Awkward syntax at places where you have to create an object from scratch is a fair price.
encom 9/2/2025|||
Right? This is your brain on Windows.
ohdeargodno 9/2/2025||
yeah | it's | so | much | better | with | bash | tr | cut -d' ' -t5 | jq .entry[].text | sed -i s/who/evenknows/g

Anyone who has ever maintained a semi complex set of bash invocations and pipes knows it's a fragile incantation that breaks anytime you look at it funny, or something in your chain produces unexpected output.

Powershell, while absolutely horrible to read and only slightly less horrible to write (hey look, proper auto completion instead of trying to cut on the 4th, wait no sorry 5th, ah fuck it's the 6th there's an invisible space) at least produces consistent and reproductible results.

No, your python script doesn't count, it makes me do a pip install requests. Oh, sorry, pip can't be used like that, gotta run apt instill python3-pip or my whole system breaks.

JodieBenitez 9/2/2025||||
> because Windows doesn't (didn't?) have ENV vars.

As long as I can remember in my career, Windows had environment variables. So that's at least 25 years. It's both available to view/edit in the GUI and at the prompt.

delfinom 9/2/2025||||
Damn, I didn't know someone could be so clueless about Windows or operating system history in general. What the hell do they teach in computer science these days
throwaway127482 9/2/2025||||
Port detection? Thread management? These things have nothing to do with next.js right?
ohdeargodno 9/2/2025|||
Windows has had envvars since before Linux existed. It also has FindFirstChangeNotification (or ReadDirectoryChangesW if you hate yourself) since before inotify existed, etc.

Windows has pretty much everything you can dream of (although sometimes in the form of complete abominations), it's just that the people employed by Vercel don't give a shit about using native APIs well, and will map everything towards a UNIX-ish way of doing things.

berkes 2 days ago|||
My point was not that windows doesn't have Inotify (or the other stuff) but that it does it different to Unix.

Or, if you insist, that Unix is inconsistent with how windows does it.

Which is what those wrappers and abstractions do: they expose a single api to e.g. detect file changes that works with inotify, readdirectorychanges, etc.

arcfour 9/2/2025|||
This seems to ignore the possibility of Windows having done them in a UNIX-ish way to begin with, which would be infinitely better than what Microsoft came up with.
ohdeargodno 9/2/2025||
Windows had most of these APIs _before_ UNIX ever dreamed them up. You can jerk yourself off about the superiority of io_uring all day long, but it had been in Win32 for 15 years prior, and has kept compatibility throughout. I can't promise that io_uring will still be in the kernel by 2040.

So, yeah, speaking in hindsight is really easy.

PS: no, the UNIX way is also shit, just in a different way.

avdwrks 9/2/2025|||
My biggest problem with it now is the official React team pushes it as their framework of choice. Back when it used the Pages Router and wasn't trying to push everything into server components, etc., it wasn't terrible but I can't help but feel bad for any newcomers trying to learn web development.

I switched to Astro from Next for most projects and haven't looked back. It's such a breath of fresh air to use.

signaleleven 9/3/2025||
Next.js was a godsend when it came out because of how easy it made SSR. Many React projects don't need SSR, but for those that do it was technically complicated and time-consuming to hand-roll it.

I was part of a successful large project where we did our own SSR implementation, and we were always tinkering with it. It wasted a lot of time. Next.js "just worked". I've used Next with the pages router on two significant and complex projects and it was a great choice. I have no regrets choosing it.

827a 9/3/2025|||
The most frustrating thing about Next.js is that it tries to be a really cool Rails/Wordpress/Meteor-like full-stack everything-and-the-kitchen-sink framework, but you quickly realize that all the opinions you delegate for it to make are, like, the most boring possible things it could choose to take opinions on (e.g. its opinions about middleware, image resizing, SSR-everywhere, etc) while the actually productive opinions it could take it leaves to you (database, ORM, communication protocols). Its not remotely in the same realm as Rails/Wordpress/Meteor.

Framework-defined infrastructure is a seriously cool and interesting idea, but nowadays Next feels more like an Infrastructure-defined framework; the Vercel platform's architecture and design are why things in Next are the way they are. It was supposed to be "Vercel adapts to Next", but instead we got four different kinds of subtly different function runtimes. My usage dashboard says my two most-used things are "Fluid Active CPU" and "ISR Writes". I just pay them $20/mo and pray none of those usages go over 100% because I wouldn't have the first clue why I'm going over if it does.

Half the labels on there are Star Trek technobabel, which I would take the effort of learning, except I'm convinced they're all going to change with the next major release anyway. Partly because, I keep hoping & praying they will. I know a concerning number of former die-hard Zeit fans who've taken their projects and customers elsewhere. At the end of the day, if they were to ask me what they need to address in the next major release, I seriously do not know how to answer that question beside "practically every major and minor decision y'all have made since and including the App Router was the wrong one". How do you recover from that? Idk.

jimbokun 9/2/2025|||
Sounds like Javascript's answer to Spring.
simpaticoder 9/2/2025|||
Java Spring is at root a way to combine large software components (singletons) together in a controlled manner (dependency injection). It doesn't really have an opinion on what you do with it, or even if you use it for webapps. In fairness the Servlet API (which predates Spring) was and always has been really good (which is why it's still the foundation of everything webapp in the Java ecosystem). Oddly enough, logging in Java was a mess but became really good when slf4j and logback became the de facto standard. The OP's problem is trivial in Java, Spring, Spring Boot, or Dropwizard.

Java doesn't offer isomorphic React SSR, but in most cases that is a questionable feature. Most SPAs don't need or want search-engine indexing or require instantaneous-seeming load times.

jimbokun 9/3/2025|||
Spring Boot pulls in countless dependencies without warning. It can generate classes without you asking it to. It will run code just because you added a dependency, even if you don't explicitly call it. A lot of functionality is action-at-a-distance activated through annotations, which could just as easily be simple method calls which are easier to trace and debug. Version updates are aggressive about making breaking changes, sometimes seemingly for aesthetic reasons.

It just adds a lot of complexity even if you don't explicitly opt in to it or need it.

randder 9/3/2025||
Spring Boot is not Spring (Framework). (Yes it makes use of it).
theflyinghorse 9/2/2025|||
Best explanation of spring I have ever read.

And while Spring has it's rough edges and quirks it is still an incredibly stable framework. Next, on the other hand, is a box of surprises that keeps on giving even when you think you saw it all.

thr0w 9/2/2025|||
That would be Nest, not Next. A true abomination.
mablopoule 9/2/2025||
I'm a bit surprised at reading that. I've tried both, Next left a bad taste in my mouth, but Nest was kinda neat. Didn't used it for anything too complicated though, so I'm curious about what sort of grievances people have against Nest.
Aeolun 9/3/2025||
Something, something enterprise software. I find its dependency injection harder to reason about.
nailer 9/2/2025|||
I needed to move something. By a few pixels. I spent about 4 hours learning about hydration and somewhere in my source there's a note about why I can't move the thing and how I'm working around it.
lysecret 9/2/2025|||
What did you use instead?
nonethewiser 9/2/2025|||
People will complain about Next but there is no perfect solution. The complexity driving the problems with Next materialize in other forms elsewhere. Remix is a competitive option with its own quirks. You can always roll your own with Vite, Tanstack router, etc. but then of course you're manually implementing the same stuff albeit better suited to your needs. Which isn't necessarily bad but it's not the right choice for everyone.
tacker2000 9/2/2025|||
The perfect solution is to use React for the frontend (where its main purpose and strengths lie) and use something like PHP, Java, ruby or whatever for the backend.

This insanity of server side react introduces all kinds of unnecessary quirks.

Also, the VC-funded Vercel is of course purposely dumbing down Next.js, so that everyone pays them. Its a trap everyone should be aware of.

nonethewiser 9/2/2025|||
>The perfect solution is to use React for the frontend (where its main purpose and strengths lie) and use something like PHP, Java, ruby or whatever for the backend.

>This insanity of server side react introduces all kinds of unnecessary quirks.

Im kind of confused by what you mean here. You can use PHP, Java, Ruby, etc. for the backend with Next.js. You can even use if for the SSR server if you want.

I guess you are actually talking about simply not doing server side rendering at all? Im just clarifying because I think that still constitutes using "React for the frontend." I mean, how could React be used for anything BUT the frontend?

The server side rendering is actually one of the objective goods Next.js offers (not necessarily that it handles the complexity of it well). I mean, if you dont need that, sure... that's one more reason to just use Vite. But the backend choice is irrelevant.

fragmede 9/2/2025|||
Sounds like a conspiracy theory. What's wrong with making the framework easier to use? Yes, the company that's paying for development on the framework is also paying those developers to make the golden path for deployment to use that company's PaaS offering, but unless we all band together and GoFundMe a framework that doesn't, how else do you want framework development to happen? Heroku/Cloudflare/AWS/GCp's entirely able to also pay those devs to make it easier to deploy to their platform.
recursive 9/2/2025||
> What's wrong with making the framework easier to use?

Vendor lock in. Magic leaky abstractions are great until you need to debug something a few layers down when the magic stops working.

> how else do you want framework development to happen?

Loosely affiliated open source efforts maybe. If that doesn't work, I would prefer to have none at all.

fragmede 9/2/2025||
> If that doesn't work, I would prefer to have none at all.

While we would all like to retire to a cabin in the woods and be a carpenter, and for corporations not to exist, that seems unrealistic.

Magic leaky abstractions are orthogonal to vendor-lock in, and the source is open, so I'm not seeing the lock-in part. The "hey it's easier and cheaper to smash the deploy-to-vercel"-in, sure, but things cost money. Either to a developer, or to a company.

recursive 9/2/2025||
I never claimed my preferences were realistic!

Stuff costs money, sure. But I don't think it's that simple. Next and Vercel come from the same organization. I have no objection to a paid hosting solution making it operationally simpler. However when that same org has control over the free thing, they can make it even more easier (probably grammatical! who knows) that it would have "naturally" been.

claytongulick 9/2/2025|||
Lightweight native web components rendered on the light dom with lit-html and a simple API layer in express 5 is about as close to perfect as I've ever found.

The only "weakness" is that it doesn't have guard rails, so may not be great for larger teams with mixed experience.

YuukiRey 9/2/2025||||
It's hard for me to give a blanket answer to this. I tend to mostly work on services that offer GraphQL APIs these days, and not so much on client side rendering. For APIs I stick with Go because it's what I'm most familiar with. But I'd also be happy to work on a Django or FastAPI service. Anything is fine really, as long as it's mostly boring technology.

If I had to create something that has a UI I'd just go with a bog standard server rendered multi page app, built using really boring technology as well. If you like Javascript and friends, go with Express. Nowadays you can run Typescript files directly and the built-in test runner is quite capable.

If a single page application makes sense, then go with vanilla React. For a highly interactive application that's potentially behind a log in anyway, you probably don't need React Server Components.

TranquilMarmot 9/2/2025||||
I've really been loving Astro lately, it's simple enough that it stays out of your way and you can host it yourself easily. Gives you nice backend + frontend with the option to drop in React, Vue, Angular, etc if you need them.

react-router if you just want a simple React frontend, write your backend in something else.

chrisweekly 9/2/2025||||
Not OP but FYI React Router v7 (fka "Remix") has all the key features of Next.js but none of the bloat or Vercel-driven enshittification.
aswerty 9/2/2025|||
My personal experience is Remix has all kinds of problems akin to the issues in the blog post, including the mess that is remix -> react router v7. When I worked with Remix a year ago logging and middlewares were also a disaster. For example it didn't have middlewares, and had no way to create a LocalContext from the host (e.g. Express or whatever you use) that first starts handling the request down through the remix app.

I also had the impression they would probably follow the Vercel style, framework as a business model, with it being sold to Shopify.I don't really know where it's all going, but it is not the sort of thing I would tie myself to.

mm263 9/2/2025|||
Except when they ship v8 and you'll be forced to restructure your app to the whims of the library creators in case you need to update.
65 9/2/2025|||
Hono
mb2100 9/4/2025|||
This. It's what inspired me to build a static site generator and web framework built from first principles: https://mastrojs.github.io
Alex3917 9/2/2025|||
> Next.js is easily the worst technology I've ever used.

To be fair, this is partly on the kind of people who use it. E.g. if you're trying to build something that's intended to last for 10+ years but you don't think it's worth it to spend the 20 hours watching the Udemy course on Angular, then your technology is going to be a complete dumpster fire no matter which stack you choose.

Aeolun 9/3/2025|||
What is frustrating is that like 3 or 4 major versions ago Next.js was the best thing since sliced bread.
rpcope1 9/2/2025||
It's almost like the channeled the same problems and bad juju that plagued ext.js.
solatic 9/2/2025||
Half these issues stem from a relative misunderstanding of exactly where the code is running. Next.js has layers upon layers upon layers due to the interplay between the browser, middleware, edge vs. node, SSR... It's an enormous amount of complexity and it really only fits under the following set of circumstances:

  * You sell a B2C product to a potentially global audience, so edge semantics actually help with latency issues
  * You're willing to pay Vercel a high premium for them to host
  * You have no need for background task processing (Vercel directs you to marketplace/partner services), so your architecture never pushes you to host on another provider.
Otherwise, just tread the well-trod path and stick to either a react-vite SPA or something like Rails doing ordinary SSR.
oDot 9/2/2025||
I wouldn't say I agree with those circumstances, but even if they did indicate a match with Next.js, they are not worth the reduction in productivity and maintainability that comes with it.

I use Gleam's Lustre and am not looking back. Elm's founder had a really good case study keynote that Next.js is basically the opposite of:

https://www.youtube.com/watch?v=sl1UQXgtepE

tajd 9/2/2025||
this is a really interesting talk - thank you for sharing!
oDot 9/2/2025||
Via Gleam's discord:

https://discord.gg/Fm8Pwmy

There's some good stuff there

9dev 9/2/2025|||
Vercel is the cancer of the modern web. The claw into every framework ecosystem and abuse them as sales funnels for their paid plans, pretending they care about open source, competition, and the web.
hirako2000 9/2/2025|||
Thank you for the reminder. Not used next.js in years, mental health improved significantly.
oompydoompy74 9/2/2025|||
Vercel funds and sponsors many open source projects that would otherwise be struggling for funding. Their framework is tailored to the platform they build because that’s a good experience. I don’t currently use them, but people get funneled to their paid plans because it’s a good developer experience. I acknowledge that they are a capitalist enterprise with their own motives, but I think cancer of the modern web is a little strong.
specialp 9/2/2025|||
People get funneled to their paid plans out of necessity. While NextJS is open source, the back-end to run it is not. That is where all the complexity lies. Even on Netlify, you run into crazy issues with things like their image stack. It does all this "Optimization" and caching that make it completely impossible to reason about and you run into implementation problems from the providers. Sure you can just run it in a container but then you are taking on all the complexity of NextJS preoptimizations without getting any of them.

Serverless framework attempted to make this stack to run yourself for Next but it is buggy due to the complexity of Next. Open source includes being able to run it. Releasing the framework and funding OSS that also enhances NextJS is nice, but it is a trap because if it comes time to seriously run it, your only option is vercel.

rustystump 9/2/2025||||
Vercel won the techfluencer space like none other. They get a bad rep largely due to the influencer crowd adjacent to them. Influencers are cancer but an almost necessary one like marketing.

Annoying, obnoxious, and always trying to get your email but god damn do they get your attention.

9dev 9/2/2025||
No. It’s not the influencers, they are just an irrelevant nuisance. It’s the business plan of Vercel, the venture-Capital backed company.

They hire the core contributors of all major web frameworks to continue development under their roof. Suddenly, ongoing improvement of the web platform is largely dependent on the whims of Vercel investors.

They pretend to cater to all hosting providers equally, but just look at Next, which will always be tailored toward Vercel. When will it happen to Nuxt? Sveltekit? Vercel is in a position to make strategic moves across the entire SSR market now. Regardless of whether they make use of that power, it’s bad enough they wield it at all.

When has this ever been a good idea? When has it produced a good outcome? It never has, and it never will.

rustystump 9/2/2025||
If you know much about oss devs, then you know they make little money for buckets of work. Vercel is a path where they can make good money and still do some amount of oss work. I dont agree with the argument that vercel=bad because they hire people.

The fact you use the term ssr market is a key point to how effective vercel’s marketing has been via techfluencers. There isnt a market for ssr in the way you use it, only web hosting.

There is a world of engineering outside js framework relevancy wars. It isnt only vercel pushing the framing btw. Other players are trying to replicate the vercel marketing playbook. Use/hire techfluencers/oss devs to push frameworks/stacks on devs who then push it up the company stack.

Usually it doesnt work for a startup but vercel proved it can.

Enter a million lite framework wrappers around well known tech, like supabase and postgres, upstash and redis, vercel and aws.

badestrand 9/2/2025|||
I agree, I don't understand the hate in this thread.

And I think their paid hosting was actually really good, up until they switched their $20/month plan to a whatever-it-may-cost and we-send-you-10-cryptic-emails-about-your-usage-every-month plan. That's when they lost me, not because it got more expensive but because it became intransparent and unpredictable and annoying instead of carefree.

vendiddy 9/2/2025|||
And even if you fall under the first category, I find it hard to believe that the performance bottleneck is solved by using Vercel and SSR.

With all the other crazy shit people are doing (multi-megabyte bundle sizes, slow API calls with dozens of round-trips to the DB, etc) doing the basics of profiling, optimizing, simplifying seems like it'd get you much further than changing to a more complex architecture.

ncphillips 9/2/2025|||
> Half these issues stem from a relative misunderstanding of exactly where the code is running.

I used to think Javascript everywhere was an advantage, and this is exactly why I now think it's a bad idea.

My company uses Inertia.js + Vue and it a significantly better experience. I still get all the power of modern frontend rendering but the overall architecture is so much simpler. The routing is 100% serverside and there's no need for a general API. (Note: Inertia works with React and Svelte too)

We tried Nuxt at first, but it was a shit show. You end up having _two_ servers instead of one: the actual backend server, and the server for your frontend. There was so much more complexity because we needed to figure out a bunch of craziness about where the code was actually being run.

Now it's dead simple. If it's PHP it's on the server. It's JS it's in the browser. Never needing to question that has been a huge boon for us.

jbreckmckye 9/2/2025|||
Notice that nearly everyone pushing edge-execution JS has some infrastructure to sell you.

It's positioned as a ramp up for companies where frontend and backend devs work at loggerheads and the e-commerce / product teams need some escape hatch to build their own stateless backend functions

fragmede 9/2/2025||||
> If it's PHP it's on the server. It's JS it's in the browser. Never needing to question that has been a huge boon for us.

In what way has that been a boon? Context switching between languages, especially PHP, seems like an even bigger headache. Is it strlen($var) or var.length or mb_strlen($var)?

Do you ever output JavaScript from PHP?

My biggest question though is how do you avoid ever duplicating logic between js and PHP? Validation logic, especially, but business logic leaks between the two, I've found. Doing it all in Next saves me from that particular problem.

1oooqooq 9/2/2025||
spoken like a middle manager.

why would anyone send JavaScript from the php? why care about duplicating a couple json translations and null checks... it's all code is today anyway.

and switching languages? you can't use most of js as it is. even something as simple as split() have so many weird bugs that everyone just code from a utils lib anyway.

fragmede 9/4/2025||
Oh hey, insults. Those are fun.

spoken like someone who's not experienced enough to realize that duplicated code needs to be kept in sync, and then when it inevitably isn't, it'll lead to incidents, and also can't write JavaScript without using leftpad.

makestuff 9/2/2025|||
I am a backend dev, and I needed a website that was temporary for an event. I thought to myself this would be a good opportunity to learn some frontend development.

After looking through the 20 different popular front end frameworks and getting confused by SSR, CSR, etc. I decided to use Nuxt. I thought oh this is great, Vue makes a lot of sense to me and this seems like it makes it easer to make Vue apps. I could not have been more wrong. I integrated it with Supabase + Vercel and I had so many random issues I almost scrapped the entire thing to just build it with squarespace.

danielroe 9/2/2025||
would love to know what kinds of issues you encountered
b_e_n_t_o_n 9/2/2025|||
Yeah this is basically it. Vercel is trying to solve for optimised performance by using a combination of React Server Components, Partial Pre-rendering, Edge servers, streaming, etc. A lot of their seemingly weird design and API decisions basically come down to that. If you need it, it's good that it exists. But you can also go pretty far with doing some ssr in an edge function too.
cluckindan 9/2/2025||
I would be more inclined to believe it’s an end product of years of simultaneous resume and job security driven development.
boppo1 9/2/2025||
LIRPslop, as Brad Troemel would put it.
mvdtnz 9/2/2025|||
> Otherwise, just tread the well-trod path and stick to either a react-vite SPA or something like Rails doing ordinary SSR.

Just write your SPA the grown up way. Write your APIs in a language and framework well suited to such work (pick your poison, Rails, Spring, whatever Microsoft is calling this year's .NET web technology). And write your front-end in Typescript.

There's absolutely no reason to tightly couple your front-end and backend, despite how many Javascript developers learned the word "isomorphic" in 2015.

matt-p 9/2/2025|||
Having front-end and backend in the same language and mono repo is such an outrageous productivity booster for me. Obviously the opposite may still be true if you've got big, separate frontend and backend teams but if you just want to ship.. I wouldn't have it any other way.
webdevladder 9/2/2025|||
Full-stack rich schemas, not the poor lossy JSON Schema or other language-agnostic ones, are so nice for long-term quality and development velocity. You get to categorically avoid bugs that drag teams down. Zod 4, ArkType, and Valibot are all great.
smaudet 9/2/2025||
This is the problem inherent in web dev I suspect. JS developers thought they reached the zenith of programming because they had a type system and could realize some gains via strong typing checks applied to what would otherwise be network calls.

However, at a certain point, you're better off not writing a web app anymore, just an app with a somewhat wonky, imprecise runtime, one that lacks any sort of speed and has many drawbacks.

And you lose one of the most fundamentally important parts of the web, interop. I'm sure other langs can be made to speak your particular object dialect, however the same problems that plague those other type systems will still plague yours.

Which circles back to my issue, no, sticking your head in the sand and proclaiming nothing else exists, does not, in fact, make things better.

webdevladder 9/2/2025||
You've missed the point, it's inherent in any serialized communication, and the gains are far greater than a type system. Protobuf and friends, and every type system in existence, pale in comparison to runtime capabilities and guarantees.
happimess 9/2/2025|||
You can have a monorepo with any tech stack you'd like.

You can write your front-end and back-end in the same language.

No shade to you for finding a productive setup, but Next.js tightly couples your front-end and back-end, no question.

evilduck 9/2/2025|||
> Next.js tightly couples your front-end and back-end, no question.

I'd question that statement, since it's wrong. There's no requirement to connect your NextJS server to your backend databases, you can have it only interact with your internal APIs which are the "real backends". You can have your NextJS server in a monorepo alongside your APIs which are standalone projects, and Next could exist solely to perform optimized payloads or to perform render caching (being the head of a headless CMS). It seems like a weird choice to make but you could also build almost a pure SPA have have Next only serve client components. The tightness of the coupling is entirely up to the implementor.

matt-p 9/2/2025|||
I don't use next.js really any more. That's exactly what I do.
zarzavat 9/2/2025||||
I don't agree. Having front-end and backend in the same language is so convenient I would never go back to doing it the old way. I'd rather compile the frontend to WASM than introduce a mismatch.

I used to use Django and there were so many issues that arose from having to duplicate everything in JS and Python.

turtlebits 9/2/2025||
What about HTML? Are you writing HTML via JS - if not you're already writing multiple languages.
zarzavat 9/3/2025||
HTML is not a programming language. But yes, I don't write much HTML anymore.

The issue with mixing languages is that they have different data models, even simple things like strings and integers are different in Python and JS, and the differences only increase the more complex the objects get.

Sometimes I write some code and I realise that this code actually needs to execute on the client instead of the server (e.g. for performance) or the server instead of the client (e.g. for security). Or both. Using one language means that this is can be a relatively simple change, whereas using two different languages guarantees a painful rewrite, which can be infectious and lead to code duplication.

b_e_n_t_o_n 9/2/2025||||
Agreed. It's a bit insane that updating a button padding redeploys your entire backend.
matt-p 9/2/2025|||
Not the same problem though is it? You can have a express backend and react-vite frontend both in typescript and in a mono repo.
fragmede 9/2/2025|||
Are you paying for computer time by the CPU cycle?
nchmy 9/2/2025||||
or dont even write a SPA. Send hypermedia from your backend language/framework, use HTMX + Alpine or Datastar, and call it a day.
icedchai 9/2/2025||
I’ve been experimenting with HTMX and it feels so much simpler.
jakubmazanec 9/2/2025|||
> There's absolutely no reason to tightly couple your front-end and backend

I'll give you one reason: Gel [1] and their awesome TypeScript query builder [2].

[1] https://www.geldata.com/ [2] https://www.geldata.com/blog/designing-the-ultimate-typescri...

rco8786 9/2/2025|||
> a relative misunderstanding of exactly where the code is running.

This is the exact problem with the App Router. It makes it extremely difficult to figure out where your code is running. The Pages Router didn't have this issue.

robertoandred 9/2/2025||
Does it? Just look for "use client" at the top of the file.
rco8786 9/3/2025||
I love this comment!

"use client" does NOT mean it only renders on the client! The initial render still happens on the server. Additionally, all imports and child components inherit the "use client" directive even when it's not explicitly added in those files. So you definitely cannot just look for "use client".

See what I mean now?

From the docs:

```

On the server, Next.js uses React's APIs to orchestrate rendering. The rendering work is split into chunks, by individual route segments (layouts and pages):

Server Components are rendered into a special data format called the React Server Component Payload (RSC Payload).

Client Components and the RSC Payload are used to prerender HTML.

```

HUH?

```

On the client (first load) Then, on the client:

HTML is used to immediately show a fast non-interactive preview of the route to the user. RSC Payload is used to reconcile the Client and Server Component trees.

```

HUH? What does it mean to reconcile the Client and Server Component trees? How does that affect how I write code or structure my app? No clue.

```

Subsequent Navigations On subsequent navigations:

The RSC Payload is prefetched and cached for instant navigation. Client Components are rendered entirely on the client, without the server-rendered HTML.

```

Ok...something something initial page load is (kind of?) rendered on the server, then some reconciliation (?) happens, then after that it's client rendered...except it's not it actually does prefetching and caching under the hood - surprise.

It's insanely hard to figure out and keep track of what is happening when, and on what machine it's actually happening on.

robertoandred 9/3/2025||
Correct, 'use client' means it can render in the browser, not that it only renders there. Rendering only in the browser would break SSR.

If you try to use browser functionality in a component without 'use client' or to use server functionality in a client component, you'll get an error.

pjmlp 9/2/2025|||
As mentioned somewhere else, these are the kinds of layers SSR frameworks have had for decades, maybe people should learn not to do SPAs for everything.
marcosdumay 9/2/2025|||
> so edge semantics actually help with latency issues

Hum... You make an entire app in node, load the UI over react, pile layers and more layers of dynamicity on top (IMO, if next.js didn't demonstrate those many layers, I wouldn't believe anybody made them work), eschew the standard CDN usage, and then want distributed execution to solve your latency issues?

h4ck_th3_pl4n3t 9/2/2025||
> Half these issues stem from a relative misunderstanding of exactly where the code is running.

If I take a look at other languages, these kind of multi-threading issues are usually represented by providing a separate context or sync package (that handle mutexes and atomics) in the stdlib.

And I guess that's what's completely missing in nodejs and browser-side JS environments: An stdlib that allows to not fall into these traps, and which is kind of enforced for a better quality of downstream packages and libraries.

christophilus 9/2/2025|||
This has nothing to do with multithreading, though?
arnorhs 9/2/2025|||
Absolutely correct. Those are runtime execution context-issues. There are other frameworks that do force you do deal with those (and in other languages, probably), but I believe in next.js the difficulies are at another level - because of poor documentation and the built in abstractions to allow for running next.js both in development, node.js server, and edge.
cookiengineer 9/2/2025|||
Not OP but wasn't the article about lots of async/await context issues?

If the handle() method of the middleware API would have provided, say, a context.Context parameter, most of the described debugging issues would have been gone, no?

h4ck_th3_pl4n3t 9/3/2025||
Yes, that's what I meant
Rauchg 9/2/2025||
Heard and appreciate the feedback. We’re well aware of the DX papercuts in Middleware. With 15.5 we made a big step in supporting Node runtime[1] which addresses a slew of issues people have reported over time.

If I went back in time, I would have called it Routing Middleware or Routing Handler. A specific hook to intercept during the routing phase, which can be delivered to the CDN edge for specialized providers. It’s also a somewhat advanced escape hatch.

Since OP mentions logging, it’s worth noting that for instrumentation and observability we’ve embraced OpenTelemetry and have an instrumentation.ts convention[2]

[1] https://nextjs.org/blog/next-15-5#nodejs-middleware-stable

[2] https://nextjs.org/docs/app/api-reference/file-conventions/i...

throwaway150 9/2/2025||
Appreciate the response. But ...

> Since OP mentions logging, it’s worth noting that for instrumentation and observability we’ve embraced OpenTelemetry and have an instrumentation.ts convention

That makes it sound as though the answer to a clumsy logging facility is simply to add another heavy layer of complexity. Surely not every application needs OpenTelemetry. Why can’t logger().info() just work in a sensible way? This can't be such a hard problem, can it? Every other language and framework does it!

conor- 9/2/2025||
> Why can’t logger().info() just work in a sensible way?

I think OTEL is pretty sensible for a vendor-free and if you want to have a console logger you can use the console exporter[0] for debug mode during local development. Also if Next is designed as a framework to make it easy to build production-grade apps, having a standardized way to implement o11y with OTEL is a worthwhile tradeoff?

If you view that as being overkill, perhaps you're not the target audience of the framework

[0] https://opentelemetry.io/docs/languages/js/exporters/#consol...

specialp 9/2/2025|||
Because making it easy to run and monitor NextJS is never in their interest. The difficulty of that is what pushes people that make it to production with Next onto their platform. The goal is to provide more impressive preoptimizations that complicate the stack more and make it more difficult to run NextJS yourself and actually use any of them.
conor- 9/3/2025||
I don't really know anything about self-hosting Next apps - but if you're deploying to k8s, it's not really that difficult or far-fetched to run an otel collector sidecar for your applications. It's already common to run some kind of prometheus scraper or other service to collect logs/metrics from your services but instead of having to have different collection methods for APM vs logs vs traces you can have it all aggregated in one place using OTLP format
camdenreslink 9/4/2025||
Just by bringing up k8s you are making their point. It should be dead simple to do logging without having to set up hardly anything. I shouldn't even need to know what a sidecar container is.
conor- 9/4/2025||
"dead simple" really depends on what you're targeting and how. If you're targeting a cloud deployment on hardware you don't control or that's running with multiple instances/replicas, OTEL makes that pretty simple because you get a lot for free in the way of tracking instances/correlation ids, etc.

If you wanted "dead simple" text-based logging in a situation where a service is deployed in multiple places you'd end up writing a lot of fluff to get the same log correlation abilities that most OTEL drivers provide (if you can even ship your logs off the compute to begin with)

Which again comes back to the "maybe the framework isn't for you" if you're building an application that's a monolith deployed on a single VPC somewhere. But situations where you're working on something distributed or replicated, OTEL is pretty simple to use compared to past vendor-specific alternatives

tacker2000 9/2/2025|||
Again, why would one need such a heavyweight tool?

Most frameworks have powerful loggers out of the box, like Monolog in the PHP world.

conor- 9/2/2025||
What specifically is heavyweight about OTEL? At its core it's a standard for producing structured logs along with some standards for exporting/collection. The heaviness is really implementation-specific and can vary stack to stack

There's even a handler for monolog in PHP - they are not necessarily mutually exclusive

https://github.com/open-telemetry/opentelemetry-php/blob/mai...

tacker2000 9/3/2025||
Yes but instead of just logging to a text file for example you need OTEL, thats my point.

The fact that Monolog has a handler for this tool isnt relevant, but it shows that there is one more layer of complexity tacked on.

conor- 9/3/2025||
That doesn't really mean it's heavyweight though; an extra layer, sure (but I don't even really agree that it's complex - you set it up once and then mostly just log the same way you would with any other).

You can still log to a text file if you want to run locally, but for something like next.js where you're intended to deploy production to some cloud somewhere (probably serverless) the option of _just_ writing to a text file doesn't really exist. So having OTEL as an ootb supported way to do o11y is much better than the alternative of getting sucked into some vendor-specific garbage like datadog or newrelic

arnorhs 9/2/2025|||
First off, since the sentiment here is really negative, I'd like to say that next.js is actually really good for what it does. You've done a great job at building the software that powers millions of websites at this point.

I think a big part of the negative sentiment derives from the fact that detailed documentation and reference documentation almost non-existant. The documentation mostly tells you what exists, but not how to use them, how they get executed, common pitfalls and gotchas etc etc.

The documentation is written to be easy and friendly to newcomers, but is really missing the details and nuances of whatever execution context a given api is in and does not touch on derived complexities of using react in a server environment etc.

This is a trend across a lot of projects these days - often missing all the nuances and details - writing good documentation is really hard. Finding the balance between making things user friendly and detailed is hard.

Keep it up

icyJoseph 9/2/2025|||
> Finding the balance between making things user friendly and detailed is hard.

Thanks for the note! Indeed, it is also challenging when experience hides what things are not obvious or necessary to make further connections when reading the docs. It is an area of continuous improvement.

> The documentation is written to be easy and friendly to newcomers, but is really missing the details and nuances of whatever execution context a given api is in and does not touch on derived complexities of using react in a server environment etc.

I think on this particular topic, there had been an assumption made on the docs side, that, listing Edge runtime (when middleware was introduced), as its own thing, that might as well run in another computer, would also communicate that it does not share the same global environment as the underlying rendering server.

I'll do some updates to narrow this down again.

> The documentation mostly tells you what exists, but not how to use them, how they get executed, common pitfalls and gotchas etc etc.

Do you have anymore examples on this. I have been improving the revalidateTags/ Paths, layouts, fetch, hooks like useSearchParams, gotchas with Response.next, etc..

I know the OP post does talk about issues not being responded to, but that trend has been changing. If you do find/remember something as you describe, please do open a documentation issue, pointing to the docs page and the confusion/gotcha - we have been addressing these over the past months.

mhitza 9/2/2025|||
Don't you find it problematic, as a framework that's 8 years old to already have reached version 15.x? Assuming they follow semantic versioning and those are 15 different backwards incompatible upgrades?
Vinnl 9/2/2025|||
Most of our upgrades have been fairly painless. Yes, they're not CI-succeeds Dependabot merges, but usually it's basically running the auto codemod and you're done, though I do always scan through the release notes and migration guide. That seems justified for the backbone of our application.
conradkay 9/2/2025||||
I haven't used next.js but it looks like they have mostly automatic/codemod migrations

`npx @next/codemod@canary upgrade latest`

arnorhs 9/3/2025||
Yes, those have been really decent IIRC - don't remember ever having issues upgrading
presentation 9/2/2025|||
Don’t think it’s semver.
brazukadev 9/2/2025||
I think it is, that is why it is still unstable, 2 majors changes/year.
bestest 9/2/2025|||
Since you're here — I'll just pipe in.

Here in this article, the author, failing to comprehend the domain differences, is applying the same approach to call a function everywhere. Of course it won't work.

The fallacy of nextjs is attempting to blend function domains that are inherently different. Stop doing that and you will be fine. Documentation won't work, it will be just more confusing. Blending edge and ssr and node and client-side into one is a mess, and the attempt to achieve that only results in layers upon layers of redundant framework complexity.

presentation 9/2/2025||
Sounds like you wouldn’t be a fan of React Server Components in general then since blending domains is its whole point.
hungryhobbit 9/2/2025||
Blending domains is great. Blending domains where you don't get logging at some levels because your framework is incompetent is not.
dminik 9/2/2025|||
Yeah, I was actually recommended the instrumentation route by a commenter on Reddit.

I spent a similar amount of time setting up opentelemetry with Next and while it would have been titled differently, I would have likely still written a blog post after this experience too.

This isn't your fault, but basically every opentelemetry package I had to setup is marked as experimental. This does not build confidence when pushing stuff to production.

Then, for the longest time I couldn't get the pino instrumentation working. I managed to figure it out eventually, but it was a pain.

First, pino has to be added to serverExternalPackages. If it's not, the OTel instrumentation does not work.

Second, the automatic instrumentation is extremely allergic to import order. And also for whatever reason, only the pino default export is instrumented. Again, this took a while to figure out.

Module local variables don't work how I would expect. I had to use globalThis instead.

And after all that I was still hit by this: https://github.com/vercel/next.js/issues/80445

It does work, but it was not great to set up. Granted, I went with the manual router (eg. not using vercel/otel).

rozumbrada 9/2/2025|||
If you finally decided to support proper server-side middleware, why is there still a limitation for only one middleware function and not a chain of middleewares as every other sane server implementation offers?
bestest 9/2/2025||
Consider middleware.ts as a root middleware. Nothing is stopping you from creating your own chain (which is trivial) in there. I mean, that would eventually work the same if nextjs implemented that feature — there would be a root somewhere.
rs186 9/2/2025||
That doesn't answer parent's question.

People expect "middleware" to mean a certain thing and work a certain way.

bestest 9/2/2025||

  middleware = fn(req) → next(req).
express/koa give you the use() chain. next.js gives you one root, but nothing stops you from chaining yourself. same semantics, just manual wiring.

  type mw = (req: Request, next: () => Response) => Response;
  
  const logger: mw = (req, next) => {
  console.log(req.url);
  return next();
};

  const auth: mw = (req, next) => {
    if (!req.headers.get("x-auth")) return new   Response("forbidden", { status: 403 });
    return next();
  };
  
  function chain(mws: mw[]) {
    return (req: Request) =>
      mws.reduceRight((next, mw) => () => mw(req, next), () => new Response("ok"))();
  }
  
  export function middleware(req: Request) {
    return chain([logger, auth])(req);
  }
root is given, chain is trivial. that’s middleware.
rafaelmn 9/2/2025||
Nothing trivial about that implementation in my mind - need to keep track of where middleware is registered, reduceRight is non obvious.

I expect these things to be standardized by the framework and all the sharp edges filed off - thats why I go to a framework in the first place.

foldr 9/2/2025||
The reduceRight is just a bit of cute FP code golf. All it’s saying is that chaining an empty list of middleware yields an ‘OK’ response, and that the first middleware is passed a function which, when called, executes the remaining middleware chain, and so on. It would be obvious enough if written out as a for loop, or via direct recursion.

(My username has never been more appropriate!)

matt-p 9/2/2025|||
Will vercel/next come up with an official policy on pages roter/API routes, will they be supported long term? If I start a next project I still use pages/API routes, because of several really really bad experiences with the app router.
RadiozRadioz 9/2/2025|||
> Since OP mentions logging [...] we’ve embraced OpenTelemetry

I really hate this stuff. Users raise feedback for something they need, the dev team considers the feedback, they spend a really long time thinking about the most perfect abstraction, scope the problem way out to some big fundamental system, and come up with an extremely complicated solution that is "best". The purist committee-approved solution could technically be used to address what the user asked for, with a lot of work, but that's no longer the focus. Pragmatism goes out the window; it's all about inventing fun abstract puzzles.

All the while, the user just wanted to log things.

Not saying that's the exact situation here, but the phrasing in the comment was all too real to me.

n2h4 9/2/2025||
[dead]
DanielHB 9/2/2025||
When I first saw Next.js I was immediatelly reminded of Meteor.js. I did invest a bit in learning into it and did some personal projects. But quickly realized it was both over-abstracted and inflexible which made it really hard to get it past prototypes.

But these solutions keep coming up because they bring one thing: Self-contained / "batteries included". Just the other day there was a thread in hackernews about Laravel vs Symphony and it was the same thing: shit breaks once complexity comes in.

If you compare those solutions with the old model that made NodeJS / React SPA get so popular, so fast: Buffet-style tooling/libraries. You basically build your own swiss army knife out of spare parts. Since all the spare parts are self-contained they have to target really low abstraction levels (like React as a component library, HTTP+Express as a backend router, Postgres as DB).

This approach has many disadvantages but it really keeps things flexible and avoids tower-of-babel style over-engineering. As in a lot of layers stacked on top of each other. Not that the complexity goes away, but instead you have a lot of layers sibling to each other and it is more doable to replace one layer with another if things aren't working well.

It is understandable why "batteries included" is so popular, it is really annoying to stitch together a bunch of tools and libraries that are slightly incompatible with each other. It definitely needs people with more experience to set up everything.

martinald 9/2/2025||
Thing is I'm spoilt by asp.net, which has so much bad 'stigma' in the (esp startup) dev community but it is _extremely_ well designed.

You get a very batteries included approach(es) but you can always punch out of it and override it. I've never got into a situation where I'm feeling like I'm fighting the framework.

I also really like both Blazor Server and Blazor Webasm which allows you to write the frontend in C# too. Blazor server is great for internal admin panel style apps, and blazor webasm is good for saas apps, and for everything else plain old server sider rendering works great.

I'd really recommend anyone who is annoyed with their web framework to give it a go. It's extremely cross platform now (the huge drawback until about a decade ago was it was very hard to run on Linux, which isn't the case at all now - in fact, it's the opposite, harder to run on Windows), very fast and very easy to use. It takes a while to figure out the mental model of the design in your head but once it comes together you can quickly figure out how to override everything when you hit limitations (which tbh, is pretty rare compared to every other framework).

AstroBen 9/2/2025|||
It's weird how C# can elicit such an eugh response, and TypeScript gets so much love. They're.. made.. by.. the.. same.. people

I agree people really need to update their mental model of where dotnet is at. I worked with it on Linux and it's a great experience

porridgeraisin 9/2/2025||
Probably because the standard way of writing C# is too OOP-ish (for lack of a better term). Typescript lets you write just usual functions handling mostly typed objects, which is about as much abstraction as most people want (except for 1-2 classes for stuff like `BTree`), and as much typing as most people want.
mrsmrtss 9/2/2025|||
It's more likely they never tried C#, but have a very strong negative bias towards it nevertheless. C# can also be written very functional if you want, it's a multi-paradigm language like Typescript itself.
porridgeraisin 9/2/2025||
Of course it _can_ be. But that's not how major libraries are structured. Which defines how majority of business apps are structured. The way majority of folks use a language defines the language in its entirety, doesn't matter if theres a kitchen sink of alternative paradigms. You can't argue that C# isn't enterprisey in the majority case. In JS you can build on top of a whole, extremely popular library ecosystem purely using functions and options objects.
DanielHB 9/2/2025|||
It is because C# uses nominal types (C-like) and typescript uses structural types (ocalm-like).

https://en.wikipedia.org/wiki/Nominal_type_system

https://en.wikipedia.org/wiki/Structural_type_system

Although nominal types doesn't necessarily mean OOP-ish (inheritance-heavy) it is a pre-requisite (for inheritance-heavy code).

The distinction between the two is not a black/white thing but (modern) typescript (and Flow as well) is heavily focused on structural typing while C# is heavily focused on nominal typing. In fact the whole composition vs inheritance discussion fundamentally is about making types that behave in a more structural manner.

terandle 9/2/2025|||
Blazor is not good at anything. Please stick with JS for the frontend .NET devs. You'll thank me later.
hirvi74 9/2/2025||
What issues have you encountered?

As old school as it may be, I can accomplish basically everything my users need with just vanilla JS and .fetch() requests.

I've been playing with Blazor, and it's been great so far. However, like everything, I know it's not perfect.

terandle 9/3/2025||
Performance of WASM issues. Rendering performance of large data grids is not good. Also the first load time is also terrible 50mb+ payloads.

Blazor server uses websockets and is just a whole other bag of hurt. You'll have to deal with disconnects even if you can stomache the increased cloud costs.

martinald 7 days ago||
50mb payloads are very extreme. There's definitely a few MB of hurt for WASM - but nextjs is just the same, plus it doesn't have the excuse of having to download the entire CLR!

You can (and I have) definitely rendered huge data grids efficiently with Blazor.

The biggest drawback with wasm is no proper multithreading support which has been delayed for years.

On blazor server; I totally agree, it's a pain. But for 'intranet' style apps which are used internally it's by far the most productive development environment I've used for web. I wouldn't use it for anything that wasn't a total MVP for public use but it's pretty great for internal apps like admin panels.

noisy_boy 9/2/2025|||
> If you compare those solutions with the old model that made NodeJS / React SPA get so popular, so fast: Buffet-style tooling/libraries. You basically build your own swiss army knife out of spare parts. Since all the spare parts are self-contained they have to target really low abstraction levels (like React as a component library, HTTP+Express as a backend router, Postgres as DB).

I have done a few Angular apps and the experience/setup quoted above is basically foreign to me. I know that it is a framework and not a library but it is a very well designed framework (atleast Angular 2 onwards; I used Angular v20 for my latest component). Basically most of the commonly needed stuff is included in the framework (I just added NGXLogger for logging) and the abstractions are pretty nice and fairly similar to a backend service (services wrap libraries and components rely on services). RxJS can be a bit of a learning curve but once you are comfortable with the basics, it can take you quite far. Atleast I rarely had to fight with the framework for typical SPAs. Also, the documentation along with tutorials is great - I learned using the tour of heroes application[0] but seems angular.dev[1] is the new home for v20 docs.

[0]: https://v17.angular.io/tutorial/tour-of-heroes

[1]: https://angular.dev/

myflash13 9/2/2025|||
Nah, Laravel is proof that over engineered abstraction can sometimes be done right. Laravel works beautifully in production and I have never regretted using it.
skydhash 9/2/2025||
I don't think Laravel is over engineered. It seems more like a bag of libraries for building web applications held together by a thin framework layer. Even if there's a lot of reflections being used, it's a very readable codebase and very semantically tied to the web apps domain.
panny 9/2/2025|||
>both over-abstracted and inflexible which made it really hard

This seems to be built into the culture of companies which have those ridiculous whiteboard leetcode interviews. You find people who can produce very clever complex solutions in their sleeep, and then they do that. Interviews aren't selecting for people whose strength is simplicity and clarity instead. So you get a lot of tight loop optimizers and they tight loop optimize everything... not just the tight loops. But if your product is a library/framework being consumed by mere mortals, you probably want something simple if you want to succeed in the long run. The super car's performance is meaningless to you if you can't drive stick.

DanielHB 9/2/2025||
Yeah, clever code is the bane of my existence.

Only my own code is allowed to be clever!

bapak 9/2/2025|||
> it is really annoying to stitch together a bunch of tools and libraries that are slightly incompatible with each other

This is my job. We're a small team and my job is to keep things up to date. Insanely time consuming. Packages with hard dependencies and packages that stopped being supported 5 years ago.

DanielHB 9/2/2025||
Yep, been there. It is a lot better these days for React SPAs but it is still a pain.

Fact is the only way around this in the frontend without a monolitic "batteries-included" all-encompassing all-knowing all-mighty framework is through standardization which can only be pushed by the browsers. Like if browsers themselves decided how bundlers should work and not have them be extensible.

And this tooling-hell is not only a browser frontend problem only either, it is also quite common in game development. Where you also have these monstrosities like Unreal Engine that "includes batteries" but makes it really hard to troubleshoot problems because it is so massively big and complex. A game engine is basically a bundler too that combines assets and code into a runnable system to be run on top of a platform.

wild_egg 9/2/2025||
Advances in the browser standards are slowly removing the need for most client side JS altogether so standardizing on some concept of bundlers would be a step backwards.

Vast majority of web dev projects have zero need for an SPA framework these days and all this pain is self inflicted for little benefit.

Those tools do have good use cases still but the chances that your project is one of them I'd shrinking all the time.

Browser standards have come a long way in filling the holes that caused react to be written in the first place.

DanielHB 9/2/2025||
I don't think we will ever be able to get away from bundlers because there is no way to solve the waterfall request problem of using modules (one module imports requires another module). Maybe some kind of standard manifest spec that tells the browser which parts of the code to load upfront and which parts of the code to lazy-load, but to generate that manifest in an efficient manner you would need at least part of what the bundlers do today.

Minifying is also somewhat of a hurdle, I guess it could be done at the CDN level on-the-fly+cache, but that is also its own nest of complexity.

SPA frameworks have a place, if anything I think they will become more prevalent, but I can foresee WASM opening the door for non-JS language stacks. However they will need bundlers as well and some languages are just not built around giving ways to minimize binary size and lazy-load code. Just try to compile some C++ to wasm, you end up with 10+mb .wasm files.

wild_egg 9/2/2025||
> Advances in the browser standards are slowly removing the need for most client side JS altogether

I probably wasn't clear enough when I said this.

If you're talking about waterfall requests in module loading, you've missed what I said and are likely sending orders of magnitude more JS to clients than you need to.

It's really worthwhile looking at all the new features in browsers over the last 5-10 years and asking yourself if you really can't do what you need just with vanilla HTML and CSS at this point. You can always sprinkle in a bit of JS to fill in some gaps if needed. My team usually has a 2-300 line JS file in each project. No bundlers or modules ever required at that scale.

AstroBen 9/2/2025||
> It definitely needs people with more experience to set up everything

I mean it's not just the experience - it's the upfront time cost and then ongoing maintenance.. and for what? It's really easy to underestimate how much effort this will be

Having done both I genuinely think Rails is a 10x productivity boost over stitching your own mishmash of libraries together in Node

The only lack of flexibility you run into is if you really disagree with the fundamentals of the framework. If you hate the ActiveRecord pattern for example you need to stay away

"shit breaks once complexity comes in" is a skill issue

pavel_lishin 9/2/2025||
> Let's not skip over the fact that you can't have multiple middlewares or chain them either.

Surely this can't be right?

https://nextjs.org/docs/messages/nested-middleware > If you have more than one Middleware, you should combine them into a single file and model their execution depending on the incoming request.

By Talos, this can't be happening.

zelphirkalt 9/2/2025||
Am I reading this correctly? They are advocating giving up on structuring code in separate files? Is that a scoping problem that NextJS has, which makes it difficult to use multiple files? Seems like a rather ridiculous statement of a framework to make.
wetoastfood 9/2/2025||
It's the single file that is used to define the middleware function that runs. You can import whatever you want into it and decide how "you should combine [your middleware] into a single file."
qbane 9/2/2025|||
As a JavaScript developer, combining/consolidating middlewares manually just defeats the design of middleware. I would rather call it a callback function.
hn_acc_2 9/2/2025|||
I prefer this to having app.use / router.use scattered anywhere throughout the app init (i.e. Express)
digianarchist 9/2/2025||
I can’t help but feel some of these decisions are made because it’s what is best for Vercel and not what’s best for the framework.
tshaddox 9/2/2025||
I don't see how this particular case makes anything better or worse for Vercel. It's just a poor developer experience to need to come up with your own composeMiddlewares function (or find one of the many that people have posted in various threads).
digianarchist 9/2/2025||
They validated this on the thread. They made an architectural decision to run middleware only on edge.
tshaddox 9/2/2025||
That's unrelated to the complaint I'm responding to, which is simply that you can only provide a single middleware file. This is merely a DX problem. You absolutely can develop your own composeMiddlewares function and import different middleware functions from different modules. It's just on you to do that, and to reimplement some basic functionality for each composable middleware function (like matcher regexes).
digianarchist 9/3/2025||
From their blog post:

> Previously, Next.js middleware only supported the Edge Runtime, which provided better performance and isolation but had limitations when integrating with Node.js-specific libraries and APIs.

That's not something that can be resolved with a library abstraction. That was an architectural decision.

j-krieger 9/2/2025||
It really is. I am a staunch react defender, I work with it daily and I found the change from class components to hooks to be a better programming model.

But whenever I work with Next, I feel like we lost the plot somewhere. I try a lot of frameworks and I like esoteric programming languages, but somehow Next.js, the frontier JavaScript framework embraced by React is the only experience where half the time, I have no idea what it’s error messages (if I get any to begin with) are trying to tell me. I can’t even count the hours I spent with weird hydration issues.

palmfacehn 9/2/2025||
I'm not a React or Next.js user. Others will disagree, but personally I prefer to minimize my exposure to JS by decorating traditional HTML+CSS documents with vanilla JS as needed.

I was somewhat surprised when I noticed simple Next.js landing pages would break in Firefox. Worse yet, the failure mode was to overlay all of the content with a black screen and white text, "An application client side error has occurred". It was surprising in that a simple landing page couldn't render, but when I discovered that the cause was a JS frontend framework, I felt that it was par for the course.

Perhaps it makes sense to the advocates, but for those of us not on the bandwagon, it can be sincerely baffling.

rimunroe 9/2/2025||
> Others will disagree, but personally I prefer to minimize my exposure to JS by decorating traditional HTML+CSS documents with vanilla JS as needed.

If you don't mind my asking, what sort of applications have you worked on, how many contributors were there, how long was their lifespan, and how long did you work on them for? Personally, I've found the type of "vanilla" JS approach to be prohibitively difficult to scale. I've nearly exclusively worked on highly interactive SaaS apps. Using a substantial amount of JS to stitch together interactions or apply updates from the server has been unavoidable.

The engineering organizations at companies I've worked at have ranged in size from three devs to over 20,000. Projects I've worked on have ranged from three devs to maybe 500-1,000 (it's sometimes hard for me to keep track at a giant company). I've worked on projects using "vanilla" JS, Knockout, Backbone, Vue, and React[0]. The order in which I listed those technologies is also roughly how quickly the code became hard to maintain.

[0] This is not an exhaustive list of which frontend frameworks/libraries I've used, but it's the ones I have enough experience with to feel comfortable speaking of the long term support of[1]. For example, I used Ember heavily for about a year, but that year was split between two projects I spent six months each on. Similarly, I've used Next.js, but only for prototyping a few times and never deployed with it to anything other than a private server.

[1] Except Lightning Web Components, which I've used a lot but hate so much that I don't want to dishonor those other technologies by listing it alongside them.

atemerev 9/2/2025||
Next has enshittifed themselves some time ago. Everything that goes through the VC cycle does that eventually.

I am happy for them and their money, but I can't use this anymore. I take Vite as the default option now, but I would prefer something more lightweight.

ollysb 9/2/2025||
When they transitioned to the app router it was like they'd given some bootcamp graduates a crack at "improving" on the express apis - which are mature and roughly align with the composable russion doll approach taken in servlets, rack, plug and any other server interface I've ever seen.

Aside from the abysmal middleware api you also have the dubious decision to replace having a request parameter with global functions like cookies() and headers().

Perhaps there is some underlying design constraint that I'm missing where all of these decisions make sense but it really does look like they threw out every hard fought lesson and decided to make every mistake again.

arend321 9/2/2025|
I believe the obsession with streaming is a major factor in the new constraints. Together with supporting the lowest common denominator, edge runtimes.
Etheryte 9/2/2025|||
And the reason they're all in on streaming to begin with is because they're sending massive amounts of data back and forth all the time. Like Sean Goedecke said in his API design writeup [0], a technically poor product can make it nearly impossible to build an elegant API. I believe we're seeing the same thing with Next.js, all of these wonky interfaces derive from the underlying architectural issues.

[0] https://www.seangoedecke.com/good-api-design/

conradkay 9/2/2025|||
Maybe it's a good design from the perspective of making more money from your hosting business
n2h4 9/2/2025|||
[dead]
kremi 9/2/2025||
I think “middleware” is a bit of a misnomer in Next.js. It’s really an edge function that runs before your request hits the app -- quick header checks, routing, and other lightweight guards. It runs on the edge runtime, not on the app server.

The post's author seems to conflate the edge runtime with the server runtime. They’re separate environments with different constraints and trade-offs.

I struggled with Next.js at first for the same reason: you have to know what runs where (edge, server, client). Because it’s all JavaScript, the boundaries can blur. So having a clear mental model matters. But blaming Next.js for that complexity is like blaming a toolbox for having more than a hammer.

yladiz 9/2/2025||
> But blaming Next.js for that complexity is like blaming a toolbox for having more than a hammer.

The biggest issue is that the complexity is self-inflicted. The term middleware has a pretty well understood meaning if you've worked with basically any other framework in any language: it's a function or list of functions that are called at runtime before the request handler, and it is assumed those functions run in the same process. The fact that Next.js puts it on the edge and only allows one is breaking that assumption, and further, most applications do not need the additional complexity. To go back to your toolbox analogy, more tools mean more complexity (and money), so you wouldn't get a new tool simply because you might need it, you get it because you do need it, and the same applies to edge functionality. If Next.js wants to allow you to run code on the edge before your app is called, that's fine, but it should be opt-in, so you don't need to worry about it when you don't need it, and it shouldn't be called "middleware".

kremi 9/2/2025|||
Yes, the term "middleware" is unfortunate, this is abundantly clear.

> you wouldn't get a new tool simply because you might need it

No but you get a framework precisely because it's "batteries included": many apps will need those tools. You don’t have to use all of them, but having them available reduces friction when you do.

> If Next.js wants to allow you to run code on the edge before your app is called, that's fine, but it should be opt-in

It already is. Nothing runs at the edge unless you add a middleware.ts. You can build a full app without any middleware. I'm surprised the author of the article fails to acknowledge this, given how much time was spent on finding alternative solutions and writing the article.

iw7tdb2kqo9 9/2/2025|||
As I have mention in another comment

> If learn what is a package/module in python, try to apply that in Go without any brain power, you will complain that Go is bad. If you are using any technology, you should have some knowledge about that technology.

mrbombastic 9/2/2025||
Don’t really think the analogy holds up, middleware is an established term in web frameworks, the same space next is operating in and the thing looks a lot like a middleware but violates some of the core assumptions people make about what a middleware is. It is not really surprising it is a point of confusion.
koonsolo 9/2/2025|||
I'm also working with Next.js, app router, and like it very much.

The problem is probably that Next.js makes it very easy to move between front and back end, but people think this part is abstracted away.

It's actually a pretty complex system, and you need to be able to handle that complexity yourself. But complexity does not mean it makes you slower or less productive.

A system with a clearly separated front- and back-end is easier to reason about, but it's also more cumbersome to get things done.

So to anyone who knows React and wants to move to Next.js, I would warn that even though you know React, Next.js has a pretty step learning curve, and some things you will have to experience yourself and figure out. But once you do, it's a convenient system to easily move between front- and back-end without too much hassle.

fabian2k 9/2/2025|||
I wouldn't consider this a misnomer, but a really big misuse of the term. Middleware has a long established definition in web applications, so they really should not use the term if they mean something entirely different.
kremi 9/2/2025|||
To people who downvote my comment (and there are many): please elaborate.

I like to learn and improve. A lot of comments here are just baseless negative comments. Please let’s have a real discussion.

iw7tdb2kqo9 9/2/2025||
Finally someone with a brain.

If learn what is a package/module in python, try to apply that in Go without any brain power, you will complain that Go is bad. If you are using any technology, you should have some knowledge about that technology.

eknkc 9/2/2025||
I have a tendency to use different stuff on new projects for the sake of it. I've built apps with express + react on client, angular, vue, next, nuxt.. Used go, .net, node, php etc on the server. I always find good and bad parts and appreciate different aspects of different solutions.

Not Next though. We built a pretty large app on Next and it was painful from start to finish. Every part of it was either weird, slow, cumbersome or completely insane.

We still maintain the app and it is the only "thing" I hate with a passion at this point. I understand that the ecosystem is pretty good and people seem to be happy with the results given that it is extremely popular. But my own experience has been negative beyond redemption. It's weird.

lmm 9/2/2025|
They're trying to do something that's fundamentally very hard. Unifying server-side and client-side code was always going to cause confusion when the difference becomes relevant.

Personally I'd rather go in the direction of having code that's explicitly server-side, explicitly client-side, or explicitly shared utilities. But you'd need more of a type-safe mentality to take that approach, and you'd probably scare off the majority who prefer runtime errors over build-time errors.

palmfacehn 9/2/2025||
Your observations apply generally. Debugging "magic" frameworks is often more complex than starting with simple basics and a coherent design. As a bonus there are less dependencies, less build issues and lighter pages or binaries.
jama211 9/2/2025||
Well said.
lysecret 9/2/2025||
Fully agree really enjoying TRPc for this.
More comments...