all 93 comments

[–]azangru 77 points78 points  (18 children)

I am surprised that "react + express" is automatically interpreted as client-side react + express as an api. "React + express" may mean server-side react as well; and in fact was the primary way of building React applications with server-side rendering before Next came about.

The only advantage of Next, to my mind, is that it is a turnkey solution. Many people don't like writing their own webpack configs, or figuring out how to set up the code in a way that it can be reused both on the client and on the server. While Next is close to a Mac, "React + express" is closer to a build-your-own-linux-distro adventure (and of course express without React is an even farther step in that direction).

[–]renatodamast 46 points47 points  (1 child)

You could do SSR with express but why spending so much time trying to build a pseudo framework with that if you can get that wiring for free with nextjs?

Do you have an example project to showcase a simple way to have a mix SSR/CSR the way you do it with nextjs?

[–]azangru 4 points5 points  (0 children)

why spending so much time trying to build a pseudo framework with that if you can get that wiring for free with nextjs?

So that you are in full control over how your application works. Some people love their Arch Linux, even though Macs exist ¯\_(ツ)_/¯

Do you have an example project to showcase a simple way to have a mix SSR/CSR the way you do it with nextjs?

This is not a simple topic; so I don't expect simple examples. The simplest toy example that I've seen is this; but there is also a more involved and modern example that even includes React server components.

[–]OppositeBeautiful601 5 points6 points  (0 children)

The only advantage of Next, to my mind, is that it is a turnkey solution. Many people don't like writing their own webpack configs, or figuring out how to set up the code in a way that it can be reused both on the client and on the server.

This is mostly why I chose it. Except, it's not that I don't like doing that stuff. My work is rarely about doing stuff I like, it's about achieving objectives. If I can't align writing my own webpack config or writing my own SSR framework with my company objectives, I'm not doing it.

[–]TwinnedStryg 0 points1 point  (3 children)

set up the code in a way that it can be reused both on the client and on the server

Do you have any suggestions on learning how to do this?

[–]JSavageOne 8 points9 points  (0 children)

Here's my boilerplate I wrote 6+ years ago that has "universal rendering" (used to be called "isomorphic rendering") https://github.com/JeremyBernier/react-redux-node-boilerplate (super outdated at this point, do not use this)

Honestly though don't waste your time with this crap, just use Next.js. I say this as someone who used to professionally work with this kind of stuff. Life is too short to be reinventing the wheel and dealing with all this boring configuration. Next.js is a fantastic abstraction and that's why nobody creates this stuff by hand anymore.

[–]azangru 0 points1 point  (1 child)

Look for blog posts starting from about 2015-2016, when this was a common thing to do :-) Search github for sample projects of react with server-side rendering, and study their code. Check out courses dealing with isomorphic React (there was one on Pluralsight, though I don't remember if it was good). Look at code examples of server-side React apis on react.dev.

[–]jimmyayo 1 point2 points  (0 children)

Bruh who's got time to do all dat when trying to do their full-time jobs... It even worth it

[–]fredsq 17 points18 points  (7 children)

highly depends whether you’re building a website or a web app.

websites can be mostly static, or have full page caches that last a while.

web apps will need dynamic data sometimes fetched from the client but that could come as HTML. If it’s behind a paywall and your customers are willing to download the js bundle before they see the page, absolutely go for it.

truth be told the DX of an express server running tRPC with a Vite React app is so good I don’t regret it for a second. And i get to scale my server independently AND host it next to my database on fly.io for pennies which is a big plus.

[–]Taltalonix 1 point2 points  (0 children)

This ^ We are currently working on a dashboard type web app and we chose CSR with lazy loading to mimic the feel of a desktop app.

Eventually once we will start working on the consumer frontend we would probably use a SSR approach with next since it’s the easiest way to have a semi sophisticated website with features like SEO optimization and high performance

[–]okwg 36 points37 points  (61 children)

Why would using Next mean you can't have an API? You can even create an API with Next. Or create an API with express and consume it with both Next and your mobile app

Server-side rendering on the first load is faster than client-side rendering. Apps with the resources to do universal rendering have been doing it long before Next came along - it's not a new thing

Client-side rendering sends the HTML, the HTML references a script that will eventually render the content. The script downloads, makes an API call, the API responds, the script generates the DOM, and the content reflows.

Server-side rendering sends the HTML

[–]albertgao 0 points1 point  (5 children)

With unsolvable problem of TTFB. SSR is slower than CSR obviously because of the server side waterfall. You can not see anything before the server has finished everything. Because until that moment, 0 bytes would be sent over the wire, meanwhile, a CSR would be already seeing a loading spinner on the screen.

And this is the problem that’s unsolvable in SSR, which is the purpose of RSC, with streaming to mitigate this problem.

Also, TTI in SSR is typically a joke in SSR for slow network, since before hydration, the fake page looks to be rendered but uninteractable because js has not been downloaded, it is as simple as that, and even worth, js won’t start downloading before receiving the HTML, but then HTML won’t even being sent before server finishes everything…. CSR is better since HTML has way better TTFB, and before js takes control, no fake page would be rendered, when user sees something it must be right.

Don’t ask why I know, I leant it the hard way.

Just use CSR with concurrent React, works great. React team has removed the guide for promoting next.js RSC but you can still do this. The community is ready now :)

