Skip to content

Commit aef67bd

Browse files
docs(nx-dev): add continuous tasks and terminal ui articles (#31092)
Co-authored-by: Juri <juri.strumpflohner@gmail.com>
1 parent 124eba7 commit aef67bd

20 files changed

+330
-2
lines changed

docs/blog/2025-02-06-hetzner-cloud-success-story.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ tags: ['customer story']
66
description: Discover how Hetzner Cloud uses Nx Enterprise to ship new features to market faster and with more reliability.
77
youtubeUrl: https://www.youtube.com/watch?v=2BLqiNnBPuU
88
cover_image: /blog/images/articles/hetzner-cloud-story-bg.jpg
9-
pinned: true
109
metrics:
1110
- value: '116+'
1211
label: 'projects in modular architecture'

docs/blog/2025-05-01-nx-mcp-ci-fixes.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ tags: ['nx', 'nx-console', 'ai', 'ci']
66
cover_image: /blog/images/articles/bg-nx-mcp-cloud-integration.jpg
77
description: 'Learn how Nx Console integrates with CI to alert you of failing builds and uses the Nx MCP to automatically fix errors right from your editor.'
88
youtubeUrl: https://youtu.be/fPqPh4h8RJg
9-
pinned: true
109
---
1110

1211
{% callout type="deepdive" title="Series: Making your LLM smarter" expanded=true %}

docs/blog/2025-05-05-nx-21-release.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ tags: ['nx', 'release']
66
cover_image: /blog/images/2025-05-05/header.avif
77
description: 'Discover the latest in Nx 21, featuring continuous tasks and the new Terminal UI'
88
youtubeUrl: https://youtu.be/9zsncTxfcl4
9+
pinned: true
910
---
1011

1112
{% callout type="deepdive" title="Nx 21 Launch Week" expanded=true %}

docs/blog/2025-05-07-migrate-ui.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ tags: ['nx', 'nx-console']
66
cover_image: /blog/images/2025-05-07/migrate-ui-header.avif
77
description: 'Introducing the new Migrate UI in Nx Console, a visual interface that simplifies the migration process.'
88
youtubeUrl: 'https://youtu.be/5xe9ziAV3zg'
9+
pinned: true
910
---
1011

1112
{% callout type="deepdive" title="Nx 21 Launch Week" expanded=true %}

docs/blog/2025-05-08-improved-module-federation.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ authors: ['Colum Ferry']
55
tags: ['nx', 'module-federation']
66
cover_image: /blog/images/2025-05-08/module-federation.avif
77
description: 'Nx 21 introduces native support for Module Federation with Inferred Tasks and Continuous Tasks, enabling streamlined Rspack configs and seamless multi-app serving for improved developer experience.'
8+
pinned: true
89
---
910

1011
{% callout type="deepdive" title="Nx 21 Launch Week" expanded=true %}
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
---
2+
title: 'Continuous tasks are a huge DX improvement'
3+
slug: nx-21-continuous-tasks
4+
authors: ['Philip Fulcher']
5+
tags: ['nx']
6+
cover_image: /blog/images/2025-05-09/continuous-tasks.avif
7+
description: 'Learn how to use continuous tasks in Nx 21 to improve your developer experience.'
8+
youtubeUrl: https://youtu.be/AD51BKJtDBk
9+
pinned: true
10+
---
11+
12+
{% callout type="deepdive" title="Nx 21 Launch Week" expanded=true %}
13+
14+
This article is part of the Nx 21 Launch Week series:
15+
16+
- [Nx 21 Release: Continuous tasks and Terminal UI lead the way](/blog/nx-21-release)
17+
- [Introducing Migrate UI in Nx Console](/blog/migrate-ui)
18+
- [New and Improved Module Federation Experience](/blog/improved-module-federation)
19+
- **Continuous tasks are a huge DX improvement**
20+
- [A New UI For The Humble Terminal](/blog/nx-21-terminal-ui)
21+
22+
{% /callout %}
23+
24+
Continuous tasks are one of the most exciting features we've launched that radically improve the developer experience (DX) of your monorepo.
25+
26+
{% toc /%}
27+
28+
## What are continuous tasks?
29+
30+
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 other tasks to depend on them.
31+
32+
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.
33+
34+
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. These continuous tasks can be configured as part of a task pipeline like any other task. Let's walk through some examples of how to use these in your task pipelines.
35+
36+
## What is a task pipeline?
37+
38+
A [task pipeline](/concepts/task-pipeline-configuration) is a series of definitions determining how tasks depend on one another. In a monorepo, you're rarely running a single task. That task may rely on the output of another task. For example, if your application depends on a buildable design system library, the design system must be built before the application. The application's `build` task depends on the design system's `build` task.
39+
40+
This is such a common pipeline that we include it by default when Nx workspaces are created. It's defined in your `nx.json` in `targetDefaults`:
41+
42+
```json {% fileName="nx.json" %}
43+
{
44+
"targetDefaults": {
45+
"build": {
46+
"dependsOn": ["^build"]
47+
}
48+
}
49+
}
50+
```
51+
52+
This task pipeline says that all `build` tasks depend on the `build` task of any project it depends on, also known as "descendants." The `^` indicates descendants.
53+
54+
`targetDefaults` is where you can define task pipelines for all tasks with that name, but you can also define them at the task level. This same task pipeline could be defined on an individual project:
55+
56+
```json {% fileName="apps/frontend/package.json" %}
57+
{
58+
"nx": {
59+
"targets": {
60+
"build": {
61+
"dependsOn": ["^build"]
62+
}
63+
}
64+
}
65+
}
66+
```
67+
68+
This is a brief overview of task pipelines. Be sure to [check the docs](/recipes/running-tasks/defining-task-pipeline) for more details.
69+
70+
But these examples configure finite tasks: tasks that start up, produce an artifact, and then shut down. How do things change when we configure continuous tasks?
71+
72+
{% callout type="note" title="See these examples in action" %}
73+
To see these examples working in an actual workspace, be sure to [checkout the video](https://youtu.be/y1Q1QSBEsuA).
74+
{% /callout %}
75+
76+
## Frontend serve depends on backend serve
77+
78+
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:
79+
80+
```json {% fileName="apps/frontend/package.json" %}
81+
{
82+
"nx": {
83+
"name": "frontend",
84+
"targets": {
85+
"dev": {
86+
"dependsOn": [{ "projects": ["api"], "target": "serve" }]
87+
}
88+
}
89+
}
90+
}
91+
```
92+
93+
The `frontend:dev` task now depends on `api:serve`. We must also ensure the `api:serve` target is flagged as continuous. Tasks are already flagged as continuous if you're using [inferred tasks](/concepts/inferred-tasks). If your target uses an executor, you must flag those targets as continuous yourself. This is as easy as adding `continuous: true` to the target configuration like so:
94+
95+
```json {% fileName="apps/api/package.json" %}
96+
{
97+
"name": "api",
98+
...
99+
"nx": {
100+
"targets": {
101+
"serve": {
102+
"continuous": true
103+
}
104+
}
105+
}
106+
}
107+
```
108+
109+
Now running `frontend:dev` will also result in the `api:serve` starting in parallel. If we look at the task graph using Nx Console or `nx graph`, we'll see the new task pipeline:
110+
111+
![Graph showing connections between frontend and backend serve tasks](/blog/images/2025-05-09/frontend-to-backend.avif)
112+
113+
In addition to making for a great local development experience, e2e test suites that also run `frontend:dev` will have the same experience. The frontend and backend will be served at the same time, making e2e tests easier to run locally.
114+
115+
## Configuring custom commands as continuous
116+
117+
So far, we've talked about tasks from Nx plugins, but what about the custom targets you've added to your project? Continuous tasks work the same way. Let's say our project has a `codegen` target that uses graphql-codegen. The configuration for this target looks like this:
118+
119+
```json {% fileName="packages/models-graphql/package.json" %}
120+
{
121+
"nx": {
122+
"targets": {
123+
"codegen": {
124+
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
125+
}
126+
}
127+
}
128+
}
129+
```
130+
131+
This only allows for a static output, though: it runs once, produces the artifact, and shuts down. That works well for our `build` task pipeline, where we would define a task pipeline like this:
132+
133+
```json {% fileName="apps/frontend/package.json" %}
134+
{
135+
"nx": {
136+
"targets": {
137+
"build": {
138+
"dependsOn": ["^build", "codegen", "^codegen"]
139+
}
140+
}
141+
}
142+
}
143+
```
144+
145+
Any time `build` is run on a project, it also runs the `build` task for any descendants, the `codegen` task on the project itself, and `codegen` on any descendants. This ensures we have the latest version of our generated models whenever we run `build` on an application. We want that same experience for our local dev experience when serving the frontend application.
146+
147+
First, we create a continuous version of our `codegen` target so that now our configuration looks like this:
148+
149+
```json {% fileName="packages/models-graphql/package.json" %}
150+
{
151+
"nx": {
152+
"name": "models-graphql",
153+
"targets": {
154+
"codegen": {
155+
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
156+
},
157+
"watch-codegen": {
158+
"continuous": true,
159+
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts --watch"
160+
}
161+
}
162+
}
163+
}
164+
```
165+
166+
We have a new target called `watch-codegen` that is marked as continuous. We added the `--watch` flag to the command. Now, when we run `watch-codegen` on a project, it will watch for changes to the GraphQL schema and re-generate models. We can apply this to any project that needs it.
167+
168+
Now we can add dependencies from our `serve` targets to depend on `watch-codegen`:
169+
170+
```json {% fileName="apps/frontend/package.json" %}
171+
{
172+
"nx": {
173+
"name": "frontend",
174+
"targets": {
175+
"dev": {
176+
"dependsOn": [
177+
{ "projects": ["api"], "target": "serve" },
178+
"^watch-codegen"
179+
]
180+
},
181+
"serve": {
182+
"dependsOn": [{ "projects": ["api"], "target": "serve" }]
183+
}
184+
}
185+
}
186+
}
187+
```
188+
189+
Our frontend app may not have its own `codegen` target, so the `serve` can depend on the `^watch-codegen` descendants.
190+
191+
And for the backend:
192+
193+
```json {% fileName="apps/api/package.json" %}
194+
{
195+
"nx": {
196+
"name": "api",
197+
"targets": {
198+
"serve": {
199+
"continuous": true,
200+
"dependsOn": ["watch-codegen", "^watch-codegen"]
201+
},
202+
"codegen": {
203+
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
204+
},
205+
"watch-codegen": {
206+
"continuous": true,
207+
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts --watch"
208+
}
209+
}
210+
}
211+
}
212+
```
213+
214+
Since our backend project has its own codegen target, it needs to depend on both its own `watch-codegen` and `^watch-codegen` for its descendants.
215+
216+
## What can continuous tasks do for you?
217+
218+
We've covered a few different scenarios here, and the [video shows them all working inside an actual workspace](https://youtu.be/y1Q1QSBEsuA). We can visualize the task graph that we've just created to see how much we've accomplished:
219+
220+
![Graph showing connections between frontend and backend serve tasks as well as watch-codegen tasks](/blog/images/2025-05-09/watch-codegen.avif)
221+
222+
Now, developers can run `npx nx dev frontend` and have the `api:serve` and `watch-codegen` tasks run. One command, one terminal, and they are ready to work immediately. No more fumbling through multiple terminals or creating your own solution to the problem. Nx provides the tools to improve your developer experience.
223+
224+
What processes could you improve using continuous tasks?
225+
226+
Learn more:
227+
228+
- 🧠 [Nx AI Docs](/features/enhance-AI)
229+
- 🌩️ [Nx Cloud](/nx-cloud)
230+
- 👩‍💻 [Nx GitHub](https://github.com/nrwl/nx)
231+
- 👩‍💻 [Nx Console GitHub](https://github.com/nrwl/nx-console)
232+
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
233+
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)

docs/blog/2025-05-09-terminal-ui.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
---
2+
title: 'A New UI For The Humble Terminal'
3+
slug: nx-21-terminal-ui
4+
authors: ['Mike Hartington']
5+
tags: ['nx']
6+
cover_image: /blog/images/2025-05-09/terminal-ui.avif
7+
description: 'Nx 21 introduces the new Terminal UI, an elegant way of viewing log output from multiple running tasks.'
8+
youtubeUrl: https://youtu.be/ykaMAh83fPM
9+
pinned: true
10+
---
11+
12+
{% callout type="deepdive" title="Nx 21 Launch Week" expanded=true %}
13+
14+
This article is part of the Nx 21 Launch Week series:
15+
16+
- [Nx 21 Release: Continuous tasks and Terminal UI lead the way](/blog/nx-21-release)
17+
- [Introducing Migrate UI in Nx Console](/blog/migrate-ui)
18+
- [New and Improved Module Federation Experience](/blog/improved-module-federation)
19+
- [Continuous tasks are a huge DX improvement](/blog/nx-21-continuous-tasks)
20+
- **A New UI For The Humble Terminal**
21+
22+
{% /callout %}
23+
24+
At Nx, we're all about providing great experiences. From project inference, to our MCP server, to the great Nx Console extension for VS Code and IntelliJ, we work hard to make sure that developers have a smooth experience when working on their projects. However, there has been one place where you probably got the least great experience compared to the rest: the terminal.
25+
26+
"Um, it's a terminal, it doesn't need much. Why spend time trying to improve it?"
27+
28+
Great question! Why spend time on a terminal? Well, the terminal is the starting point that every developer begins with, and it's ripe for improvements. Plus, with the migration to Rust for Nx core, we took this chance to reevaluate how developers experience the terminal. With a new suite of Rust-based packages at our disposal, we're thrilled to share our brand new terminal UI (or TUI) for Nx 21. Let's dive in!
29+
30+
{% toc /%}
31+
32+
## The Status Quo
33+
34+
Let's first look at how the terminal behaves in Nx 20 and below. In a project with multiple packages, if you run `nx run-many`, what you'll first notice is that you get all the output from any continuous tasks mixed together in one giant stream. This is very typical in most terminal programs, but with monorepos it's not ideal. For instance, let's say we have a build error in one of our projects:
35+
36+
{% video-player src="/documentation/blog/media/2025-05-09/old-tui.mp4" alt="Showing the previous terminal experience for Nx" autoPlay=true loop=true /%}
37+
38+
It might be hard to notice that we had the error if we have multiple tasks being run, so unless we scroll up, we could miss it. This might sound trivial, but it's an annoyance that doesn't have to happen. It's also difficult to separate tasks that are continuous and those that have an ending.
39+
40+
## Rust To The Rescue
41+
42+
With the Rust migration, we've been looking at the Rust ecosystem and noticed how many terminal-based programs seem to provide a great TUI. For example, if we wanted a resource monitor that was written in Rust, there is `btop`, and it looks awesome:
43+
44+
![Screenshot showing the resource monitor btop](/blog/images/2025-05-09/btop.avif)
45+
46+
This led us to the Rust package [`ratatui`](https://ratatui.rs/), a Rust library for building TUIs. Ratatui provides common building blocks and hooks for working with terminal programs. With Ratatui, we went ahead and rebuilt our TUI with the following goals:
47+
48+
- Provide a great looking UI
49+
- Provide clear output for all tasks
50+
- Provide a way to interact with multiple running processes
51+
52+
So let's see what we've built:
53+
54+
![Screenshot of the Terminal UI for Nx](/blog/images/2025-05-09/tui.avif)
55+
56+
There are a few things going on here, so let's walk you through it.
57+
58+
## A Clear Overview Of Projects
59+
60+
One of the things you may notice is that instead of a stream of output, you're presented with a clear list of all project tasks being run for the given session. You can scroll through the list of tasks with the arrow keys or `h`/`j` if you're used to vim-based navigation.
61+
62+
To inspect a task and its output, you can press `Space` to open a new window with all of the output from that given task. If that output has a lot of content and you'd like to see something further up, you can hit `Tab` and then use the arrow keys to scroll up and down in the output.
63+
64+
![Screenshot of Nx Terminal UI showing how multiple running tasks appear in the sidebar](/blog/images/2025-05-09/multiple-tasks.avif)
65+
66+
If you have a lot of projects being run, and you'd like to filter the list of tasks, you can press `/` and type the project you're looking for.
67+
68+
![Screenshot of Nx Terminal UI showing how filters reduce the number of tasks visible](/blog/images/2025-05-09/filter.avif)
69+
70+
And finally, if there's a particular project that you'd like to constantly see the output for, you can pin the output by pressing `1` or `2`.
71+
72+
![Screenshot of Nx Terminal UI showing how pinning tabs results in their logs being visible](/blog/images/2025-05-09/pins.avif)
73+
74+
Now there are more key bindings in this new TUI, and to see them all, you can use the `?` key.
75+
76+
![Screenshot of Nx Terminal UI's help screen](/blog/images/2025-05-09/help.avif)
77+
78+
## Parting Thoughts
79+
80+
Now, while the new TUI is awesome, it currently is not available on Windows due to various issues with pseudo-terminals. While not ideal, we hope to resolve these issues as soon as possible, so keep an eye out! For macOS and Linux, you can upgrade to Nx 21 today to take advantage of the new TUI:
81+
82+
```shell
83+
nx migrate latest
84+
nx migrate --run-migrations
85+
```
86+
87+
Learn more:
88+
89+
- 🧠 [Nx AI Docs](/features/enhance-AI)
90+
- 🌩️ [Nx Cloud](/nx-cloud)
91+
- 👩‍💻 [Nx GitHub](https://github.com/nrwl/nx)
92+
- 👩‍💻 [Nx Console GitHub](https://github.com/nrwl/nx-console)
93+
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
94+
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)

docs/blog/images/2025-05-09/btop.avif

77.9 KB
Binary file not shown.
Binary file not shown.
Loading

0 commit comments

Comments
 (0)