Blog
Philip Fulcher
May 5, 2025

Nx 21 Release: Continuous tasks and Terminal UI lead the way

Nx 21 Launch Week

This article is part of the Nx 21 Launch Week series:

  • Nx 21 Release: Continuous tasks and Terminal UI lead the way
  • Continuous tasks
  • Terminal UI
  • Migrate UI

Welcome to Nx 21 Launch Week! Nx 21 is here with some of the highest-impact changes we've ever built. We're really excited to share what we've been cooking up, so we'll be following up with more details throughout the week.

ICYMI: Updates from Nx 20

Before we dive into the newest features of Nx 21, make sure you catch these updates that happened during Nx 20:

Continuous tasks

During the development of Nx 20, we started an RFC for continuous tasks. After gathering feedback from the community, continuous tasks are here to make many workflows in your workspace much easier to implement.

Many of the tasks in your workspace are finite: they run, produce an output, and shut down on their own. Continuous tasks are long-lived tasks: they run until interrupted by an outside input. These are tasks like serving your application or running tests in watch mode. While Nx has always supported running these tasks, you couldn't configure a task pipeline. For example, you could serve your backend and frontend separately, but you couldn't easily configure your backend to be served whenever your frontend is served. There are always options like opening two separate terminals to run the tasks or setting up a specific script or task for running these in parallel. But the DX has always been lacking.

Now, tasks can be marked as continuous, and other tasks can depend on them. Nx will no longer wait for these tasks to shut down before invoking the tasks that depend on them. Let's wire one up as an example: a frontend that depends on a backend running to function. Assuming we run a dev target from our frontend project, and a serve target from our api project, we configure this on the frontend project like this:

apps/myfrontendapp/package.json
1{ 2 "nx": { 3 "name": "frontend", 4 "targets": { 5 "dev": { 6 "dependsOn": [{ "projects": ["api"], "target": "serve" }] 7 } 8 } 9 } 10} 11

The frontend:dev task now depends on api:serve. We must also ensure the api:serve target is flagged as continuous. We've already flagged tasks as continuous if you're using inferred tasks.

If your target uses an executor, you need to flag those targets as continuous yourself. This is as easy as adding continuous: true to the target configuration like so:

apps/myfrontendapp/package.json
1{ 2 "nx": { 3 "targets": { 4 "serve": { 5 "executor": "@nx/esbuild:esbuild", 6 "continuous": true, 7 ... 8 } 9 } 10 } 11} 12

Or if your target uses a custom command:

apps/myfrontendapp/package.json
1{ 2 "nx": { 3 "targets": { 4 "serve": { 5 "command": "astro dev", 6 "continuous": true 7 } 8 } 9 } 10} 11

Now serve the frontend with nx serve frontend. You'll see the backend project spin-up in parallel with the frontend.

This opens up tons of opportunities to better configure your task pipelines, such as:

  • Start servers required for an e2e test suite to run (both frontend and backend)
  • For any application, serve can depend on code generator tasks in watch mode
  • serve can also depend on watch-deps in order to watch buildable libraries for changes

We'll have more details on this as part of our Nx 21 Launch Week, so keep your eyes open for more.

Terminal UI

Screenshot of Nx Terminal UI showing a task list on the left and log output on the right.

Continuous tasks are a massive improvement to your DX in a monorepo. Still, they also bring a challenge: now that we're running multiple tasks in parallel, how do we handle the logs from those continuous tasks?

You've encountered a similar problem using affected or run-many. When you run multiple tasks simultaneously, finding the logs for one particular task can be tricky. Nx Cloud has previously solved this problem with its structured logs, but continuous tasks demanded a new solution that lives in your terminal. Enter the Terminal UI.

Our new Terminal UI (TUI) takes over whenever you run a task in Nx. Rather than just seeing an output of logs, you'll see the currently running tasks in one panel with log outputs for the selected task appearing in a separate panel. You can navigate the TUI with the arrow keys or h/j/k/l Vim-style navigation. Pressing the ? will bring up the keyboard shortcut list, and pressing q will exit the TUI.

This is one of the most significant changes to how users interact with Nx daily, and we're excited to share more about it later this week.

Windows Compatibility

The initial Nx 21 release disables the Terminal UI on Windows. We are currently working on Windows support, so stay tuned.

@nx/gradle is blazingly fast

We've been iterating on our @nx/gradle plugin for a while now. We're bringing two considerable enhancements to this plugin that make it perform better than ever before.

