It's not just you, Next.js is getting harder to use
propelauth.com
propelauth.com
Some issues we ran into:
- The dev environment is too finicky. Full page reloads instead of HMR and random errors after x reloads.
- Cache is a black hole and works differently between dev and production. They’re changing things up now with v15, but this lack of stability is not fun to rely on.
- The file based router has its limitations. For instance: having the language in the URL means your entire tree remounts when the language is changed.
- No clear way to bootstrap specific stuff outside of React
- Portals don’t seem to work on the server.
- very easy to mess up auth stuff. At some point Supabase even put out a YT video [0] where their implementation caused auth to be accidentally cached. There are 3 levels of checks you need to do just to be safe, but this is all very opaque.
For me it also wasn’t clear how to combine client and server state. These patterns haven’t been defined yet and I kept running into hydration issues with no clear solution.
A year after the app router the eco system still feels very much in limbo and brittle.
I also worked with Next as a replacement for Gatsby’s SSR, but quickly discovered that there’s no easy way for Next to just pre generate all responsive image sizes it needs for a static output like Gatsby has. You need to implement a custom loader and rely on something like cloudinary. This is ridiculous for a completely static site.
But I have a mixed opinion on the big Context object. It may help to write less verbose code, but it can also cause OOP's antipattern God Object[1], even though the context is more of a namespace rather than a big object.
// Not
app.get('/hello', (c) => { return c.json({ greet: `Hello ${c.req.params('id')}`)
// But
import { jsonResponse } from 'library'
app.get('/hello', (req) => { return jsonResponse({ greet: `Hello ${req.params('id')}`)
[1] https://www.wikiwand.com/en/God_objectFix: format
Doesn’t sound like a great idea to me.
If it's something like m4b-tool[2] or tone [3], that has to be maintained for a while, I tend to use battle proven libraries or frameworks (in this case Symfony, because it is an older project and Spectre.Console and atldotnet for tone). I prefer libraries over frameworks though, less background magic.
However, I have the feeling that you also find something in this comment that you don't like - maybe the shameless advertisement of my FOSS projects ;-)
1: https://github.com/sandreas/pure-todo
At some point people will realize there’s some value on full stack batteries included frameworks that have been around for a long time.
As I already said: My comment was not meant totally serious, I also hate this framework hopping... although hono.js is promising.
- very easy to mess up auth stuff. At some point Supabase even put out a YT
video [0] where their implementation caused auth to be accidentally cached. There
are 3 levels of checks you need to do just to be safe, but this is all very opaque.
Auth is all you need. It is a non-functional requirement in that your site is non-functional if auth is broken.In the large it is Yahoo or Google or Facebook buying a site and hooking it up into their entire service but in the small it is "I want an email newsletter script" and instead of messing around with HMR and file-based routing and other inessentials to develop my own, I just pick a best-of-breed application and hook it up to my user database and auth system and I am in business. (Today, without a clean API, I can hack that application to query my user database and be behind my auth module if the tech stack is sufficiently similar to my own at risk of braving whatever inessentials that route entails)
Because we haven’t seen good frameworks at the user management level, I think, the mistakes made by the creators of that YT video are common in the industry.
The docs were absolutely amazing, dev server was super fast, the build times were fast, I could easily create server side and static sites, host them on Vercel easily, good times all around.
Then came the Vercel + React partnership and it took things in a different direction. Now React almost became a child of Vercel. All of a sudden, the focus instantly shifted to server side from what was earlier client side & server side both. Breaking changes, added complexity and the strange co-existence of 2 routers, out of which the old one (which works perfectly fine btw) is certainly set to become obsolete in the near future leaving us with no choice but to move to this 'new' router.
Next.js app router is extremely slow. You don't even need to do anything special, just compare the dev server compile times of Next.js v12 vs v14, the performance has decreased. The dev server sometimes occupies gigabytes of memory, why?
Can I also mention the 'new' but worse file-based routing system that forces every page to be named page.tsx? Who thought that was a good idea? They simply copied Sveltekit. This even forced the VSCode team to introduce a way to edit the tab names because every page being called page.tsx is undoubtedly worse DX!
All good things come to an end, and I certainly feel this way now with Next.js. I was a proponent, I recommended it to everybody who was looking to build apps with React but now? I'm not so sure anymore, considering how confused they are about their own decisions (refer to the v14's caching controversy).
I'll be jumping ship to a better product as soon as I find one (and I'm sure there will be in the future). For now, I'm just sticking because of the years of familiarity with React.js and Next.js. They have served me well but Next.js has simply become Outdated.js as far as the future is concerned.
They changed their whole state management system. It's like using a totally new framework now and it looks very much like React which is strange because Svelte was supposed to not be like React and offer simplicity in code.
I think the best contender right now Solid.js but it needs some financial help and the fanciness of Next.js to attract a larger developer base.
I’ve gone back to Vue for now.
I’m glad I noticed this early and stopped using Next on time. For me the thing that made me realize this was their “hiding” (for as much as they can) and making it more difficult than intended of the call home metrics system in next. They refuse to add a setting to turn that off, and instead want you to set an env variable or run a npm command.
Just think about they do this and refuse to add a setting.
That’s how you know who you’re dealing with.
Also, Next.js is becoming like Angular: The progress from Angular.js 1 to Angular 18 was necessary for solving the problem of very hard front-end web development. So I'm guessing this Next.js contender is trying to become the Angular of the back-end. They're basically turning into the theoretical computer science constructs that they must become. Script kiddies and non-computer science students need not apply.
A part of HN history, if you will, making light fun of the "it's just a wrapper" idea that transitions into a multi billion dollar company, because only naively is execution and the integration of different ideas a trivial task. The people at NextJS are obviously(?) doing something that's not just Express and you can look at the version history if you are interested in identifying those things.
Of course, you might not think of them as important. But that's a very different take.
Setting it up was a hassle and so was hosting it. It's a great tool, don't get me wrong but after using Next.js, I never needed it.
There's also Hono (https://hono.dev) now, which is like Express.js but better.
How is it possible that there are people active in this industry who think setting up Express is a hassle?
>hono
Seems absolutely the same to me, their getting started shows no login mw (only already token-ed auth), and it’s just a single context param instead of (req, res, next, res.{text,json}). What’s so innovative there? Feels like yet another cute solution looking for a problem.
The biggest issue with apps like NextJS is that they didn't explicitly build upon and expose the Express API. What they should have done is client-side app routing with a version of Express that runs route handlers in the browser. They also needed to add parallel middleware that runs in both a browser and server context. That's the only sane way to support functionality and components that run in both the server and browser context.
The entire NextJS architecture is flawed because they picked the wrong pivot point.
We want to be making sandwiches from store-bought components. Sometimes we do need to swap out the bread and NextJS has the wrong abstractions to do so which results in all sorts of soon-to-be-breaking-changes-spaghetti to work-around the deficiencies.
It would have been much better to maintain an application by working directly with requests, request middleware and request route handlers, with a mock request corresponding to mouse events for the client-side.
The request-response cycle is the fundamental nature of the web application, even in the browser.
My strong suspicion is async locals. I found some references to next related async locals hanging on timers recently: https://lucumr.pocoo.org/2024/6/5/node-timeout/
Maybe it's time.
A company I workerd for has a large nuxt app they won’t be to upgrade any time soon.
"I care way more about the speed at which I ship features, and all that complexity becomes a burden on my dev team."
This is exactly why I started building ZenStack(https://zenstack.dev) toolkit. The goal is to brings simplicity back to building SaaS applications, using whatever framework you like.
They do love to collect shiny things!
Over here in Angular land not much has been happening. Ok, we have signals now, but that's about it.
If you want simplicity, use htmx and your backend framework of choice.
Angular is actually very nicely laid out as a front end framework. I’m finding the modern react ecosystem more obtuse than old angular apps.
Things _can_ be done in a simple way. The issue with React is that it's just a library, and there's some gaps it leaves that companies like Vercel tried to fill (and abused, but that's another topic). So then you get a bunch of new-ish developers who haven't even properly learned react throwing in a bunch of random libraries they also don't fully understand how to use, and you end up with a shit soup. Not because the ingredients are bad, but simply because the cook didn't know how to use them.
I've seen people abuse React. I've seen people abuse Redux (and extensions). Even with there being ample resources for both.
People want to try to be creative withou planning ahead, and then things happen and the business wants to go on, but devs are rarely given time to integrate and apply stuff they learned from previous mistakes, etc.
So while some of the problems are technological in nature, I think the biggest problem is not the technology itself, but how it's combined with inexperienced developers
With that said, I'm also a big fan of designing APIs that are easy to use, and difficult to misuse. React has areas of the API which fail on both of those principles though (I hink some of which they want to address with the React Compiler)
I'd put its quietness (relative quietness and least) forward as one of its redeeming features and an example of its stability.
Also it keeps all the thrill chasers out, which is very helpful in delivering things on time and within budget.
Of course it would be better if we had some creature comforts like fast compilation times and good performance by default, but not at the cost of introducing the sort of chaos the React people live and breathe.
React terrifies me. Nothing is consistent. Everything is always a little broken and maintenance is painful. This has been my anecdotal experience doing maintenance work on 3 diff React projects.
Framework of current project uses Vue and Vuetify - and its been a very pleasant experience. It was the easiest framework to pick up and get going amongst the three. (Though Angular is still the most stolidly consistent framework)
Don't know how it looks like for other audiences, but I'd guess e.g. HN audience on average do not like it. Just use the space to say what it actually is and does?
It's definitely not the worst offender, and that's probably why I wanted to give the feedback.
[1] "A TypeScript toolkit that supercharges Prisma ORM with a fine-grained Authorization layer, auto-generated type-safe APIs/hooks to unlock its full potential for full-stack development."
It just seems exceptionally slow to another stack I've seen. Whether this is poor docs or bad implementations, I'm not entirely sure, but it seems there is a major issue with it - I do not see in my analysis any other stack having anywhere the amount of issues that nextjs does.
The main problems I find are exceptionally poor TTFB on their server side rendering. This then pushes people to do aggressive caching of various types (without often fully understanding the ramifications of cache management) - which improves things, until a user is eg logged in then you're back to square one a lot of the time.
The second problem is slow hydration times, regardless of SSR/caching. This causes major waterfall problems for interactivity as the nextjs bundle still needs to hydrate before most (any?) interactivity is possible.
While all SPA-esque frameworks suffer with this kind of stuff, nextjs just seems to take it to the next level and it often does not seem trivial to fix when I report the issues.
[1]: mostly because I have never been interested in the modern form of SSR due to my controversial belief that that is a truly _insane_ solution to SEO, TTFB and page load performance. You don't really solve a problem by piling more problems on top, however many billion man-hours a whole industry spends on that endeavor.
More importantly you shouldn't need to restructure the codebase if the application routing changes
File based routing is a terrible idea
I see why Vercel would want everyone using SSR and their opaque server-side caching, but why do generic non-FAANG-scale web apps want it on day one?
When Next became a Vercel sales tool, I switched to React + Vite + backend, and everything just got so much easier.
I'm not a frontend dev and what I like about SSR is that you don't have to code frontend visual effects that indicate that "something is loading", you just get the hydrated page back without too much frontend logic.
It's actually wonderful
It also shouldn't be part of your product codebase.
You should not need to worry about SEO in your product itself
Typically I have a backend server written in a good language, an SPA for the app itself, and then some marketing pages written in plain html and js sprinkles, old school. It's great for SEO.
1. SPA with html css and a bunch of js hosted on cdn, talking to pure REST api. (For apps behind login)
2. Php style Server rendered pages with a sprinkle of inline jquery-ish JS. (For websites)
Hybrid of both of them is a Frankenstein monster I ain’t touching.
A year or so back I spun up a new next project only to be greeted with very unintuitive errors regarding trying to use client libraries in server pages? Something like that. I wondered if I was going crazy or if this was actually going in a terrible direction.
Someone upthread said there were some common Auth footguns and I'm not surprised at all.
Maybe the warnings are to try to mitigate that.
The second project is stuck with a cryptic error that prevents the production build step from completing, and after searching through GitHub issues and even going into the Next.js codebase, I'm unable to fix it. At this point, I've given up on the upgrade and searching for a different framework to rebuild the app on. It's hundreds of pages, many of them generated by dynamic URL routes, so I'm not looking forward to it. It's a huge effort just to get the application to work exactly as it did before.
The upgrade experience has soured me on Next.js, I wouldn't start a new project with it. Even React I'm getting doubtful of its recent direction, and eyeing other view libraries that achieve the simplicity it used to have.
I've just been working with it for the past 2 months and absolutely love it. The biggest reason being the ability call functions directly from server- or client-side code! You basically only need to write API endpoints now for externally-facing services. Saves so much time and boilerplate...
Yes it is more complex than Pages Router. And while I'm a staunch advocate for simplicity where possible, I do think the tradeoff is worth it for new projects. It just takes a bit getting used to. The negativity feels a bit like hooks all over again tbh...
I'm feeling good with it at the moment, even though I'm trying to keep things as simple as possible so you might argue that I'm not really pushing it to the limits.
The major "issue" I'm having is mixing server and client components as I inevitably tend to overcomplicate stuff: if I need any kind of client interaction then I have to mark is with `use client`, but then everything you place in that component also becomes a client component. If you want to keep server components in a client component you have to pass it through the use of {children} prop which sometimes is not ideal.
Next.Js made things complicated unintentionally because they thought that a folder based mapping of routes was good and would evidently scale to their customer base's needs.
Then they were so far in that was one of the things they couldn't undo.
Oops.
Unrelated, but I've been trying to finish a project of mine, and after long breaks I would discover that my front-end code was out of date. There was already a better framework, or a new version, making your old code obsolete. I gave up after Vue 3 introduced composition API - all I did was learn "the new ways" without actually building anything.
Then I switched to HTMX and ditched all that bullshit.
https://renegadeotter.com/2023/09/10/death-by-a-thousand-mic...
It's related, I think.
In a truly lean business environment, people would not have so much time mucking around with these frameworks. It actually looks like developers come up with zingy library and framework names and THEN they actually write them.
We're still doing a monorepo with NextJs some NX (which is frankly also rather unnecessary since everything it does can be done fairly simply with pnpm workspaces and vite), a complicated storybook setup and 9 billion libraries for components, utilities and what not. We're also still trundling along with C# even though it's 2024 and functions should be capable of living outside of classes in any language... Naturally build on "clean architecture" and "solid" which makes the entire code base a ginormous mess of unnecessary abstractions where a simple helper which does one single thing and is never re-implemented lives in 9 billion files in several different csproj's because it "might" need to be abstracted one day (it won't).
It takes me longer to figure out where things are in those projects than it does to develop an entire internal service with HTMX and Go... Which despite being a huge success for everyone, and hailed by the business itself has made no impact on our future plans. We can sit in a meeting where everyone has achieved something marvelous with HTMX and Go and still decide to keep using NextJS and C#. It's silly, but I've never really worked for a company where it wasn't this stupid and at least we're not so trapped by ourselves that we can't build things with "non strategic" tools.
Go is inferior to C# in every possible dimension: performance, package management, terseness and expressiveness - Go brings notoriously more boilerplate, Go has poorer ecosystem for writing web applications, worse ORMs and worse tools for troubleshooting advanced issues in production - the list goes on.
There are companies that do C# disservice, but you're going to hate to see what they will do with Go instead.
> Go has poorer ecosystem for writing web applications
For me personally the std http handlers is by far the best experience I've ever had with web development. Though I suspect that you may have worked with Go before the std was enough, and if so your experience was probably a little "tainted" by how the the ecosystem can be a little too "node" like.
> worse ORMs and worse tools for troubleshooting advanced issues in production
Now this is personal preference but I don't particularly like the rich debugging capabilities of the Microsoft package for C#. Exactly because it's hard to use them in production. Which depends on what sort of production environment you have, but we rely on open telemetry even for our dotnet applications. As far as ORMs go... We operate at a scale where they aren't useable. Entity Framework is quite nice... It's just that the industry has sort of moved beyond the need for ORMs. Even if your teams manage to avoid the lazy loading pitfalls your ORM is eventually going to be more complex than simply working without one. Partly because they weren't really designed for things like an Expand Contract Pattern (which you can implement, but then you're doing more work than simply writing raw SQL), but mainly because LLM's have made it sooooo easy to be both productive and remain control over your data.
> Go brings notoriously more boilerplate
I can write a struct and a function and then call it on my type in less lines of code than it takes to do the whole namespace... So I'm really not sure what you mean by this. If it's the C# magic which happens behind the scenes I think it's up to your personal opinion whether or not you want the control. As you might have guess from my take on ORM's I prefer the transparency and control.
Their FAQ literally asks if their are any open source applications built on app router: https://nextjs.org/docs/app#are-there-any-comprehensive-open...
- They sell compute / bandwidth. You can not make a lot of money if people are building SPAs that load from a CDN and execute on client.
- SSR kind of gives them some server compute but as soon as the initial page is loaded, we are back to point 1.
- Here comes RSC then. And they pushed hard. Made it look like the best thing ever. Oh the initial load time is the most important metric. You gotta make sure you hit this score on whatever benchmark thing…
- They also kind of acquired React. It is basically Vercel’s now so they can dictate the development direction.
- All this with almost no benefit to developers (compared to something like pre app dir next) but likely helps them a lot in terms of revenue.
I mean this might read like “vercel evil” post but it is what corps do and they seem to do it well.
I used next on a project recently and will not touch it again because the hype did not materialize as any type of gains during our own development.
It's like they're trying to take ideas from something like Rails without having ever even used Rails, and then pervert those ideas.
I know I sound overly critical perhaps, and maybe I'm being too harsh, but it just feels like there's this bizarre appreciation or worship of arcane complexity by Next devs. And any simplicity and straightforward-ness is shunned and frowned upon. Like simplicity is somehow beneath them, and simplicity is only for stupid plebs like myself.
I haven't used Remix, but their docs suggest it's simpler.
https://github.com/spirobel/mininext
(my goal with mininext is to provide index.php like productivity but with all of npm and typescript at your fingertips)
1. it's a mature field with many solutions already, no need reinvent the wheel for me.
2. the frontend is complex enoughJust the way to use react or vue the way it was intended to be used, paired (in a beautiful way) with a real backend framework such as Laravel, Rails, Django or Adonis.
I’m so done with every weeks new “full stack framework” that doesn’t do anything but routing and has an uncertain future.
And yes, it has a pretty nice file router built in, and useRoute() works everywhere. If file routing is all you want though, then skip Nuxt and use vite-plugin-pages (which also works with React).
- Deno Fresh: https://fresh.deno.dev/
- Astro: https://docs.astro.build/en/guides/routing/
- Remix: https://remix.run/docs/en/main/file-conventions/routes
- Nuxt: https://nuxt.com/docs/getting-started/routing#pages
- SvelteKit: https://kit.svelte.dev/docs/routing
On successful form submet change the ui based on this error state.
Now because of server actions you would just redirect to a success page..
It’s actually way simpler. It harks back to full SSR like Django/Rails/Wordpress
The webc handler does lack a few things like hydration, and this can be added if users show interest in it.
Is it similar to Vike.dev?
1. "Use the comfort of one runtime during development and the speed gains of another in production." how is that possible without hitting all sorts of backwards/forwards compatibility issues.
2. The react example you give on the front page does not seem very react-like.
- that said "Write backend code in your language of choice, leveraging the power of Wasm. Mix routes of different backend languages, allowing your application to be written by different teams." sounds like something that you might think who the hell needs that, but I've worked on a few teams, and am on one now that could perhaps benefit from it.
instead what happens now is there is a JS api that sends requests forwards to the actual backend - maybe doing some minimal verification etc. so doubling work - not all places but certain api end points where we don't want to reveal secrets in frontend etc.
As for 2, what would you consider a React-like example? The examples on the frontend are meant to illustrate commonalities between different frontends.
At the end of the day, React's weakness will always be it's model of render functions, while nice to reason on, it's close to impossible to pre compilate. That will always make React slower than template, and directives based alternatives, so people need to go into madness to get good performing react applications, and none of this is gonna come out of the box.