Trendy Coder Logo
  • Home
  • About
  • Blog
  • Newsletter

How to debug Next.js in NPM Workspaces

Posted on: May 20 2024
By Dave Becker
Hero image for How to debug Next.js in NPM Workspaces

After recently moving a Next.js app to a monorepo setup using NPM workspaces, I noticed the debugger wasn't working as expected. I was no longer able to put breakpoints on server side components or API endpoints. I eventually discovered that debugging Next.js in NPM workspaces requires some additional configuration.

In this article I'll cover the needed changes to configure and resolve the debugger issue, including:

  • Debugging Next.js in NPM workspaces
  • Key benefits of using Next.js in workspaces
  • Configuring Visual Studio Code for NPM workspaces
  • Different debug configurations

Read on if you've been experiencing this issue so you can get back to successfully debugging Next.js in workspaces.

What is debugging Next.js in workspaces?

NPM and Yarn have supported workspaces for some time now and offer a great way to break large projects into separate workspaces or modules.

Workspaces typically have a different repo directory structures which can make debugging a specific workspace different than a standalone Next.js project.

Why is debugging Next.js in workspaces important?

As development strategies continue to evolve, a good portion of projects and teams are moving to a monorepo approach, for the following reasons:

  • All of the code is in one repo location.
  • Projects can be broken down into separate workspaces allowing different teams to work in different spaces and still maintain autonomy.
  • Eliminates the need to publish internal dependency packages since they coexist in the same repo.
  • No need for versioning packages since code is always at latest.
  • Multiple Next.js and other UI frameworks can be managed using workspaces.
  • Common code can be shared and is always current without version drift.

Even though there are many benefits to gain with NPM workspaces, there will still be some learning curves. I felt an article on this topic would help understand how to debug Next.js apps in NPM workspaces.

Types of ways to debug Next.js

Next.js Standalone

Standard Next.js project setup without workspaces. This is your basic setup and usage.

Next.js in NPM Workspaces

Next.js UI apps are nested within subdirectories managed by NPM workspaces.

Tips for debugging Next.js

If your new to Next.js, it helps to have a general idea of the different component module types and how they need to be debugged.

  • client side - Any React component in Next.js that uses React hooks or providers needs to place use client at the top of the module and is considered to be a Client Component. These types of components require the Chrome debugger to set breakpoints.
  • server side - All other components are React Server Component (RSC) by default. These types of components will need to be debugged using an IDE like Visual Studio Code to add breakpoints since these components only render on the server. These are components such as:
    • layout.tsx
    • page.tsx (without use client)
    • route.ts
    • middleware.ts
    • Any exported function, object or variables that does not use React hooks or providers generally.

Next.js debug setup in Standalone project

Let's first take a look at a standalone Next.js application project structure and debug configuration. This is the project structure you'll get out of the box when using the generator.

npx create-next-app@latest

In Visual Studio Code, a typical standalone application like Next.js will generally have all the code in the root of the project.

  • project-root: representing the root of a single project that was opened in Visual Studio Code.
└── project-root
    ├── .vscode
    ├── .next
    ├── app
    ├── next.config.mjs
    ├── node_modules  
    ├── public
    ├── package.json
    └── package-lock.json

Starting a debug session

There's basically two ways to start a debug session, which include:

  • Launch: Starts a Next.js application and attaches the VS Code debugger to the running process.
  • Attach: Attaches the debugger to an already running Next.js process.

These options apply for any Node.js debug session with or without using workspaces.


Attaching a debug session in Next.js Standalone

The package.json has the following dev script, which just launches the Next.js in development mode.

Using Attach mode type, the NODE_OPTIONS env variable needs to be added with the --inspect flag as follows.


/package.json
{
 "name": "nextapp",
 "scripts": {
    "dev": "NODE_OPTIONS='--inspect' next dev"
 }
 ...
}

The VS Code debug configuration will be as follows.

/.vscode/launch.json
{
  "configurations": [
  {
      "name": "Attach debug server-side (Standalone)",
      "port": 9230,
      "request": "attach",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "type": "node"
  }
 ]
}