First, we've introduced a Gradle plugin that provides Nx with project graph information. Previously, we relied on the Project Report plugin for Gradle to provide this information. However, this tool didn't provide enough information for Nx, and it also had a static output. Our new project graph plugin is built from the ground up to support what Nx needs faster than before.

Secondly, Nx now sends tasks to Gradle in batches rather than one by one. This speeds up task execution and better aligns with how Gradle expects to run things.

To test how performance improved, we forked the Spring Boot repo and converted it to use Nx. With the latest version of our plugin, we were able to reduce CI times from 1 hour 44 minutes to 42 minutes, a 59.6% reduction in time.

These two changes make the @nx/gradle plugin better than ever for managing your Gradle plugins. Be sure to explore this new plugin if you're using Gradle, and watch out for what else we're bringing to the Java ecosystem, later this year.

Check out the docs for more details.

Migrate UI in Nx Console makes migrations easier than ever

Screenshot of Nx Console's Migrate UI showing a list of migrations to approve.

Automated migrations have always been a massively valuable part of Nx. Previously, we added migration docs to better inform you of what's happening during these migrations. Now, we're bringing the migration process to the Nx Console so that you can step through migrations even easier than before.

After updating to the latest version of Nx Console, you'll see a new Migrate UI panel. Through this, you'll be able to start a migration, install packages, and then individually approve different migrations. You'll be able to see the change before approving and moving on to the next one. This allows for better visibility into each change and helps you stay informed. As always, you'll have an option to commit after each change or squash them together into a single commit.

This is another item we're excited to talk about more later this week.

React Router plugin

React Router 7 is a big step for the library, bringing in some of the best ideas from Remix. Version 7 introduces "modes,” which allow users to use increasingly rich feature sets. The declarative and data modes can be used as a library and built using any existing React build pipeline you have. The new framework mode is closer to Remix and needs a specific build tool.

If you're using React Router in declarative or data mode, you can continue using the existing workflows that build your React app.

However, if you're ready to start a new app using the framework mode in React Router or need to migrate a Remix app to React Router, we've got you covered. Our new inferred task plugin will handle running the React Router CLI based on projects with a React Router config file. If you're migrating from Remix, follow the React Router team's migration guidance. Once migrated, you can remove the Remix plugin and use the React Router plugin.

Updated release versioning

In Nx 21, the implementation details of versioning were rewritten to enhance flexibility and allow for better cross-ecosystem support. This rewrite has been primarily made to make the implementation more flexible and more extensible. Now you can define custom version actions to provide Nx release versioning support for non-JavaScript packages, whether that's Java, Go, Rust, or other languages. The new APIs are flexible enough that you can even run versioning across different packages written in different technologies in the monorepo. So this new update is really a door-opener for polyglot workspaces.

An automated migration will update your configuration to the new format. You can still opt into the old versioning by setting release.version.useLegacyVersioning to true, which will keep the original configuration structure and behavior. In Nx 22, the legacy versioning implementation will be removed entirely, so this should only be done temporarily to ease the transition.

This is just the first release with these new APIs, and we're going to talk more about it and provide more examples in the coming months. Check out the docs for more details.

Breaking Changes

Minimum version of Node is now 20.19

With Node 18 entering end-of-life, we have increased the minimum version of Node to 20.19.

Older task runners API removed

Nx 21 removes the deprecated custom task runners API, replacing it with the preTasksExecution and postTaskExecution hooks.

This allows you to still hook into the task running pipeline, but in a well-defined way that provides enough flexibility to the Nx core to rewrite internal implementations and apply performance optimizations to the task running pipeline.

We're aware that some organizations leveraged custom task runners for implementing self-hosted distributed caches. For these cases, we have provided a free alternative. Visit our remote caching page for more details.

Read more about the deprecated custom task runners API and the self-hosted caching options in our docs.

useLegacyCache removed

As announced previously, the useLegacyCache option has been removed. All workspaces will be migrated to remove this option and use the new database-powered local cache.

createNodesV1 removed

If you're creating Nx plugins that infer tasks, be sure they're migrated to createNodesV2 to support newer versions of Nx.

What comes next

As always, there are far too many updates to talk about every single one. Check our full release notes on GitHub for all the nitty gritty details.

For the rest of Launch Week, we'll be doing deep dives on some of our biggest features. You won't want to miss it, so keep an eye on our socials and YouTube channel.

Learn more: