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.
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?
nvm use && npm i && npm run dev
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.
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.
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.
What's the story here? I assume this group was chosen for a reason and didn't meet expectations.
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.
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.
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
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.
https://react.dev/learn/creating-a-react-app
It throws you straight at Next.js
That capture happened... two years ago? (Perhaps there's a good blog post there, if it doesn't exist already)
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...
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.
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.
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.
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.
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.
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.
It's pretty absurd to have such a broad range of web solutions, and think the same solution can cover everything.
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.
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.
So you agree both solve different problems. Well, those are 2 use cases of front-end right now.
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.
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.
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.)
It's like not knowing how to write a for loop or how to access an object's property in JavaScript.
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.
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?
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".
That is extremely fishy, isn't it?
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.
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.
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.
It surely was a development platform, but wasn't supposed to be one.
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).
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.
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.
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.
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.
By comparison, DIY SSR with Express takes a few days to get working and has run quietly for multiple projects for years on end.
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)
Nope, windows has had perfectly standard environment variables since the DOS days
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".How Powershell ever got popular is beyond me.
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.
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.
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.
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.
So, yeah, speaking in hindsight is really easy.
PS: no, the UNIX way is also shit, just in a different way.
I switched to Astro from Next for most projects and haven't looked back. It's such a breath of fresh air to use.
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.
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.
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.
It just adds a lot of complexity even if you don't explicitly opt in to it or need it.
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.
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.
>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.
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.
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.
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.
The only "weakness" is that it doesn't have guard rails, so may not be great for larger teams with mixed experience.
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.
react-router if you just want a simple React frontend, write your backend in something else.
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.
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.
* 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.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:
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.
Annoying, obnoxious, and always trying to get your email but god damn do they get your attention.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
I used to use Django and there were so many issues that arose from having to duplicate everything in JS and Python.
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.
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...
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.
"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.
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.
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?
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.
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?
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...
> 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!
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...
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
Most frameworks have powerful loggers out of the box, like Monolog in the PHP world.
There's even a handler for monolog in PHP - they are not necessarily mutually exclusive
https://github.com/open-telemetry/opentelemetry-php/blob/mai...
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.
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
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
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.
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.
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).
People expect "middleware" to mean a certain thing and work a certain way.
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.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.
(My username has never been more appropriate!)
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.
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.
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).
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
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.
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.
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.
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.
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/
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.
Only my own code is allowed to be clever!
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.
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.
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.
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.
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.
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
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.
> 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.
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.
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.
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.
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.
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.
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.
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".
> 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.
> 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.
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.
I like to learn and improve. A lot of comments here are just baseless negative comments. Please let’s have a real discussion.
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.
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.
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.
So far, the experience has been absolutely wonderful, particularly, given the context of myself as a developer in the whole process, which is,
1. I am a seasoned developer, mainly doing python stuff, back-end servers, desktop applications, data applications, etc. Very little exposure to front-end tech.
2. I keep myself updated with the concepts, patterns & architecture of front-end systems, because I am extremely into design and good UI.
3. I am at a stage where I can do basic web apps with Vue, React, Angular & vanilla HTML and JS.
With Angular Signals and concept of Stores, Services and Dependency Injection, I am able to handle data flow very easily, am able to add features to the app in a consistent manner, able to debug and trace errors with relative ease.
I have earlier read NextJS docs, Remix Docs and read tutorials about developing react apps using Vite. It has always been a confusing maze of stuff. Perhaps I am getting old (about to touch 40), but I have been programming for about 25 years now and I was able to carve out the architecture I want in an Angular app with ease.
Also, this app is going to be a production app, and is critical for my work, so its an impactful decision, which, thankfully, I have been happy and pleasantly surprised with.
It could be that I could have chosen React, and end up with the same thing, but, somehow, in the extensive tech stack selection process that I took up before committing to Angular (which involved testing out core mechanisms of the application in React, Vue & Angular), I felt very much at home with Angular way of things.
I was in the trenches pre-ES6 with JavaScript and JS/CSS since the year they came out, so of course I do love KISS-style bare-bones websites when that is the proper tool for the job. But certainly not for anything at scale. Angular, being a framework and not a library, is perfect for those purposes. I prefer that it IS opinionated (no "what router does this project use?"), and I also would not develop anything these days without TypeScript (even small sites).
To each their own.
I recall back in the day when Struts was everywhere, some of us figured out it was because Struts was a trap that took twice as many devs to get anything done, and that's why there are so many openings for it. Every time I look at React, I just wonder if it is the new Struts.
The old Angular apps I worked on (heck that was before AngularJS and Angular split) was pretty decent. Long argument lists were a big problem, sure, but the whole Service layer was one of the smartest features I've seen in a framework in a while. Second only to Routes. It saved us leaking a bunch of impedance mismatches across the entire codebase. It gave us some place to stash code while we asked the backend team to change their APIs.
The previous model was that you simply have code that runs on a server when a request comes in, sends a response to the client, and then the code in that response is run on the client. Instead, now we have a situation where some bits run on the server, some of them on the client, which call out to some bits on the server again, and all of this can happen either before or after the server started sending the response. And then on e.g. Vercel, you also have edge functions as an additional permutation.
Which is kinda neat, but also massively complicates the mental model.
This true to most software projects that are used more than one set of people. Joe Armstrong proposed a solution that we should opensource functions only and people could assemble everything else using these opensource functions. I start to think that he might be right and instead using "frameworks" we should use these set of functions instead.
The ammount of functionality is not the problem.
The problem is that the functionality is not a set of composable functions and classes. It's an inversion of control "framworky" blackbox, where behavior is hard to reason about.
I'm about to start building an e-commerce site (30-50k poster print designs, i.e. no inventory), and was leaning towards a Django backend (because I know it) and... some sort of SSR frontend. I'm not really a frontend guy, but taking this as an opportunity to learn it. This article obviously does not inspire confidence in me choosing Next.js - would someone have any suggestions/pros and cons of what to use?
I currently see the options for doing SSR as:
- Next.js: well-represented in AI training data (though recent versions had breaking changes? I'm not sure), but annoying to actually use (according to this article/general sentiment I've found online), and pushes you into Vercel? (I barely know what that means)
- SvelteKit: best DX and nice to use, but might be less present in AI training data?
- Django templates + HTMX: possibly limiting? Less maintainable once you get to a certain size? I'm not sure.
- Other options?
If you insist on rolling your own, Django + templates should be plenty. Lots of existing code for integrating Stripe or whatever. AI will be fine at it. You could potentially investigate medusajs or prestashop. Here's a list that could be fun to investigate: https://github.com/awesome-selfhosted/awesome-selfhosted?tab... but keyword is fun. You should build it in wordpress because that is a bombproof solution running like half the internet and will save you endless amount of time.
If you're doing this as an exercise to learn a new tool, leave the AI to the side as you're robbing yourself an opportunity to delve into docs and gain more domain knowledge. And absolutely do not touch nextjs with a 10 foot pole, it's an absurdly overwrought tool. The only people that should learn nextjs are people working at dev houses that churn out a shitload of full stack apps for clients that have the budget to shell out for vercel's hosting costs. And even then imo they should just be using django + react + vite + tanstack MAYBE.
HTMX is cool but I'm not sure the point, again if for fun why not, but I would ask yourself: you get your site up and running and you spend the next year scrambling around putting things in boxes and printing shipping labels, and then in 2026 Thanksgiving right before the holiday rush something breaks in your app and you want to fix it but HTMX/nextjs/whatever have gone through 2 breaking change upgrades and so have 4 different libraries they rely on and actually the most up to date version of two libraries you rely on are not interoperable right now because they depend on different node versions or some other bullshit, and now what do you do?
Just use wordpress.
- I used the product variations feature, 18 variations per product, and all of a sudden the "Duplicate" button took 15 seconds! I learned this is because each variation is it's own thing, so it was making 18 new things (still insane it took that long, on my beefy dev pc). I can't imagine 30-50k products * 18 variations * metadata stuff working fast in any way.
- In avoiding product variations, there's plugins for adding product fields, and plugins for pricing rules, but clicking around to do stuff, or maybe writing php that integrates with plugins that I'm clicking around in... it's not the way I want to spend my time developing. It especially integrates terribly with AI tools, which at this point are an important development tool for me.
- I don't want to have a 1-to-1 mapping between products and pages. This doesn't fit the WC model well (or Shopify for that matter).
Generally, I can imagine an experienced wordpress/PHP dev being able to overcome these issues, but if I'm learning something anyway, I'd personally rather learn a proper frontend framework (be it any of the options you mentioned). Leveraging AI tools also matters.
I appreciate your response! Gives me more confidence in maybe sticking to Django + templates. But from what I've seen, and also in discussions with other developers, I think wordpress is out for this project. Thanks again :)
> and so have 4 different libraries they rely on
HTMX has no dependencies. https://htmx.org/essays/vendoring/
> and actually the most up to date version of two libraries you rely on are not interoperable right now because they depend on different node versions
HTMX has no build step. https://htmx.org/essays/no-build-step/
Do what gets the actual job done: focus on the selling, not the tech of the shop. Grab a template and adjust it to fit your marketing.
Actual useful tech is integration with a printer/printshop. Or getting packaging labels automatically for orders. Or using AI to make new posters.
It lets you ship client islands to the client, which AFAIK is essentially partial hydration.
Katie Sylor-Miller named them when she was at Etsy and from memory they were React components in a PHP page to start
Use Context7 mcp to get Svelte 5 docs if the agent messes up something you know should work.
The new experimental remote functions solved a big pain point with sveltekit, so I no longer have any reasons not to recommend svelte and sveltekit to people.
Once you know what is actually going to be on your site, you can style the output with CSS and add the necessary interactivity with JS. Browser APIs have mostly standardized as compared to the bad old days. Using them directly instead of libraries or frameworks will keep your site lean and fast.
All of your CSS, HTML and browser API knowledge will continue to serve you for the years to come. In a few years, people will be arguing about a new magic framework.
Theres some things to learn but once you do its amazingly simple and powerful.
That said I havent tried Astro, Nuxt
So many things built in ready to go.
You want to use something full of abstractions to the point you have no idea how it actually worked.
You did this to save time.
Then when issues occur it's someone else's fault.
That said, let me pass in a flag to get my dev logs in prod. That's ultimately what the author wants.
I've encountered issues based on Nextjs in a few projects where the best approach was to eliminate it.
The outcome was nicer and higher development satisfaction.
If you dare to say that you had to get rid of Nextjs from a particular project, during a job interview, you're done!
Possible follow up questions:
- what led your team to want to remove it? - what was involved in removing it? - what did you replace it with? - what makes the new thing better than the old thing? - how did you evaluate that spending X days/weeks/months to remove it was worth the time that could have been spent on developing features?
I think all frameworks and tools have their time and place, and knowing when and how to use them is important.
If a company can't understand this then I wouldn't want to work for them.
For me, it isn't a framework I want to use in any production environment. Your system is too much depending on something you have no influence on. Like in your own code, it is good to decouple, don't make things depend too much on something, not in your own code, but also on external code like frameworks and libraries.
That is why I prefer to build things like I can (kind of) easy drop my dependencies, for what reason, and use something else, or build it in my own codebase. If some framework doesn't allow it, and you have to work it their way, and is the base of everything, that should be a big red flag.
Unfortunately incompetence of developers to see beyond has brought the web to the point that every React developer has dealt with Nextjs at some point.
What are the alternatives beyond Vite and Remix?
On more than one occasion I’ve seen someone refer to Vite as an alternative to Next.js. Isn’t Vite a bundler and Next and Remix frameworks? How is Vite an alternative to these?
While Vercel acqui-hired many developers behind SvelteKit and Nuxt.js, I was under the impression that they weren't interested in running these projects hands-on, or even making them similar to each other. Can anyone correct me here or explain what their long-term game seems to be?
Seems Svelte is still mostly managed as an independent open source project.
I am wondering about giving Remix a whirl for an upcoming forum/CMS rewrite with custom auth. Anybody else have experiences with Remix?
Stick with a single version and you'd probably be happy though.
FWIW, I've been doing webdev-related work for a living since 1998, and React since 2016.
New devs coming in and expecting the framework to be with "batteries included", which it absolutely is not, will also have a bad time. Node apis, ALS/context, handling app version changes on deploys, running the server app itself (if in cluster mode, e.g. with pm2, what that means in terms of a "stateless" app, wiring up all the connnections and pool and events and graceful reloads and whatnot...), hell even basic logging (instead of console.xxx) ... all of that is up to you to handle. But the framework gives you space.
People new to React and/or Node will be confused as hell for quite a bit... in such a cases I would add like 3 months of personal dev time and learning to just wrapping your head around everything... React docs themselves say that you should use a framework if you're using React in 2025 - but it's not that easy. There is a cost, especially if you go the full stack route (client + server + hydration) of having everything under one "typescript roof". The payoff is big, but definitely not immediate.
Having to know node (or other supported server) and needing to implement your server business logic from scratch (models, db access, caching layer with redis or something, etc. etc.) is not a weakness, it's a strength.
The thing that .net tried to do for like a decade and failed to (one stack for both the server and the client), see Blazor bullshit etc. is handled here. Imagine you need a modern web app or a shop or whatever and that means React. It just does. Your backend stack is PHP or Rails or Go or whatever. Now you have to somehow square the hydration circle which you can't do without it being a massive pita (as PHP renders a page on the backend in.. well.. PHP) so you end up passing the data manually in some blobs of jsons or whatever with each request (or even worse, side to it in some fetches) that then React initializes from on the client and it's a total mess. Not to mention that unless you render the page in both php and react (try to keep both outputs the same lmao), you'll only see the full app "on the client" meaning crawlers/bots/google have to run JS on all your pages or see nonsense ... yikes.
SSR with hydration is there for this reason. You render the same React tree both on the server and on the client. The hydration process itself is made much easier by RR and its infrastructure (automatic passing of data to the client). Hell, thanks to SSR you don't even have to have JS enabled on the client if you're using just basic web standarts (see RRv7 docs on progressive enhancement and state management) and the site will work. This means even crawlers without JS runtimes will be able to index your site.
I have always developed backend apis in nodejs with express and used Nextjs for frontend only and just when I needed SSR.
Developing projects this way had always been a joy.
App router did change everything and destroyed the good reputation of Nextjs: it is hard to learn, to manage and does offer few concrete advantages
I’ve run into this myself. I tried middleware, AsyncLocalStorage, even wrapping layouts and pages in HOCs. After plenty of research, it still feels over-engineered for such a trivial task. Ironically, my understanding is that Next.js on Vercel already provides a requestId by default.
Another recurring issue is the documentation. The moment you hit anything even slightly advanced, it becomes too simplified to be useful, and the only guidance you find is a handful of open GitHub issues.
Imho next attempts to do too much, moves too fast, every few months the wheel gets reinvented and never perfected.
I've wrote previously about nextjs: https://omarabid.com/nextjs-vercel My opinion remains the same: Most of the issues in Nextjs are not a bug but a feature. A feature that only functions and locks you in Vercel platform.
Since their routing/SEO/content features are also now less functional, there is really very little reason to use Nextjs especially with React Server Components.
These days I do my best to stay in Rails land, far away from Next.js. It just looks like a cluster.
Wait, if you have issues with logging, why don’t you set up opentelemetry? It’s really easy to add into a project [1], and if you don’t want to manage it, you can easily find some cost efficient solutions like Grafana Labs [2].
[1]: https://nextjs.org/docs/app/guides/open-telemetry
[2]: https://grafana.com/
There are a lot of gotchas and considerations with Nextjs, but it is a framework and it is not unexpected that unless it is developed by yourself, frameworks require some getting used to.
There are some things that could be better, especially in non-Vercel-hosted scenarios, and if the backend for frontend part becomes too complicated, I would switch to Nest.js, but overall I am satisfied with Next.
It’s just a shame it’s Deno-only (although I completely understand why)
https://fresh.deno.dev/docs/concepts/islands
https://github.com/honojs/honox?tab=readme-ov-file#interacti...
(Edit: well, potentially at least)
I did try to make something like this a couple years back to deal with multiple renderers and a choose-your own set of various SSR techniques [0], but didn’t get very far with it in the end. I should have based it on Hono really, to get web standard Request objects.
Astro is pretty good too, though. I’m not 100% sure on some of the decisions it’s made, and personally don’t enjoy the need for new file formats and domain specific languages, but it does a half decent job of being framework-agnostic despite a few pain points.
Edit: I just saw an email from two hours ago that they added support for any CSS solution because they just migrated to Vite. This is promising!
I also don’t believe a React monoculture is good, so a growing Preact or Solid ecosystem would be really positive, alongside growing web/DOM standards to ultimately make these frameworks more of a light wrapper around some trivial updates.
React and Next.js, to me, have done the typical architecture astronaut thing, and it feels like they’ve both increased the barrier to entry and just made everything a little more complicated than it really needs to be for much of the web.
https://web.archive.org/web/20190612110518/http://kill-or-cu...
Long story short it's a proof of concept demo/exploratory project.
Currently, using Next.js app router, multi-root routes for stuff like (marketing), (app), (login), etc.
Db is Neon for the branching, will probably include Vercel AI SDK for AI stuff since its likely I'll be asked to include some AI functionality.
The only worry is I'm unsure with how this serverless layer/backend? interact with user authentication / authorization when used with the BetterAuth.
Currently hosting on Vercel, I feel like Next.js is married with Vercel for hosting. Although maybe because I'm unfamiliar with it, since Next.js made it quite simple and straightforward to do host quick proof-of-concepts on Vercel.
I understand the author’s frustrations. I have had similar ones when it comes to middleware and other parts of Next.js. I’ve also had those kinds of frustrations with every piece of software and framework I’ve ever used. A lot of times they stem from trying to shove a square peg into a round hole, and it only gets better when I finally develop the right mental model for how the thing works.
As a web developer going back to CGI scripts in the 90s, all this server and client side rendering, edge runtimes, etc., is quite foreign. But when I find myself screaming “why won’t it let me do this?”, the answer is often “because it doesn’t make sense to do that”. Auth is one of the places where that happened, and going through the process of “but why can’t I look the user up in my database from middleware” was a big part of wrapping my head around the parts of Next.js that I had been ignoring.
As far as being married to Vercel for hosting, not at all, if you don’t choose to use all their stuff. The sample Docker build they have works just fine to deploy anywhere, in my experience.
Maybe I’m speaking mostly out of ignorance of not having tried dozens of other modern TS web frameworks (I was on a big tech island for a decade and not in touch with what the cool kids were up to), but I rather like Next.js. I may feel differently when I want to start adding native mobile apps and realize I was lulled into omitting a clean API layer, but for now, adding features has been pretty smooth.
"Never doubt that a small group of thoughtful, committed citizens can change the world; indeed, it's the only thing that ever has." Margaret Mead
A big project becomes design by committee. If the initial kernel was sound, it can go on for quite some time. If it wasn't, it takes herculean effort to turn such a boat. And you will likely never be thanked for it.
Starting a new project to show people how it's done works as well or better than any amount of cajoling or badgering. But you still may not be thanked for it.
But in this case, I tried in earnest to use nextjs for a project with auth & stripe, etc. this past week, and I can't believe how frustrating it is to get stupid things like modal dialogs to work properly in the client.
I have tons of experience with React SPAs. But the client/server divide in Next remains quite inscrutable to me to the extent that I'm just going to start again with Django (where I nearly started it in the first place).
So yes, it doesn't work like I expect it to either...
There's no real alternative for these developers because they weren't brought up to understand server/networking fundamentals, how to operate a VPS, etc. Vercel manages to make this even more confusing for them by blurring the line between server and client, "edge" functions, etc, while all behind variable pricing.
Depending on the project, just write an SPA with an API server, or if it is a static website just prerender it and serve on Cloudflare. I don't get the appeal of all the complexity. If you need SSR for SEO, then SolidStart is a nice and simple solution.
Use .run.
return LoggerStorage.run(requestLogger(), () => {
logger()?.debug({ url: request.url }, "Started processing request!");
return NextResponse.next();
});
If you picked NextJS without knowing how it structures its middleware, the vendor lock-in to Vercel, its SSR strategy, its hydration schemes etc. that's on you. I, and many others, have had a lot of success with NextJS increasing delivery speed and ultimately, customer value.
Two years ago I moved off of the React ecosystem to Elixir/Phoenix/LiveView, and it's been great. But that's had its own challenges stemming from the design decisions its creators have made. You're always going to be running into things that you don't like, and I feel NextJS has just become an easy target for people who are looking to vent.
The middleware section is a setup. The real trouble starts when ejecting from Next and using a custom server still doesn't allow you to do anything because Next is a black box.
I would have been happy with installing fastify and just using it's middleware, but even that doesn't work.
- Passing data from LiveComponent's/JS is a bit of a pain (need to use update())
- phx-hook doesn't always pay well with re-rendering state changes
- Directly calling JS functions (e.g, getting Apple Pay to work) isn't clean
- Can't use attr when using LiveComponents (need to wrap them in a functional component)
- Unique ID requirement for LiveComponent is a pain (so is wrapping them in a div)
- No great APIs for updating session data when using sockets
- Can't pass params to LiveView in live_render, have to use session
Potential alternatives I've found:
* astro
* remix
* back to react-router... and there were multiple back when I used it! :(
Update: after some research, I really Tanstack router approach:
https://tanstack.com/start/latestBut once we got that out of the way, it is pretty nice to work with. The FE developer is very happy with how fast the project is and how easy it is to just peek into the BE portion and understand it. Server functions are just so nice to use and everything gels together really well. But it's still early days though. I would only recommend it if you are OK with parsing not-really-great documentation and maybe some relevant GitHub issues from time to time.
Astro I've found to be pretty solid for prototyping, I like that it gives you control over the rendering of client side code islands and that it works with multiple rendering libraries. I don't love some of the direction they've taken lately though, and I worry that it will become bloated with things like astro db
Likewise React Router is ... the example I use when I want to tell someone about a terribly engineered library. As you said, there are multiple React Routers, because the developer is completely incompetent, and has no idea what he is doing. As a result, he changes the entire library in massive, backwards-incompatible ways ... EVERY. NEW. VERSION.
Astro and Remix are viable options, but there's a reason why Next (despite it's flaws) remains dominant over them.
I personally updated Remix v2 project to React Router v7 and because I used various flags to prepare for the upgrade, it was done without any issue and fairly quickly.
> entire library in massive, backwards-incompatible ways ... EVERY. NEW. VERSION
So a new major version has some breaking changes? Why is that surprising?
I also like the server side, PHP works better for me than a Javascript server. I've had some weird bugs with nodemon, pm2 and other server tools.
It really doesn't do much, which is very refreshing coming from Nextjs.
It's simple tooling for backend for frontend-style APIs, taking care of basic routing, fetching of data, and submitting forms.
While inertia was invented for Laravel, I'd argue that it works even better with Adonisjs. Because Adonisjs is TypeScript you can infer the types coming from the backend.
Adonis + Inertia works wonderfully well. It's the best of both worlds. And the simplicity of this architecture is something to admire. It's very easy to know what's going on at every point: It's just requests, responses, middlewares and routes/views. Simple and easy, while still super powerful.
We had to choose a framework for our new app last year and were researching the current state of things. Next.js was / is by far the most popular, but also had some of the worst feedback and caution to stay away. Remix isn't perfect, but I appreciate less abstractions and working with simple request / response structures.
Also, a warning for those hiring for frontend / fullstack roles:
Over the years when hiring for roles for X frontend framework, we would constantly find "experts" in framework X that would really impress us. Whether it was React, Angular, Vue, Remix, etc. Then after moving forward, we found they didn't know core JS fundamentals and were basically useless beyond the framework.
Don't be scared by the complaints about previous breaking changes (which BTW are inevitable when we still haven't figured out the best approaches to the server/client app architecture) - React Router's current strategy using various flags [1] allows you to prepare for breaking changes well in advance.
[1] https://reactrouter.com/community/api-development-strategy
I suspect all these "all-in-one" JS frameworks out there unfortunately made people think that web apps are made of "one big happy javascript application, yay!" while it's really two (or even three) entirely decoupled runtimes (backend & frontend) instead.
This one has been the most over-hyped, vendor locked-in and completely vulnerability ridden web framework I have ever seen.
It's so much easier to hire people to do prioritisation (or deprioritisation) or code of conduct enforcement or whatever than to just do good work.
Seriously, give Elixir a shot.
Next.js is 8 years old and still under-documented, and you will still get lost if you veer off the beaten path - of which sometimes there is none.
Frankly, I was mad at myself for not recognizing the hubris and their ignorance of web dev history when I noticed that they brought back directory based path convention from the 90s. That should’ve been the red flag that stopped me but I fell for Vercel’s fonts and web design.
Investing in an implicit and inflexible routing pattern such directory based routing that was used when we didn’t have nice things is like being a rich hippie. Oh it doesn’t stop there. Isn’t it cool that you get to (jk, you HAVE TO) name your files like ‘[path-that-takes-arg].tsx’? You may think that I used brackets as a placeholder signifier, but I didn’t! Brackets are part of the filename and they indicate that this route takes params.
Look, we all tried and maybe had a little too much fun inventing and sometimes reinventing clever patterns we shouldn’t have, but few of us doubled down and just ran with it for so long.
Luckily, you can get around the pattern above pretty easily by just using the one route as a router file and adding your own indirection. Obviously you miss out a bit on tree-shaking and probably some other optimizations they designed to rely on their implicit conventions but your codebase remains greppable.
truly hate how hard these guys have made my job by making react popular.
https://loglayer.dev/example-integrations/nextjs.html
Overall, the logging experience in Next.js is terrible, and not being able to chain middleware, even more so.
I don't see this as a major problem, since there are so many ways to work around it if you really don't like the tradeoffs.
imo, if docs never give a clear example of what something is for, that's a pretty good sign that this was just tacked on without considering any particular use case. i've come to realize that nextjs probably intends for us to use RSCs for most middleware-like behaviors
It seems Middleware in Next.js is not what Middleware is in framework X. This whole thread looks like a complete collection of misunderstandings of Next.js.
It's a bad framework for building full stack apps, but it's better than anything else.
now that rather seems sane compared to next.js stuff n other javascript things.
if you gotta use typescript while not use java and at least benefit from the ecosystem of the jvm ?
for me I will stick with Rails - that's what I know
In python / bottle.py this would just be a print statement to stderr in before_request() or before_response(). One additional LOC.
got me good
- Start the highlight on the 64th element/paragraph. Inside of that paragraph, start from the 25th character.
- End the highlight on the 65th element. Inside of that element, end at the 174th character.
- Scroll the user to element #64 on page load.
They've then got some code on the page to add a highlighted span starting and ending at those points.
If the site maintainer is here: For me, the links are currently broken, as they should link to https://blog.meca.sh/3lxoty3shjc2z/l-quote/64_25-65_174#64, but currently link to https://blog.meca.sh/3lxoty3shjc2z/l-quote/64_25-65_174#64_2..., and `64_25` isn't a valid id on page-load.
I've reported the issue here: https://github.com/hyperlink-academy/leaflet/issues/196
That's fine. It works fine.
I don’t need/want to elaborate.
I’m divide my frontend and backend via pikku, that way I can continue using normal server side functions but optionally spin up a seperate api service if needed.
Haven’t really tested it on vercel as much, but it ignores middleware on the nextJS side unless it’s for frontend code.
https://pikku.dev/docs/runtimes/nextjs-app
Disclaimer: I’m the pikku core developer
These days vite is far far nicer.
Nextjs and most web frameworks assume you're building an e-commerce site that has to only differentiate on loading speeds.
Honestly, nextjs is not that bad and I would go as far as saying that it is perhaps the best web framework I have ever experienced but it does come with its own problems which might be overwhelming for beginners.
Why I'm writing pure HTML and CSS in 2025:
https://joeldare.com/why-im-writing-pure-html-and-css-in-202...
When I see Next.js on a job posting as a "requirement" or even as a "something we use" I immediately discard it
makes more sense to go full CRA though. it's just a view
The truth is, its just poorly designed software.
Where it shines is batteries included for getting started. They realized if you have low activation energy requirements, you will win a critical mass of people who put up with your crap. A good metaphor for devtools overall.
That being said, our app is largely built like a standard React app, we aren't using much server-side-rendering, and we use TanStack Query for loading most data. So, the main value of Next.JS is mostly just the routing and project organization.
I've loved all the Tanstack libraries so I'm looking for an excuse to use Start lol.
React Router + Express?
Or something else?
For my team, React Router 7 just gets out of the way. If you use it in framework mode (SSR) you will have loaders and actions, which are things that run on your server. I find it SO much less convoluted. The logger example from the article above is childs play in React Router. Either import your logger and run it in your loader. (You may want to add .server.ts to make it explicitly ONLY server) or inject the logger via context.
I recently developed a small internal application in NextJS and we are using Azure PostgreSQL, we are on the Pro Plan from Vercel (honestly even that's an overkill, our use case would be satisfied easily on the free plan; which is very very generous) but one problem I faced is a NextJS App hosted on Vercel, it will never have a static fixed IP, so we couldn't directly access our database unless ofc we opened it to the entire world, which is never an option. This is so dumb honestly, the audacity to call it a full stack framework is stunning.
Case and point
“Use server” “Use client”
Intuitively, one runs on server and one on client. But you would be wrong. It is far more complicated. Now multiply this by 100 features. What you get is an obtuse hard to penetrate framework that seems to behave unpredictably unless you carefully read the thousands of pages of docs.
Now ai doesnt help as the api changes so frequently that it often spits out version 13 and not 14.5 let alone 15 or whatever is most recent.
This likely happens due to the need to rush features out for the next nextjs conf much like many other saas providers rush for their respective conf.
Another thing I don’t know how to think about is the target market for nextjs seems to overlap with Ruby on Rails, a lot of e-commerce, media, etc. And most of these B2B apps I write are certainly not that…
One of my latest experiments was using vite.js and then using a go backend where I embedded the vite app using embed.FS. I haven't tried it in a live environment yet but it seemed like a potentially nice way of doing it.
Just to make single "log("hello") appear anywhere, in a file, in a console, as smoke puffs in the sky.
Infuriating, frustrating, agitating AF.
Turning off logging in a production system is brain damaged move because inevitably production is when you need it the most.
Still love Next but it's because I drank the Kool aid early on. Would be intimidated to learn it anew in current state
It handles edge-cases extremely poorly, and when you have those scenarios, you either need to find a workaround (so code becomes ugly and painful to maintain) or give up.
I've worked with it for a project, gladly never again.
I'll extend my feedback about Node.JS backend. Look how many flavors: deno, bun... It's a mess.
Node.js a terrible platform for server-side in comparison to Java/C#(performance/stability) & Ruby/Python(dev speed).
The only reason it is successful is that everybody knows JS/TS. But just because everybody knows it is rarely a reason to use it.
The event loop is quite nice and easy to reason about, but that's all there's to it. It is single-threaded and comes with gotchas, with at the end being in my opinion a negative aspect of it.
Many other langs/platforms offer also an event loop for concurrency, but they aren't often used. In the end no matter how much we hate threads, they serve a great purpose that has been battle-tested for so many decades.
Unfortunately companies adopt programming languages based on hype and trends, rather than technical reasons.
Until when we will have people hyped up about writing web servers in CSS, even though it doesn't make any sense to?
TLDR: It isn't only Next.JS, but the whole NodeJS thing isn't that great.
Everything can be a word if you know what you're trying to say. Don't let anyone tell you otherwise. If they try, say: фakdelengiчpolis!
Even though I'm a fan of looking for underlying motivations to what people do, I'd be wary of pointing out "only" reasons for anything. I know it's a rhetorical exaggeration, but still.
For example, I've found Node to do what Python does, only better. For example, Node does dependency resolution without involving the OS package manager. And ultimately, people end up using whatever they become comfortable with.
Which is not an exact science and people resist it being made into one. (Maybe if it was, it'd be much easier to sell people on working with the "least worst" tooling that is not actually good for anything.)
But the important thing is that on the backend they're all different. The baseline is the CPU, and you get to choose between real tools with real histories of real tradeoffs. Even if the tradeoff is "run JS" or "be written in C++" or smth else.
On the frontend, the baseline is JS, and whatever the browsers bolt to JS, and as us few sane keep pointing out, JS land is already such an "OS-within-an-OS" that there is very little point to building entire freaking frameworks between that and the application, just for the sake of having to swim through someone else's moat instead of invoking the APIs directly (which are also better designed for the most part).
So, in order to differentiate the market, one would need to build at least 1 "layer of layers" on top of JS, some products in which are gonna more pointless, while others are gonna be less pointless (all of this to all different people of course). That way the user gets to choose between what sucks more vs what sucks less, and one gets to feed on the attention paid to the choice of lesser evil; or -- if insufficient attention is paid -- to entirely direct the choice in whatever direction. It's a win-win.
I find it infuriating how people don't utilise any TSC based compiler plugin codegen, to automate two way sync for database entities...
Millions lines of code, for nothing.
Every day that went by I wondered if I was going insane for thinking we should just go back to building apps in straight vanilla javascript. Or like, just react SPAs pointing at fastapi apps deployed on s3, which has never failed me.
For many years I'm advocating the community to be very open about the history of web stack (and JS in particular) and be honest about it's suitability for the modern software development. The level of accidental complexity in this stack is insane and people seem to embrace it add more and more layers of it.
Personally, I try to avoid using it as much as possible. And it works beautifully. Of course, tradeoffs are everywhere, and the sheer scale of the web development community has its own benefits. For example I miss the wide choice of alternative design systems in Flutter (compared to web), but hey, flutter now decoupling it's core from design systems in 2026. But the net effect of not using fundamentally flawed tools for your products is huge.
For web apps? How is the performance? How is the developer experience?
Developer experience is... well, I usually develop app while running it locally as a MacOS desktop app build. Just much easier to use with hot-reload and Flutter dev tools. Often using DevicePreview [1] wrapper to check against different sizes, dark/light mode, font scaling etc. Unless I'm working on something platform-dependent (like push notifications or a QR code scanner that uses camera/ML frameworks from OS), I don't even test it on mobile devices or web - I know that it will look pixel-perfect. There are optimization caveats like "emojis are not included in the web build by default to decrease the size", but otherwise web build looks the same way pixel-to-pixel as MacOS or mobile view. Test I run with maestro in iOS simulator.
Centering widgets ("<divs>") is never a problem, haha. Having a properly designed layout system is a no-brainer and thousands of times better experience than that pile of hacks on top of hacks called CSS.
Still, my main issue with the current Flutter design is the tight coupling of two main design systems (Material Design and Cupertino) and the core, and the lack of a wide choice of alternative design systems. Just to make it clear - it's extremely easy to create your own widgets/themes/look-and-feel in Flutter app. But having a well-thought-out design system is a different beast. Luckily, decoupling is on the way [2] and I hope it will lead to a boom of nice design systems implementations.
Also, because Flutter originally was targeting mobile development, and expanded to desktop/web almost accidentally, the majority of the widgets are optimized for mobile UI. For example, if you want a date input field that feels native to a desktop user, with masking and yet a calendar picker – good luck finding one. And as I create desktop/mobile apps 50/50, I settled for now with forui [3] design system, heavily inspired by shadcn.
Performance has been the last of my concerns with Flutter, because the engine was originally heavily optimized to hit <15ms frame rendering and modern web renderer is using Wasm and shader precomilation and some dark magic I don't even want to know about. And to be honest, my own experience with "web apps" is so bad, that I don't think any non-native-to-browser rendering pipeline can make it worse. Like, having UI glitches and unresponsive components, bad state management, need to refresh the page (which is essentially a "restart an app" in web), mess with forms/fields it's just such a normal experience in web. I don't have any of that with Flutter web apps. They might feel a little bit "non-native" to HTML-based web apps, but I never heard real users caring about that.
[1] https://pub.dev/packages/device_preview
[2] https://docs.google.com/document/d/189AbzVGpxhQczTcdfJd13o_E...
Don't waste your time.
They're all almost the same (crap), but the real issue is the instability of all of them. They change every week, they're constantly pushed sideways by the VCs or other interests behind them (or the constant mind change of their devs, i.e. React Router.. I mean Remix... I mean framework mode... I mean now we nap and then invent our own frontend framework but keep the old name, just to add a bit more to the confusion and keep everyone entertained).
They're overengineered, complex, and promote the little shiny "look how fast this counter updates in a type safe way" while they totally break down when you have to do real world serious stuff like authentication (ehh...go and use this SaaS..), authorization (ehh..what's that? just put an "if"), translations (who speaks other than english?..no need for that), background jobs or anything else a real world application needs. They're focused on the shiny "typesafe call server function" and everything else is just let on you to figure out, and good luck with the library you pick, because next week it's going to be a different one and you'll be out of fashion!
Many years ago I started using Inertia [1]. I'm confident to say it's the right, simple, most effective way to use React/Vue/Svelte. It's a super simple "protocol" with very thin adapters implementations that glue together your favorite frontend lib (react, vue, etc) with your favorite full stack backend framework (laravel, rails, django, adonis).
I've used it for client projects with both, Rails, Laravel and Adonis. I have no complaints about it. It works super well, follows a simple to understand model and you literally get the best of both worlds: a powerful frontend, and a powerful backend. It keeps things simple and stable using rock solid battle proven production ready building blocks with great documentation and community support.
I'm just done with all these other "meta frameworks". They're all marketing and hype and everyone is swallowing it and then ending up cornered with a terrible solution and a lots of problems they didn't account for and have no official or recommended solution to get out of it.
That won't happen if you use plain React/Vue. That won't happen if you use plain Laravel/Rails/Django/Adonis. Inertia just glues plain X + plain Y. No lock in. No possibility of being "stuck" in a situation where "I can't do X because...."... you can.. and you can in a very nice and clean framework-supported way.
It's a fantastic undervalued idea, and we're not paying enough attention to it (yet).
Don't fall for the marketing and the hype. Look for the simple and pragmatic solutions, they're there. They work. They're just not as hyped, so I'm hyping it up a bit for you in this post. Apparently that's what everything needs: Marketing.
The middleware issues the OP describes are not bugs, they are symptoms. When you can't get basic logging to work, when you can't use WebSockets, when you are forced to deploy on edge runtimes that don't support Node.js APIs — these are all deliberate choices to push you toward Vercel's platform. Guillermo and his team have prioritized their cap table over the open web.
This is why I started https://github.com/openuiai/next.js last month. The web is humanity's greatest collaborative achievement. We are building toward a global, decentralized network that should enable unrestricted computation and storage for everyone. And for that to actually happen, we need frameworks with the power and flexibility that Next.js used to have. But instead we are all watching Vercel carve it up to lock developers into their platform
Next.js used to be great. Now it's a trojan horse for vendor lock-in. The fact that so many developers are comparing it to SharePoint and Lotus Notes should be a wake-up call.
To everyone frustrated: you are not wrong. The framework is ACTIVELY working against you unless you are on Vercel.
I'm working on OpenNext.js every single day — still climbing the learning curve of the massive spaghetti codebase, but fully committed. We are already running OpenUI on a fork with full Node.js middleware support and native WebSockets. These will merge into OpenNext.js once I have properly cleaned out the cruft (their CI/CD alone has cost me $400 just figuring out how to untangle it). But I'm taking the time to do this right.
Guillermo: Vercel/Next.js shouldn't dictate where we can deploy. It should respect the open nature of the web. You know this, but you chose the money instead.
I was talking to a fellow dev at the company I work at and he was extolling the virtues of one-click nextjs deployments. As the conversation progressed it turned out he'd never actually had to set up or manage his own servers and felt that it was a waste of time for him to learn.
It hurt my soul. I am considering linking this article, but i feel it may come across as aggressive.
After using it in three production-scale projects now, I think it's a great isomorphic JS / TS framework. It's as close to a "batteries included" (such as Rails or Phoenix) system that the JS ecosystem has.
And yet, people generally like to shit on Next.js I sense because they haven't taken the small amount of time investment required to actually just understand it: which I fear is especially true if they came from Pages Router. This kind of fallacy appears to hold true in the OP -- bemoaning that you "can't have multiple middlewares or chain them either"... yes, you can? Sure, it's different from the Express way of doing things, but you absolutely can get it to do what you want.
Was Express ever _that_ easy before you actually understood it and knew what you were doing?
yes
also sails.js was the bomb.
A RoR app will just sit comfortably wherever you deploy it, slowly doing its job like a good, reliable tractor.
A typical Next.js app is smeared all across its origin, some geographically convenient Edge and the frontend. It's a very different use case.
Also shout out to Pinia, I love you!
Everyone complains that react is so slow and horrible, it isn't. It's their code that's slow and horrible, react is snappy as hell when you use it properly.
That's the problem though, it's hilariously easy to shoot yourself in the foot with React. If almost every project makes the same common mistakes, it ceases being an issue with the people using it, it's a broader problem. With Vue or Svelte you'd have to try damned hard and go out of your way to mess up in similar ways, because the idiomatic way of writing Vue, especially with Options API, is so simple and straightforward. How many articles do we have out there begging people to please stop using `useEffect`, for example?
Plus, React's reactivity model is terrible and a source of a lot of performance pitfalls. Vue's and Svelte's Proxy/Signals-based approach is much more performant out the gate, and in the case of Vue the diff reconciliation algorithm is a lot better than React's, which itself will already prevent a bunch of useless re-renders compared to 'standard' React apps.
This isn't just a react problem by the way, people write horrible messy backend code as well so I'm having a hard time believing that they wouldn't find a way to make a horrible mess of a Vue app as well.
But maybe you're right, maybe it is better. I wouldn't know.
I'd recommend giving it, and especially Svelte, a try, especially with Options API in Vue (but CompAPI is nice too). It's really clear early on how simple it is, despite it paradoxically having more to it than React does (like the event/prop system)
Why use something that you have to use "properly" when there are things out there that enforce being used properly?
And just to be clear I'm not saying react is better than Vue. I don't know Vue. Maybe it is better. All I'm saying is react is alright in my experience, the problem is people overcomplicate and mess things up. I've seen that in pretty much every piece of software I've ever worked on, backend/frontend/whatever. So the claim that Vue just magically can't be messed up is difficult for me to believe.
With Vue I started to use Pinia for my whole apps state management, which are data stores. Clean and centralized logic, with React idk what a substitute would be.
I know React can be clean too, but that (in my opinion) requires a lot more depth of knowledge about the framework.
Saying this as someone doing Web related development since 1998, glory days of Perl and CGIs.
Because anything Java, .NET and Python, it certainly requires configuration and related infrastructure.
I think you haven't used .NET in a while. Nowadays, logging is absurdly easy to configure. Heck, you usually don't even need to configure it, because the basics are already included in most templates. You just use the Logger class and it works.
The only time you have to spend more than 30 minutes on it is when you use some external logging libraries. And most of them are quite sane and simple to use, because it's so easy to create a custom logging provider.
Java, .NET and nodejs are all over the place around here.
The point was without configuration.
Logger class doesn't do the work for production monitoring, without additional configuration so that its output appears on the necessary production dashboards.
Spring Boot doesn't provide a serious production quality deployment without configuration.
Bare bones logging into standard out, yes.
That isn't production quality.
Production quality is telemetry logging, log rotation and zipping, forwarding logs to Kibana or Datadog dashboard.
Word vomit into standard output isn't production quality.
I do whatever I feel like, you're the one that started down this thread, don't complain where it goes.
https://github.com/angular/angular/pull/43529#issuecomment-9...
It's kind of funny in hindsight, but at least we didn't have to modify every project just to update such a minor thing which was working already anyway.
In this regard the thing that absolutely sucks is the migration tool. Your best course of action is to update the versions manually in package.json, read the documentation on breaking changes and act accordingly.
In my view Angular was always insane, but it's becoming saner with each subsequent version. We now have typed forms (that took a while), standalone components and, most importantly, signals, which do most of the stuff RxJS is doing, but without the junior-killing hidden state and memory leaks.
For an upgrade someone has to pay for it anyway, so whatever pains there are, they are reflected on project budget anyway.
More devs should do the math of work hours to money.
I have not worked with older versions, but with V20 & signals, it has been pretty good.
He still ended up sneaking some metaprogramming capabilities into it, though he stopped short of something recognizable like macros.
So when the highest grade vendors started taking front end extra seriously since I'd say 2008-2010, what they built basically bulldozed over the things that made JS per se tolerable. Instead, they built frameworks out of the standard imperative primitives in JS, which take things in more of a C++-inspired direction.
The "growth hack" is here, as with vaunted Apple, vertical integration. The only way to couple markup to state management to server/client flow does not amount to a framework; it amounts to no framework since the Web was not invented by VCs.
To get a framework out of it, i.e. couple developers' practical knowledge to your ecosystem (turning it from general to domain specific but fuck devs right), you also need to couple things in your stack at the wrong places, as exemplified by the already much-maligned misfeature explored in TFA.
I.e. for the onboarding flow of a hosting business to work in 2025, you first need to have been teaching bad architecture for a generation. (It's why Meteor.js didn't take.)
On the one hand, pragmatic of Vercel to exist in the long shadow of the React/TS monstrosities. On the other hand, it's just one more company whose mere existence in this world has contributed for my work and life becoming harder for no real reason, even though nobody I'm within a handshake is even their customer.
Like many, I only learned of them only when I googled, "who the hell made this horrible thing the frontend team over is now stuck with, it's 0.01xing their velocity and frying their brains besides" and, well, now they're here. I would like to remind them to try and measure their externalities.
So you need (1) the knowledge of what platform APIs exist (2) the ability to reason about existing abstractions (3) the ability to define abstractions.
In modern life all three are considered unsafe things. Therefore to prevent people from entering invalid states exists The Framework: useless abstraction layer that does nothing besides be conventional. That's a common enough pattern anywhere population's above Dunbar; whether it's embodied by React or TypeScript or Windows or an entirely different order of lowest-common-denominator monoculture is immaterial.
Thankfully, software maintains an objective material component - the code, which they're trying to now turn into another wishy-washy thing you interact with using endless imprecise human language. Purely in terms of that, it remains possible to propose some ways to get a project off the ground more efficiently by virtue of dodging the toxic mainstream:
TL;DR conventional: native DOM manipulation; state management with Observable; Vite; TDD.
TL;DR forward-thinking: same but in proper static language: write in Rust, compile to WASM.
TL;DR exotic: ClojureScript or another Lispy language that compiles to JS or WASM.
Ofc, unless totally cowboying it, you also gotta be able to counteract the illusion of social proof. Ideally you want to be actively shaming people for building and normalizing bloatware. Preferably packing 1-2 yesmen worth of social proof of your own, just to get basic parity with the "best practices" in close quarters.
As always, depends on what you're building, for what purpose, and, critically, with whom... fuck all that though, the objectively bestest solution is always https://github.com/Matt-Esch/virtual-dom /s
That repo is a milestone of where history took its next wrong turn. I remember it making some waves when it dropped, and it's certainly the first VDOM implementation I saw. I considered it a good, original idea.
IIRC, React came around about that time: to take the simple and sane "VDOM" optimization, apply it judiciously (i.e. where it doesn't), and make it possible to bolt enough shit onto it (redux! teaching you to type the same thing thrice before typescript! SAGA! that one weird DB paper from '74 applied to frontends JS' half-baked half-async "generators", just to demonstrate to people that they should revere the old CS publications, and definitely not anything like read them or reason about them!)
Just so that people could hold bloody bootcamps about it, where they'd be able to weed out any junes capable of reading MDN for themselves. ("Bootcamp" is another cosmic joke like "Instagram" and "Trump". That thing where they harass people into obedience then turn them into socially sanctioned murderers? Ok checks out, let's name our programming learning experience! It's nothing if not profoundly mission-driven!)
Back in those days or a little later, I remember Vue 1 and 2 being pretty great: it somehow managed to do its thing without first having to introduce three whole new dialects of JavaScript and counting.
Overall I'm glad to be out of the frontend space for a good while now and only learning about it from the confused screaming of those still trapped there. (Oh and also Next's "static build" is a Docker container I had to cook up myself, which is a next level of ridiculous; as with VDOM, you first need to have seen the past level in order to recognize it as regress, and I presume a lot of people simply haven't had the opportunity to pursue any form of informed comparison)
(For "agentic workflows" idk -- just don't use them ffs the externalities are not remotely priced in; otherwise you'd be the exact same problem as them -- the designed-by-corporate-committee frontend DX of the past decade certainly strike me as something that'd make more sense to a statistical model than to a human mind.)
Old Vue is nice, we still have some Vue apps and they’re just running without major headaches. I do recall some distinct issues with properties introduced on objects after initiating the component not being reactive, but it has mostly been an acceptable experience
That's probably the better outcome here. If you know enough things to find what I wrote entertaining, rather than vexing, chances are you're able to pick right tools for jobs just fine.
Meanwhile treadmills are gonna treadmill; if I've got one answer to everything it's to stay off them. Mighty difficult when everyone's trying to drag you onto one.
I do recall some distinct issues with properties introduced on objects after initiating the component not being reactive
Wasn't that what they fixed using Proxy (making ES6 finally a hard requirement for anything at all)?
>Old Vue is nice, we still have some Vue apps and they’re just running without major headaches. >but it has mostly been an acceptable experience
Better than one could say about the current generation stacks. Big vibe like vendors are trying to cargocult ZIRP-associated patterns (as if those were what produced value in pre-2020s Web and totally not all the human creativity that used to be channeled into the medium before the masks started falling off.)
Maybe, but I haven't touched Vue in a long time.
> Better than one could say about the current generation stacks.
For sure. I still have some projects that use what I like to call "jQueryScript", where there's just a bunch of unprocessed (or only minified) JS files with `$("#foo").click(function() { ... })` stuff everywhere. Looking back, it wasn't all that bad.
I just wish there was a pattern that is simple, works with plain, modern JS without any big dependencies (I don't want 600 node modules installing a frontend framework, please) and is easily modular and integrates nicely with other stuff (so likely either manipulating DOM nodes directly or using WebComponents)
Out of protest, I have some smaller projects that have their GUI templates stored in `<template>` tags and manipulated with plain Javascript. Anyone that opens the code will see it and think "wtf?" and then be like "oh... uh sure". The largest one I had written was 1000s of lines of code like that, kinda like a classical MVC pattern where a view (class manipulating DOM nodes) renders a model (a JS object or class). The controller would subscribe to custom events (defined by the view), update the model and call `render()` on the view. It had a lot of small classes, which was a bit too verbose to my liking.
Do you want to be a spirit haunting the threshold in half-agony, half-but-also-mockery? It's accomplished by the "Figuring Out How NPM Packaging Actually Works So You Can Write Proper Isomorphic Business Logic" ritual, a fell rite from the forbidden "Uncomfortable Truths About The Presentation Layer" grimoire, and one that a lot of them would be better off with you not knowing, and now you do ;-)