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

Csaba Apagyi
May 3 · 3 min read

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. Defining a catch-all route currently overwrites the /graphql endpoint regardless of the order of imports in your main module. If you’re using that, you’ll need to define pages explicitly. The handler for the pages will be the same.

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

Sign up for Geek Culture Hits

By Geek Culture

Subscribe to receive top 10 most read stories of Geek Culture — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Geek Culture

A new tech publication by Start it up (https://medium.com/swlh).

Csaba Apagyi

Written by

Geek Culture

A new tech publication by Start it up (https://medium.com/swlh).

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store