The default port is 9229 but adding NODE_OPTIONS='--inspect' will use the next adjacent port 9230 to avoid port conflict.


To start the debug session, start the Next.js application manually.

npm run dev

Then attach the debugger with the Attach debug server-side (Standalone) configuration.

The debugger will now be connected and ready for any breakpoints on server side code.


Launching debug session in Next.js Standalone

For Launch mode type, you don't need to specify any NODE_OPTIONS on the dev script command and can just include it in the Launch configuration as follows with runtimeArgs.

/.vscode/launch.json
{
  "configurations": [
  {
      "name": "Launch debug server-side (Standalone)",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/node_modules/.bin/next",
      "runtimeArgs": [
        "--inspect"
      ],
      "skipFiles": [
        "<node_internals>/**"
      ]
    },
 ]
}

Simply start the debugger with the Launch debug server-side (Standalone) configuration to start the Next.js application process.

The debugger will now be connected and ready for any breakpoints on server side code.


Next.js debug setup in NPM workspaces

Now let's take a look at how NPM workspaces differ and the changes we'll need to make.

So if you're not familiar with using NPM workspaces or the monorepo approach, here's a high level overview.

Workspaces allow for multiple project modules to exist under one project root.

Configuring NPM workspaces

In the root package.json you can define workspaces as follows.

For example, consider the following:

  • apps: Any UI apps can be located here.
  • packages: Any shareable or internal dependency packages may be located here.

/package.json
{
 "workspaces": [
    "apps/*",
    "packages/*"
  ],
}


The NPM package manager will automatically scan these locations and find all of the directories that have a package.json defined and treat it as a separate workspace module.


A sample Next.js NPM workspaces project

So in the directory diagram below, NPM will manage all of the following workspaces we defined in the root package.json.

└── project-root
    ├── apps
    │   ├── nextapp1
    │   │   ├── node_modules  
    │   │   ├── .next
    │   │   ├── next.config.mjs
    │   │   ├── app
    │   │   └── package.json
    │   └── nextapp2  
    │   │   ├── node_modules  
    │   │   ├── .next
    │   │   ├── next.config.mjs
    │   │   ├── app
    │   │   └── package.json
    ├── packages
    │   ├── shared
    │   │   ├── package.json
    │   │   └── src
    │   └── services
    │       ├── package.json
    │       └── src  
    ├── package.json
    └── package-lock.json

In NPM workspaces, all package.json files should have a unique package name. We'll assume in this tutorial that all the workspaces have the name of their respective directory.


Attach debug session in workspaces

Similar to standalone , each Next.js workspace application will need to have the --inspect flag added to the dev start script or the launch configuration.

/apps/nextapp1/package.json
{
 "name": "nextapp1",
 "scripts": {
    "dev": "NODE_OPTIONS='--inspect' next dev"
 }
}

Since workspaces are nested in subdirectories, we'll need to add some additional settings to the launch.json configuration.

Here's the Attach configuration with the addition of the cwd field to specify the current working directory path to the target workspace.

Including cwd is an essential step because wihout it, the debugger won't be able to reference the source maps and breakpoints won't attach properly.

/.vscode/launch.json
{"configurations": [
  {
    "name": "Attach debug server-side (Workspaces)",
    "port": 9230,
    "request": "attach",
    "skipFiles": [
      "<node_internals>/**"
    ],
    "type": "node",
    "cwd": "${workspaceFolder}/apps/nextapp1"
  },
]}

To start and attach a debug session for nextapp1, we'll need to use NPM workspace notation to target the Next.js workspace.

npm run dev -w nextapp1

Once the Next.js app is started, start the debugger with the Attach debug server-side (Workspace) configuration.

The debugger is now ready for server-side breakpoints to be added.

Launch debug session in workspaces

Similar to the standalone Launch type, we don't need to start the app manually, since it will lauch a Next.js process once we start the debugger.

Here's the debugger configuration settings to launch.

