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.
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.
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!
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!)
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 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.
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.
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.
Why use something that you have to use "properly" when there are things out there that enforce being used properly?
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.
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.
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.
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.
* 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.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 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:
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.
I used to use Django and there were so many issues that arose from having to duplicate everything in JS and Python.
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?
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
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.
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.
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.
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.
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.
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.
Nextjs and most web frameworks assume you're building an e-commerce site that has to only differentiate on loading speeds.
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.
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 don’t need/want to elaborate.
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?
It’s just a shame it’s Deno-only (although I completely understand why)
Imho next attempts to do too much, moves too fast, every few months the wheel gets reinvented and never perfected.
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.
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.
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.
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?
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.
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 :)
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.
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.
- 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.
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...
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.
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 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.
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.
Better use something else
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!
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.
Use .run.
return LoggerStorage.run(requestLogger(), () => {
logger()?.debug({ url: request.url }, "Started processing request!");
return NextResponse.next();
});
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.
This one has been the most over-hyped, vendor locked-in and completely vulnerability ridden web framework I have ever seen.
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’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
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.
It's a bad framework for building full stack apps, but it's better than anything else.
These days vite is far far nicer.
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.
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
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.
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/
In python / bottle.py this would just be a print statement to stderr in before_request() or before_response(). One additional LOC.
pjmlp•3h ago
Saying this as someone doing Web related development since 1998, glory days of Perl and CGIs.
Etheryte•3h ago
pjmlp•2h ago
bob1029•3h ago
Klaster_1•2h ago
pjmlp•2h ago
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.
Tade0•2h ago
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.
kumarvvr•1h ago
I have not worked with older versions, but with V20 & signals, it has been pretty good.
doganugurlu•1h ago