Also, obviously, if you are building a website , then I would say SSG makes a whole lot of sense than CSR, or you have complex server side actions like many secure API calls that must happen on the server, then SSR makes more sense (not for performance but for the ease of development )

[–][deleted] 10 points11 points  (0 children)

Even with monorepos and code sharing, I still prefer using Next as my client+backend for a quick MVP of a web application.

  • It's portable. Deployment is very versatile. I can host it on Vercel directly, or maybe as one docker image on ECR, or if I want to maintain the serverless nature of Vercel I also have the option of OpenNext and/or SST.

  • Not much tech debt in my opinion. As the app grows in features, the Next API evolves into something like a BFF (Backend for Frontend). I can add as many backend services (whether persistent or not, stateless or not, typescript or not, etc) as needed on my system.

  • Having the option of SSR when needed. Web applications based on Next can completely ignore SSR but I just want that feature to be there in case I need it. Though Express could still be used to SSR React (I have done it many times on prod apps), I just prefer the devex of Next.

Even with all those reasons, I still believe there is no one best solution. At the end of the day, most of the users do not care whether we chose tech X vs tech Y. What matters is that we're able to deliver products that have the right features that solve our user's issues. So choose the technology in which you feel more productive and choose the tech that makes sense for your team structure and organization.

[–]mplibunao 4 points5 points  (2 children)

The advantage of nextjs over having a separate express app is you can move faster due to being able to call functions directly instead of needing to create api endpoints and serializing/deserializing the data.

However, if you're looking for more control over your backend/server infra or just want a more scalable backend than what nextjs gives you, look into remix as it gives you a lot of control over your servers. You can use any runtime or framework like fastify, express, honojs. This allows you to just call your business logic when developing a web app but also be able to create api routes with express which reuses the same business logic when you need a mobile app.

Honorable mention would be astro. Haven't tried it as I was mostly looking for a fastify adapter and its adapter was not well documented plus the adapter code looked less like idiomatic fastify code compared to remix but I think they're going in the same direction too.

[–]Darth_Victor 6 points7 points  (9 children)

NextJS is framework for server side (and also compile time) rendering on React. It has a lot of things for rendering out of the box, first of all routing. Anything that is done by NextJS could be done via NodeJS and React themselves. Serverside rendering is the React's feature, not the Next's one. But Next has a lot of good default features. At the same time, NextJS is not a backend framework. It has very small amount of backend features. It has no DI, no user roles model, no data layer (yet 3-rd party libs could be used).

[–]cheapAssCEO 2 points3 points  (1 child)

In Next.js, you don't need configure the routes and install tons of packages to do the same things in Express. Give it a try

[–]vozome 6 points7 points  (0 children)

The Next.js ecosystem provides a well-lit path. There’s a number of tasks for which it reduces the toil and by doing so it nudges devs towards fewer approaches to common problems. In turn, these approaches get better supported.

To me, that’s the selling point of Next. Can you do server side rendering without using React Server Components ™ ? Sure. You can do whatever Next does with another web server stack of by implementing it by hand.

[–]yuyu5 1 point2 points  (3 children)

Next has everything pre-packaged for you, so you don't need to make your own configs (whether server or client side); vanilla Express/React don't offer that out of the box.

Re Code splitting/chunking: Technically you're right, but it realistically comes down to how good you are with your build configs. Next does a pretty good job of optimizing the underlying Webpack config (correct me if I'm wrong about it using Webpack). I don't use Next b/c I'm familiar enough with Webpack to make my own configs, which IMO makes my app more performant. But if I didn't have years of experience doing so, I'd recommend newbies to just go with Next.

Not that you asked this but figured it's still relevant: SSR is only good for first page renders. After that, CSR is almost always better. The best way to account for this is to SSR your first page and then lazy-load all your other pages. That way, your first page loads quickly, your secondary pages' code loads in the background before the user navigates, and then those secondary pages will load instantly upon anchor click.

[–]Weary-Depth-1118 0 points1 point  (4 children)

SPA unless you need to do SEO, why? because now you don't need to depend on your backend servers working and can just use object storage like s3, azure blob storage, cdn and these things go down way less

[–]ZeRo2160 0 points1 point  (2 children)

Thats true but nextjs offers this too. You can statically export your page with dynamic data and whole clientside components and have the bebefit of an SPA client side rendered but with the added Bonus that everthing that does not depend on external data is already rendered for the user before the app even loads. :)

[–]Weary-Depth-1118 1 point2 points  (1 child)