/.vscode/launch.json
{ 
  "configurations": [
    {
      "name": "Launch debug server-side (Workspaces)",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/node_modules/.bin/next",
      "runtimeArgs": [
        "--inspect"
      ],
      "skipFiles": [
        "<node_internals>/**"
      ],
      "cwd": "${workspaceFolder}/apps/nextapp1"
    },
  ]
}

Once the server starts, you can start adding server-side breakpoints.

Next.js client debug session

The one point we haven't mentioned is the client side debugging in workspaces.

Since all of these debugging steps have been started in dev mode, all of the client source maps are already available for debugging in Chrome by default.

However, to add a configuration for client side, we could add the following to launch a new Chrome browser for debugging.

Example client configuration:

/.vscode/launch.json
{ 
  "configurations": [
  {
    "name": "Next.js: debug client-side",
    "type": "chrome",
    "request": "launch",
    "url": "http://localhost:3000"
  }
]}


Example full-stack configuration:

/.vscode/launch.json
{ 
  "configurations": [
    {
      "name": "Next.js: debug full stack",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/node_modules/.bin/next",
      "runtimeArgs": [
        "--inspect"
      ],
      "skipFiles": [
        "<node_internals>/**"
      ],
      "serverReadyAction": {
        "killOnServerStop": true,
        "pattern": "listening on port ([0-9]+)",
        "uriFormat": "http://localhost:%s",
        "action": "openExternally"
      },
      "cwd": "${workspaceFolder}/apps/nextapp1"
    }
  ]
}


Conclusion

Since React based frameworks like Next.js are moving towards (RSC) components, it's good to know how to put a debugger on your server-side code rather than just using console.log output statements.

Whether you choose to use the Attach or Launch is up to you. My preference is always to attach so I can always start a debug session at any time.

Visual Studio Code has great support for debugging. There's a few extra steps to set up debugging in workspaces but well worth it.

Topics

SEOLinuxSecuritySSHEmail MarketingMore posts...

Related Posts

Hero image for Boost Payload CMS with Search: Step-by-Step Tutorial
Posted on: August 11 2025
By Dave Becker
Boost Payload CMS with Search: Step-by-Step Tutorial
Hero image for Server-Side Pagination Made Easy in Payload CMS
Posted on: August 11 2025
By Dave Becker
Server-Side Pagination Made Easy in Payload CMS
Hero image for Payload CMS: Getting Started Using the New Join Field
Posted on: August 11 2025
By Dave Becker
Payload CMS: Getting Started Using the New Join Field
Hero image for Maximizing Efficiency: The Power of Payload CMS Blocks
Posted on: August 11 2025
By Dave Becker
Maximizing Efficiency: The Power of Payload CMS Blocks
Hero image for Create Custom Forms Using Payload CMS Form Builder Plugin
Posted on: August 11 2025
By Dave Becker
Create Custom Forms Using Payload CMS Form Builder Plugin
Hero image for Payload CMS SEO Plugin: Boosting Your Site's Search Ranking
Posted on: April 04 2025
By Dave Becker
Payload CMS SEO Plugin: Boosting Your Site's Search Ranking
Hero image for GraphQL Optimization in Payload CMS
Posted on: April 04 2025
By Dave Becker
GraphQL Optimization in Payload CMS
Hero image for Exploring the Game-Changing Features of Payload CMS 3.0
Posted on: April 04 2025
By Dave Becker
Exploring the Game-Changing Features of Payload CMS 3.0
Hero image for Document Nesting With Payload's Nested Docs Plugin
Posted on: April 04 2025
By Dave Becker
Document Nesting With Payload's Nested Docs Plugin
Hero image for Payload CMS Collections: How They Streamline Content Management
Posted on: April 04 2025
By Dave Becker
Payload CMS Collections: How They Streamline Content Management
Trendy Coder Logo
Resources
  • Blog
Website
  • Home
  • About us
Subscribe

Get the latest news and articles to your inbox periodically.

We respect your email privacy

© TrendyCoder.com. All rights reserved.