So I'm building an application. Not only am I using react, but I'm also using node. Surely I'm using next.js right? I mean, every other article I see seems to be a next.js tutorial, it's so in right now. Well no, I'm not using it for my project.
n.b.
This isn't just a next.js diss. A lot of people swear by it after all! I just wanted to write down my personal thought process for not adopting it.
I really struggled to find a decent pros and cons list for using it, just pros. There are definitely downsides, frustrations, and compromises if you pick next.js. I just don't feel like anybody talks about them.
On to business:
Super opinionated / abstracted
There's nothing wrong with opinionated stuff per se. But the problem is in the javascript ecosystem we don't really have any standards or best practices for anything. There are 100 ways to do everything. Want classes and OOP? Sure! Want a strictly FP app? Go for it! Want to separate your concerns and heavily modularise your application? Why not! Want to just mash everything into a monolithic gross swiss army knife component? I mean... I suppose...
This isn't like making an opinionated framework in an already-opinionated language like, say C#. If you try to make an opinionated framework in javascript, you're not saying "this follows and enforces the best practices of the language", you're saying "my way or the highway!"
This first point is basically relevant to every other point in this piece so I won't spend any longer on it.
Webpack
Oh man I'm only just starting to move away from webpack and now this framework is forcing me to use it! Not only is it forcing me to use it, but it's doing its best to stop me from configuring it too.
Weighty pages
Next effectively forces you to do all of the "stuff" at the top level pages. Anything "next-y" or "server-y" has to be done directly in your pages. This creates all kinds of coupling. Not to mention your pages are also tightly coupled to your routing. This means your routing logic is tied to your page which is tied to all of your server side, data fetching, caching, everything, all tightly coupled.
I've always believed that routes should be lightweight and only concerned with which component is rendered by which route. But now I have to also stuff all of my business logic and fetching activity? No thanks.
Server routes are hardocded to /api
Next.js forces you to mount all of your backend endpoints behind /api/
. This goes back to my very first point about this being a super duper opinionated framework, where you can't even control your endpoints. I really don't want my UI framework to get to say where my api endpoints should live in my application...
Every fetch/mutation must be done in a "next-ey" manner
Everything has to be written in a way that accounts for 2 completely different rendering methods, so it can run on the server, but also on the client.
Once again, I can't just write my code in a way that suits my architecture or my conceived best practices.
Exposing low level operations
"You can now directly query the database in your react app, that's so cool!" - is that cool or is it scary? This is just asking for lazy people to directly import their db connection in a component and query it. I can't imagine some of the terrible things people have done with this kind of freedom...
I forgot I needed this bit of data. I really can't be bothered to create an abraction that retrieves the data I need in a sensible, testable context...
import { db } from '@/db';
const bitOfData = db.query(...)
I'll totally come back and refactor this later.
So now we're abstracting bits that, to me, don't need abstracting, like routing; and exposing low level backend functionality that we should definitely not be tying into the ui? Oh man.
Gotchas
There are gotchas everywhere:
For the initial page load, getInitialProps will run on the server only. getInitialProps will then run on the client when navigating to a different route via the next/link component or by using next/router. However, if getInitialProps is used in a custom _app.js, and the page being navigated to implements getServerSideProps, then getInitialProps will run on the server.
This is just one piece of confusing documentation that has tripped up friends of mine. I hear stories from them every day about weird edge cases and gotchas and "because next says so" issues. Every day I feel more validated that I don't have to deal with these frustrations.
BUT SEO!
SEO is not stupid - even without Next. With a page that just uses client-side rendering and has to fetch some data first, Google's page crawler is not stupid, it knows to wait for this sort of thing. As long as I'm adding the necessary meta tags I can more of less trust that SEO will still work.
The only major cost of not using next.js is that I can't send contextual link previews on facebook/twitter/slack/etc. They don't process javascript so I can't dynamically add meta tags to the document.
However, I don't think rewriting my entire application from the ground up, in a framework I find constrictive, just to get this single feature, is worth it. There are many many ways around this, like pre-rendering for robot useragents.
Conclusion
So there you go. The tl;dr is that I'm a stubborn developer and next.js isn't the boss of me!
So if you're not using next.js I guess you'll go back to CRA then?
Nope! I've only ever used CRA once and I ejected out of it after a couple of weeks. I quickly found that I couldn't do some of the more advanced stuff I wanted to do. Decisions were taken out of my hands that I didn't want to give up. Like typescript was being transpiled by a webpack loader rather than babel, but I use several babel plugins that parse typescript annotations. I also quickly realised there was - so - much - stuff - in the webpack config that I was just never ever going to need. I stripped out hundreds of lines of code and unneeded dependencies.
For this current project I decided to use vite
. It's still somewhat opinionated and it's super-low config but I've not yet hit an issue I couldn't easily solve with a little config.
Top comments (18)
But what about jobs, so many next.js jobs, Im having a much better time in svelte-kit, such a dilemma.
Agreed. This underpins most of my tech decisions sadly. I use Next, React, Redux, because that’s where the work is. But if it was up to me I’d be writing Vue
Oh wow, this reflects my thoughts so much that I created an account on dev.to just to thank you and comment on this post!
At the project I'm currently leading, we have two front-end apps - one uses Next.js and another that uses CRA. I've recently noticed how much time I'm spending on working out weird quirks instead of working on the app with the one that uses Next.
I had an issue with how it handled ENVs - depending on a few conditions, it wouldn't load them and instead depend on the build-time values, which wouldn't exist if I didn't bake them into our Docker images. I've filed a bug report and apparently it's been fixed, but it just shows how many edge cases there can be - in this case, the problem only appeared when navigating from an ASO/SSG page to an SSR page, and the 404 page can't be SSR so I had to go for baking the ENVs into images.
Recently, I upgraded the Next.js version we're using and some optimisation started messing with my fonts - either wrong ones were computed, or the fonts didn't load and the browser used a fallback. Turning off the font optimisation in the config file didn't work. It appears that Next expects the font stylesheets to only be referenced in a custom document, I couldn't use @import in my CSS files anymore. Oh, and this only appeared in production builds.
Next is a really cool project that does a lot of things right, could be the ultimate way to create web apps someday, but currently it's too ambitious and too messy. I want to recreate a page or two of that app using Vite CSR and Go templates SSR (separately) to see how the alternatives would perform.
Thanks again for the post! We need a healthy dose of scepticism in the programming community.
I think your definition of opinionated differs greatly from the standard. Also Next + Vercel offer way too much benefits that heavily outweigh most of your concerns. On top of this your concerns are rather weak. With all due respect but have you really worked with Next and do you really understand it's purpose and foundations?
Oh boy just wait until I write up why I'm not using react query 🤣🤣
I did try to stress that this is just my subjective opinion. Yes I use next every day at work and honestly it causes more headaches for the team than when we weren't using it.
We're all entitled to our opinions right? But for me, next is just too opinionated. I would probably say the same of most frameworks that hide the build process and routing logic from me. I like to be in control...
Might as well just go full JS vanilla mode.
Yeah or maybe just use punch cards, or we could write everything on paper and serve the internet via post
🙂
If you think the only option besides Next is Vanilla JS or punch cards then you really are narrow minded. There are some people that don't see exclusive value in Next and I am one of them.
Next gives you
These are not exclusive to Next and you can get round those using other tech and using React as a library on top of some other CMS or MVC Framework for the SEO parts of my app.
Actually it's just a React. Getinitialprops is deprecated. Getserver/static. Nothing opinionated here. Try Rails to see what is opinionated ;) . You can change the API route or/and use custom server. The server side things are only for the first request and this is awesome, but what, how, when, why will run depends on you.
In Next13 i was like wtf man? So much good stuff but behind that stuff you will see much of useless stuff... Why to push developer to use specific way of building routes? Why those strange file and dir names, like (YoutDirName) for kipping the code, you don't want to have public but you doing something with it. In documentation you have this "Marketing" example xD. What "Marketing files" do you have in your repository? In professional apps, you can't have something like that in your codebase because it is a trash... For me, It's nice to look at Next13 but it transformed to hyped marketing product.
Pretty weak points.
I'm not trying to convince the world not to use next. I just wanted to cover the factors that mattered to me personally
Yeah, and additionally this comment provides no constructive feedback. What's weak about it?
Yes I have been using vite and I've really enjoyed it!
Have you tried Vite with react-ts and SSR? Is it better than nextjs? And is it safe to start a large project with? Thank you!
Not a UI Framework is telling you where your Api routes should live Nextjs as an Application framework tells you that.
Next is almost entirely concerned with react, there isn't really much in the way of framework stuff for the backend side, besides the routing. Maybe it's described as an application framework but the emphasis is on the ui.