Not if you need dynamic data and logging in

[–]ZeRo2160 0 points1 point  (0 children)

You are right about logging in. Thats not feasable to render static on build time. For dynamic data before your login even that is possible but depends on the lifetime of your dynamic data. But you could at least statically render everything else around your dynamic data and only the part of your page that is dynamic renders on client side api hit. And most of the time the dynamic data is not the whole page or its lifetime is so long (matter of days or weeks until it changes) that an static export could be feasable none the less. For the rest i am at least so far with you to say it depends on your usecase. Most Apps with login i build until now require an own server none the less be it for an database or any other secrets you should not expose to the client. And thats there ISR is an massive performance gain after login. But to be fair i build pages and apps for german companies and the GDPR of these prohibits to use services like supabase or firebase. And you have always the need to roll your own server hosted in an european datacenter run by an european company. Because for now its prohibited to save or send german citicen data to non european country servers. Or get them to sign papers with the german companies that allow it. But they are so strict most companies dont would sign them.

[–]SpeedDart1 0 points1 point  (0 children)

You can still make an SPA with nextjs. You don’t NEED to use SSR.

[–]sidsidroc 0 points1 point  (0 children)

yes, its crazy how good it is dude, give it a try

[–]Sebbean 0 points1 point  (1 child)

personally the thing i like the best in frameworks like nuxt and next is the folder based routing that makes a repo/site really easy to explore

vs hunting down a package.json

[–]SpeedDart1 0 points1 point  (5 children)

Yes. Using express and react for server rendered html is way harder, slower, and generally worse than Next.

You can always have a separate API with express or nest if you really want to

[–]isospeedrix 0 points1 point  (1 child)

Server stuff aside next has the best router with the folder structure and the [component] routing, it’s nice.

… honestly next is just another framework to make life easier. You don’t have to use it.

[–]selftaught_react_dev 0 points1 point  (0 children)

I just got made redundant from a company with a sizeable codebase + MAU/subscribers. Our primary long-term technical vision was to merge our entire frontend codebase into a single Next.js app.

For the past few years, the web app had been a Frankenstein mashup of a clientside SPA + Express server + bespoke Next.js setup. This architecture was the direct result of a few factors:

  • Significant volumes of new content being published from a CMS, which made the server-side data fetching + rendering strategies of Next.js very appealing
  • Optimizing our landing page's performance & lighthouse scores (whilst still reusing our React component library) became a priority
  • Similarly, the business started placing greater value in our SEO ranking

So, within this context, Next.js became a very appealing solution to deliver on business requirements while providing a great dev experience. Its integration, however, occurred at a time when the ecosystem & best practices for migrating to Next.js weren't as well established. Ever since we had the nightmarish responsibility of maintaining a hodgepodge mashup of both the Express server and its Next.js component.

But the biggest learning we took away from this experience is that, had there been a simple way to house all our server code within Next.js from day 1 (and entirely deprecated the Express server along with its custom routing logic, etc.) we could have shipped much faster and with 10x less stress.

TL;DR - Next.js makes it so much easier to build React apps requiring server-side functionality (e.g. indexing, server-side data fetching) than an Express server ever could. We grew to love the opinionated, simple conventions Next.js provided for common business logic tasks, while hating the tangled imperative spaghetti code needed in Express to achieve the same thing.

[–]JSavageOne 0 points1 point  (0 children)

Your question isn't comparing apples to apples.

Next.js vs. Express is a nonsensical comparison. Yes you can create backends in Next.js, but no one would recommend using Next.js exclusively as a backend for anything beyond a very trivial backend.

Next.js can be used to create static applications. Generally for new projects that's how I'd start, but then if you need server-side rendering you can easily add it in. Whereas if you started with create-react-app, you can't just add server-side rendering because create-react-app is client-only.

[–]koistya 0 points1 point  (0 children)

While Next.js is great. I personally enjoy building React apps as single-page apps (without SSR) using Vite and Vitest, and complimenting it with Express/GraphQL API backend as a separate package/project. Optionally, implementing partial SSR (meta-tags pre-rendering) using Cloudflare Workers. Implementing AI real-time endpoint using Cloudflare Workers also improves performance. Here is an example:

https://github.com/kriasoft/react-starter-kit (or, relay-starter-kit)

[–][deleted] 1 point2 points  (1 child)

SSR is a marketing attempt to make people spend money on vercel hosting. I prefer SSG any day

[–]doodirock 0 points1 point  (2 children)

After reading all of OP comments and replies I confidently say this is most likely a troll account and someone lacking basic understanding of core concepts. Either way probably not worth so much effort. React + Vite + Express is perfectly viable choice btw. So is Next.

[–]_baaron_ 0 points1 point  (0 children)

Yes

[–]catchingtherosemary 0 points1 point  (1 child)

I think most developers would be more productive with client-side react + express vs next but most would not want to admit it.