NestJS + React (Next.js) in One MVC Repo for Rapid Prototyping

Csaba Apagyi
Geek Culture
Published in
3 min readMay 3, 2021

NestJS is solving the issue of backend architecture. Add to that the popular choice of React on the frontend and you’ll find that full-stack JS is in a really good place right now. Can we combine these into an easy-to-use MVC architecture to enable quick prototyping?

TLDR; Yes! In the nestjs-starter repo, I’m combining NestJS and Next.js, connected with GraphQL, in Typescript (end-to-end typing, of course!), in a single MVC repo (not a monorepo of multiple projects), with some added functionality such as authentication via Passport and Cognito.

This article covers NestJS + Next.js integration.

Why a single MVC repo? Lightweight infrastructure! 1 repo, 1 deployment, no synchronization needed. The same backend that serves the API can serve the frontend too. Of course, backend and frontend code and config need to be well-separated within the repo, and separable into their own repos in the future when needed. Typescript and ESLint provide great support for this.

Why Next.js? It’s the leading React framework. Much easier configuration than with create-react-app. Options for CSR, SSR, and static pages. SSR in particular is great with a Nest API on the same host. (There are resources out there for integrating Nest with CRA and plain React too.)

Frontend-first or backend-first? You can choose to host Nest via Next or Next via Nest (I know, these names...). If you have a Nest deployment you can use it as a custom server for Next. Note although that “A custom server will remove important performance optimizations, like serverless functions and Automatic Static Optimization.” On the other hand, if you have a Next deployment you can use serverless functions and dynamic API routes to run Nest. This might restrict scalability, hosting options, and the overall structure of a Nest app. So in this example, I decided to host a Nest app and serve Next through that. (Here’s an attempt the other way around.)

With all that said, only the implementation is left.

A quick search gets us nest-next, but if you ended up here you might’ve had issues like me (1, 2) or found that it doesn’t solve well the separation of backend and frontend: forcedpages folder location on the top of the structure, or their custom tsconfigsetup. You’ll find that you can solve separation by specifying any folder you prefer, and the code to serve the Next app is simple enough that you don’t have to hide it in a complex and opinionated library.

Other attempts include:

My solution below combines 2 and 4. Instead of a library, I use an explicit 15-line service fully under my control.

The repo: https://github.com/thisismydesign/nestjs-starter

Related PR: https://github.com/thisismydesign/nestjs-starter/pull/2/files

Step 1, Install

Step 2, View module

As you see in the view service we explicitly create a Next.js server. You can supply your custom config and directory. I chose to have src/client and src/server folders. Your Next pages will then be in src/client/pages.

You’ll also notice the 2 specific routes in the controller, @Get('home')for a single page and @Get('_next*')for assets. You can also use the catch-all pattern @Get("/:path((?!graphql$))*") to send every request to Next by default (except for /graphql which needs to hit the backend).

You can use Guards as well, e.g. to manage authentication from Nest.

Step 3, Next page 🎉

In src/client/pages/home.tsx

You can also make use of SSR with Next’s getServerSidePropsto query your API.

Step 4, Folder structure

Move server code to src/serverand add further config to make the folder structure work:

Step 5, Integration tests (optional)

If you’re running integration tests on your app module, importing ViewModule there will make the tests fail. I created a top-level ServerModule to combine AppModule view ViewModule as the entry module: https://github.com/thisismydesign/nestjs-starter/pull/2/commits/aff04b4a537afb6d3bb4f3a4d6af6e7d867e8a84

Finally, you have a deployment-ready app to quickly build backend and frontend together. You’ll find more examples for pages, querying data from the backend, and other features in the repo: https://github.com/thisismydesign/nestjs-starter

--

--