diff --git a/astro-docs/netlify.toml b/astro-docs/netlify.toml
index 5b8d50a020d..834d98f43e2 100644
--- a/astro-docs/netlify.toml
+++ b/astro-docs/netlify.toml
@@ -36,6 +36,24 @@ to = "/docs/quickstart"
from = "/showcase/benchmarks/*"
to = "/docs/reference/benchmarks/:splat"
+# DOC-452: Old framework tutorials redirect to new topic-based tutorials
+[[redirects]]
+from = "/docs/getting-started/tutorials/react-monorepo-tutorial"
+to = "/docs/getting-started/tutorials/crafting-your-workspace"
+
+[[redirects]]
+from = "/docs/getting-started/tutorials/angular-monorepo-tutorial"
+to = "/docs/getting-started/tutorials/crafting-your-workspace"
+
+[[redirects]]
+from = "/docs/getting-started/tutorials/typescript-packages-tutorial"
+to = "/docs/getting-started/tutorials/crafting-your-workspace"
+
+# DOC-452: Learn Nx URLs redirect to Tutorials (in case any were indexed)
+[[redirects]]
+from = "/docs/getting-started/learn-nx/*"
+to = "/docs/getting-started/tutorials/:splat"
+
# Fix broken /docs/ paths still linked from CLI/Cloud source code (DOC-428)
[[redirects]]
from = "/docs/features/ci-features/self-healing"
diff --git a/astro-docs/sidebar.mts b/astro-docs/sidebar.mts
index 15353463157..1a6029e6994 100644
--- a/astro-docs/sidebar.mts
+++ b/astro-docs/sidebar.mts
@@ -37,28 +37,45 @@ const learnGroups: SidebarItems = [
{ label: 'Editor setup', link: 'getting-started/editor-setup' },
{
label: 'Tutorials',
- collapsed: false,
+ badge: 'New',
+ collapsed: true,
items: [
{
- label: 'React monorepo',
- link: 'getting-started/tutorials/react-monorepo-tutorial',
+ label: 'Crafting your workspace',
+ link: 'getting-started/tutorials/crafting-your-workspace',
},
{
- label: 'Angular monorepo',
- link: 'getting-started/tutorials/angular-monorepo-tutorial',
+ label: 'Managing dependencies',
+ link: 'getting-started/tutorials/managing-dependencies',
},
{
- label: 'TypeScript monorepo',
- link: 'getting-started/tutorials/typescript-packages-tutorial',
+ label: 'Configuring tasks',
+ link: 'getting-started/tutorials/configuring-tasks',
},
{
- label: 'Gradle monorepo',
- link: 'getting-started/tutorials/gradle-tutorial',
+ label: 'Running tasks',
+ link: 'getting-started/tutorials/running-tasks',
+ },
+ {
+ label: 'Caching tasks',
+ link: 'getting-started/tutorials/caching',
+ },
+ {
+ label: 'Understanding your workspace',
+ link: 'getting-started/tutorials/understanding-your-workspace',
+ },
+ {
+ label: 'Reduce boilerplate',
+ link: 'getting-started/tutorials/reducing-configuration-boilerplate',
},
{
label: 'Setting up CI',
link: 'getting-started/tutorials/self-healing-ci-tutorial',
},
+ {
+ label: 'Gradle monorepo',
+ link: 'getting-started/tutorials/gradle-tutorial',
+ },
],
},
],
diff --git a/astro-docs/src/assets/tutorials/cache-hash-flow.svg b/astro-docs/src/assets/tutorials/cache-hash-flow.svg
new file mode 100644
index 00000000000..4e8183bb422
--- /dev/null
+++ b/astro-docs/src/assets/tutorials/cache-hash-flow.svg
@@ -0,0 +1,54 @@
+
diff --git a/astro-docs/src/assets/tutorials/project-graph-edge.png b/astro-docs/src/assets/tutorials/project-graph-edge.png
new file mode 100644
index 00000000000..2cfcf64993a
Binary files /dev/null and b/astro-docs/src/assets/tutorials/project-graph-edge.png differ
diff --git a/astro-docs/src/assets/tutorials/task-dependency-order.svg b/astro-docs/src/assets/tutorials/task-dependency-order.svg
new file mode 100644
index 00000000000..99130a65aec
--- /dev/null
+++ b/astro-docs/src/assets/tutorials/task-dependency-order.svg
@@ -0,0 +1,44 @@
+
diff --git a/astro-docs/src/assets/tutorials/task-graph-view.png b/astro-docs/src/assets/tutorials/task-graph-view.png
new file mode 100644
index 00000000000..ba5e6042f27
Binary files /dev/null and b/astro-docs/src/assets/tutorials/task-graph-view.png differ
diff --git a/astro-docs/src/content/docs/concepts/how-caching-works.mdoc b/astro-docs/src/content/docs/concepts/how-caching-works.mdoc
index a5119565bbd..268f5baef8d 100644
--- a/astro-docs/src/content/docs/concepts/how-caching-works.mdoc
+++ b/astro-docs/src/content/docs/concepts/how-caching-works.mdoc
@@ -214,6 +214,10 @@ npx nx build footer
## Next steps
+{% aside type="tip" title="Learn by doing" %}
+Try the [Caching](/docs/getting-started/tutorials/caching) tutorial to apply these concepts in your own workspace.
+{% /aside %}
+
Learn more about how to configure caching, where the cache is stored, how to reset it and more.
- [Cache Task Results](/docs/features/cache-task-results)
diff --git a/astro-docs/src/content/docs/concepts/inferred-tasks.mdoc b/astro-docs/src/content/docs/concepts/inferred-tasks.mdoc
index 4dd05a29b6d..2f08fcdf80e 100644
--- a/astro-docs/src/content/docs/concepts/inferred-tasks.mdoc
+++ b/astro-docs/src/content/docs/concepts/inferred-tasks.mdoc
@@ -338,6 +338,10 @@ More details about how to override task configuration is available in these guid
## Existing Nx workspaces
+{% aside type="tip" title="Learn by doing" %}
+Try the [Reducing Configuration Boilerplate](/docs/getting-started/tutorials/reducing-configuration-boilerplate) tutorial to apply these concepts in your own workspace.
+{% /aside %}
+
If you have an existing Nx Workspace and upgrade to the latest Nx version, a migration will automatically set `useInferencePlugins` to `false` in `nx.json`. This property allows you to continue to use Nx without inferred tasks.
When `useInferencePlugins` is `false`:
diff --git a/astro-docs/src/content/docs/concepts/nx-plugins.mdoc b/astro-docs/src/content/docs/concepts/nx-plugins.mdoc
index ae9afe0285f..2e7f3b296b7 100644
--- a/astro-docs/src/content/docs/concepts/nx-plugins.mdoc
+++ b/astro-docs/src/content/docs/concepts/nx-plugins.mdoc
@@ -24,5 +24,9 @@ For example, plugins can accomplish the following:
## Types of plugins
+{% aside type="tip" title="Learn by doing" %}
+Try the [Reducing Configuration Boilerplate](/docs/getting-started/tutorials/reducing-configuration-boilerplate) tutorial to apply these concepts in your own workspace.
+{% /aside %}
+
{% linkcard title="Official and Community Plugins" href="/docs/plugin-registry" description="Browse the plugin registry to discover plugins created by the Nx core team and the community" /%}
{% linkcard title="Build Your Own Plugin" href="/docs/extending-nx/organization-specific-plugin" description="Build your own plugin to use internally or share with the community" /%}
diff --git a/astro-docs/src/content/docs/concepts/task-pipeline-configuration.mdoc b/astro-docs/src/content/docs/concepts/task-pipeline-configuration.mdoc
index d89fe1a1520..863ed8e168c 100644
--- a/astro-docs/src/content/docs/concepts/task-pipeline-configuration.mdoc
+++ b/astro-docs/src/content/docs/concepts/task-pipeline-configuration.mdoc
@@ -97,4 +97,8 @@ These rules can be defined globally in the `nx.json` file or locally per project
## Configure it for your own project
+{% aside type="tip" title="Learn by doing" %}
+Try the [Configuring Tasks](/docs/getting-started/tutorials/configuring-tasks) tutorial to apply these concepts in your own workspace.
+{% /aside %}
+
Learn about all the details of how to configure [task pipelines in the according recipe section](/docs/guides/tasks--caching/defining-task-pipeline).
diff --git a/astro-docs/src/content/docs/concepts/types-of-configuration.mdoc b/astro-docs/src/content/docs/concepts/types-of-configuration.mdoc
index dfd9a36615d..a4bdc9302a0 100644
--- a/astro-docs/src/content/docs/concepts/types-of-configuration.mdoc
+++ b/astro-docs/src/content/docs/concepts/types-of-configuration.mdoc
@@ -50,5 +50,9 @@ repo/
## More information
+{% aside type="tip" title="Learn by doing" %}
+Try the [Configuring Tasks](/docs/getting-started/tutorials/configuring-tasks) tutorial to apply these concepts in your own workspace.
+{% /aside %}
+
- [Nx Configuration](/docs/reference/nx-json)
- [Project Configuration](/docs/reference/project-configuration)
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/caching.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/caching.mdoc
new file mode 100644
index 00000000000..54449d687f0
--- /dev/null
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/caching.mdoc
@@ -0,0 +1,222 @@
+---
+title: Caching Tasks
+description: Learn how Nx caching works, including computation hashing, inputs, outputs, and remote caching, to eliminate redundant task execution and speed up your workflow.
+sidebar:
+ order: 5
+---
+
+{% llm_copy_prompt title="Tutorial 5/8: Enable and configure caching" %}
+Help me set up caching in my Nx workspace.
+Use my existing workspace and projects for hands-on examples.
+
+Run a cacheable task twice to demonstrate cache hits. Then help me configure `cache: true`, `inputs`, and `outputs` for my tasks. Show me how to inspect what's cached with `nx show project `.
+
+If I'm hitting unexpected cache misses, help me debug by inspecting inputs and outputs with `nx show project`.
+
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
+
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+Why rebuild something that hasn't changed? Nx caching replays previous results instantly, saving minutes or hours of redundant work, both locally and in CI.
+
+The examples below use Vite and Vitest, but the concepts apply to any tool. Substitute your own build and test commands as needed.
+
+If you haven't already, set up your workspace ([Crafting Your Workspace](/docs/getting-started/tutorials/crafting-your-workspace)) and try [running some tasks](/docs/getting-started/tutorials/running-tasks) first.
+
+## Enabling caching
+
+Caching is opt-in per task. The recommended approach is to set `cache: true` in `targetDefaults` in `nx.json` for common cacheable tasks:
+
+```jsonc
+// nx.json
+{
+ "targetDefaults": {
+ "build": { "cache": true },
+ "test": { "cache": true },
+ "lint": { "cache": true },
+ },
+}
+```
+
+You can also enable caching per-project in `package.json` or `project.json`:
+
+{% tabs %}
+{% tabitem label="package.json" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "nx": {
+ "targets": {
+ "build": {
+ "cache": true,
+ },
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="project.json" %}
+
+```jsonc
+// apps/my-app/project.json
+{
+ "targets": {
+ "build": {
+ "cache": true,
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+{% aside type="caution" title="Only cache deterministic tasks" %}
+A task is safe to cache when the same inputs always produce the same outputs. Tasks that depend on network state, timestamps, or random values should not be cached.
+{% /aside %}
+
+## See it in action
+
+With caching enabled, run a build twice:
+
+```shell
+nx build my-app
+```
+
+The first run executes normally. Now run it again without changing anything:
+
+```shell
+nx build my-app
+```
+
+```text
+> NX Successfully ran target build for project my-app (40ms)
+
+ Nx read the output from the cache instead of running the command for 1 out of 1 tasks.
+```
+
+The second run completes in milliseconds. Nx detected that nothing changed, so it replayed the cached terminal output and restored the build artifacts. From your perspective, the command ran the same, just faster.
+
+## How caching works
+
+Before running any cacheable task, Nx computes a **unique hash** from the task's **inputs**:
+
+- Source files of the project and its dependencies
+- Relevant configuration files
+- Versions of external dependencies
+- CLI flags and arguments
+
+If the hash matches a previous run, Nx skips execution and replays the cached result. If not, Nx runs the task and stores the result for next time.
+
+
+
+## What gets cached
+
+Nx stores two things for each cached task:
+
+1. **Terminal output**: everything the task printed to stdout/stderr, replayed exactly
+2. **File artifacts**: output files restored to the correct location (e.g., `dist/`, `coverage/`, `test-results/`, `build/` for Gradle, `bin/` for .NET)
+
+Both are restored transparently. Other tools and scripts see the same files and output as if the task had actually run.
+
+{% aside type="note" title="Where is the cache stored?" %}
+Local cache is stored in `.nx/cache` by default. Run `nx reset` to clear all local cached results. If you've connected to Nx Cloud, remote cache entries are managed separately.
+{% /aside %}
+
+## Inputs and outputs
+
+**Inputs** are everything that could affect a task's result. **Outputs** are the files the task produces. Use [`{projectRoot}`](/docs/reference/inputs#source-files) to reference paths relative to the project directory and [`{workspaceRoot}`](/docs/reference/inputs#source-files) for workspace-level files.
+
+```jsonc
+// nx.json
+{
+ "targetDefaults": {
+ "build": {
+ "cache": true,
+ "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/tsconfig.json"],
+ "outputs": ["{projectRoot}/dist"],
+ },
+ },
+}
+```
+
+### Smart defaults
+
+Nx provides sensible defaults out of the box. For example, test specification files (like `*.spec.ts`) are typically excluded from build inputs because changing a test shouldn't invalidate the build cache. This is configured through [named inputs](/docs/reference/inputs):
+
+```jsonc
+// nx.json
+{
+ "namedInputs": {
+ "default": ["{projectRoot}/**/*"],
+ "production": [
+ "default",
+ "!{projectRoot}/**/*.spec.ts",
+ "!{projectRoot}/**/*.test.ts",
+ ],
+ },
+ "targetDefaults": {
+ "build": {
+ "inputs": ["production", "^production"],
+ "cache": true,
+ },
+ },
+}
+```
+
+The `^` prefix in inputs (like `"^production"`) means "include the production files of dependency projects as inputs." This is different from `^` in `dependsOn` (like `"^build"`), which means "run this task on dependencies first." The `^` in inputs affects the cache hash directly, while `^` in `dependsOn` affects task ordering.
+
+With this configuration, modifying a spec file won't bust the build cache, because specs aren't production inputs. But `test` tasks still use the `default` input set, which includes spec files.
+
+Inputs aren't limited to files. You can also include environment variables and runtime values in the hash:
+
+```jsonc
+// nx.json
+{
+ "namedInputs": {
+ "production": [
+ "default",
+ { "env": "NODE_ENV" },
+ { "runtime": "node --version" },
+ ],
+ },
+}
+```
+
+For more details, see [configure inputs](/docs/guides/tasks--caching/configure-inputs).
+
+{% aside type="tip" title="Enforce correct inputs and outputs" %}
+Not sure if your `inputs` and `outputs` are configured correctly? Use [sandboxing](/docs/features/ci-features/sandboxing) to detect tasks that read or write files outside their declared configuration.
+{% /aside %}
+
+Now that caching, inputs, and outputs are configured, try it out: change a source file and run `nx build my-app`. Nx detects the change, computes a new hash, and runs the build. Revert the change and run again to see the cached result restored, including the `dist/` output files.
+
+## Remote caching
+
+By default, Nx caches results on your local machine. **Remote caching** shares the cache across your entire team and CI pipeline, so a build that ran in CI doesn't need to run again on your machine.
+
+```shell
+# Connect your workspace to Nx Cloud for remote caching
+nx connect
+```
+
+This command guides you through creating a free Nx Cloud account and stores an access token in your workspace. Once connected, cached results are shared automatically.
+
+When a teammate or CI pipeline has already run a task with the same inputs, you get the cached result instantly, even on a fresh checkout.
+
+For more on how remote caching works, see [remote cache (Nx Replay)](/docs/features/ci-features/remote-cache). To set up CI with Nx Cloud, see [Setting up CI](/docs/getting-started/tutorials/self-healing-ci-tutorial).
+
+## Learn more
+
+- [How caching works](/docs/concepts/how-caching-works): deep dive on computation hashing
+- [Cache task results](/docs/features/cache-task-results): full feature documentation
+- [Configure inputs](/docs/guides/tasks--caching/configure-inputs): fine-tune what affects the hash
+- [Configure outputs](/docs/guides/tasks--caching/configure-outputs): control what files get cached
+
+{% cards cols=2 %}
+{% card title="Previous: Running Tasks" description="Run tasks for one or many projects" url="/docs/getting-started/tutorials/running-tasks" /%}
+{% card title="Next: Understanding Your Workspace" description="Explore projects, graphs, and debug issues" url="/docs/getting-started/tutorials/understanding-your-workspace" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/configuring-tasks.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/configuring-tasks.mdoc
new file mode 100644
index 00000000000..d23532858dc
--- /dev/null
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/configuring-tasks.mdoc
@@ -0,0 +1,228 @@
+---
+title: Configuring Tasks
+description: Learn how to define and configure tasks in your Nx workspace using package.json scripts, project.json targets, task dependencies, and targetDefaults.
+sidebar:
+ order: 3
+---
+
+{% llm_copy_prompt title="Tutorial 3/8: Configure tasks for your projects" %}
+Help me configure tasks (build, test, lint, serve) for my Nx workspace projects.
+Use my existing workspace and projects for hands-on examples.
+
+Show me what tasks already exist by running `nx show project ` for one of my projects. Then help me add or configure tasks using package.json scripts or project.json targets, set up task dependencies with `dependsOn`, and verify with `nx show project `.
+
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
+
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+Every project needs tasks: `build`, `test`, `lint`, `serve`. Nx needs to know about your tasks so it can run them, cache the results, and orchestrate them in the correct order across your workspace. If you don't have a workspace yet, see [Crafting Your Workspace](/docs/getting-started/tutorials/crafting-your-workspace).
+
+The examples below use Vite and Vitest, but the concepts apply to any tool. Substitute your own build and test commands as needed.
+
+## What is a task?
+
+A task is a named action that Nx can run for a project, like `build`, `test`, or `lint`. Each task belongs to a specific project and is referred to as `:`:
+
+```shell
+nx run my-app:build
+```
+
+You'll learn more about running tasks in the [Running Tasks](/docs/getting-started/tutorials/running-tasks) tutorial.
+
+## Defining tasks in package.json
+
+The simplest way to define tasks is with `package.json` scripts. Nx picks these up automatically:
+
+```jsonc
+// apps/my-app/package.json
+{
+ "name": "my-app",
+ "scripts": {
+ "build": "vite build",
+ "test": "vitest run",
+ },
+}
+```
+
+If your workspace already has `package.json` scripts, Nx can run them immediately, no additional configuration needed.
+
+## Defining tasks in project.json
+
+If you prefer to keep task definitions out of `package.json` (e.g., you don't want scripts published to npm) or for non-JavaScript projects, define tasks in a `project.json` file using the `targets` property:
+
+```jsonc
+// apps/my-app/project.json
+{
+ "name": "my-app",
+ "targets": {
+ "build": {
+ "command": "vite build",
+ },
+ "test": {
+ "command": "vitest run",
+ },
+ },
+}
+```
+
+The `command` property runs a shell command, similar to a `package.json` script. You can also use [executors](/docs/concepts/executors-and-configurations) for more advanced task runners provided by Nx plugins, but `command` works for most cases.
+
+{% aside type="note" title="package.json vs project.json" %}
+Both work. Define your scripts in `package.json` as usual. For Nx-specific configuration like `dependsOn`, `inputs`, or `outputs`, you have three options:
+
+- Set defaults for all projects in `targetDefaults` in `nx.json` (covered below)
+- Add an `nx` property in `package.json` (supports the same fields as `project.json`, but can bloat the file)
+- Use a separate `project.json` file
+
+See the [project configuration reference](/docs/reference/project-configuration) for details.
+{% /aside %}
+
+## Task dependencies
+
+In a monorepo, tasks often need to run in a specific order. For example, before building an app, you need to build the libraries it depends on.
+
+The `dependsOn` property defines this ordering:
+
+```jsonc
+// nx.json
+{
+ "targetDefaults": {
+ "build": {
+ "dependsOn": ["^build"],
+ },
+ },
+}
+```
+
+The `^` prefix means "the same task on projects this project depends on." So `nx build my-app` will first build all of `my-app`'s dependencies, then build `my-app` itself.
+
+You can also define dependencies without `^` for tasks within the same project:
+
+{% tabs %}
+{% tabitem label="package.json" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "scripts": {
+ "build": "vite build",
+ "generate-api-types": "openapi-generator generate -i api.yaml -o src/api",
+ },
+ "nx": {
+ "targets": {
+ "build": {
+ "dependsOn": ["generate-api-types"],
+ },
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="project.json" %}
+
+```jsonc
+// apps/my-app/project.json
+{
+ "targets": {
+ "build": {
+ "command": "vite build",
+ "dependsOn": ["generate-api-types"],
+ },
+ "generate-api-types": {
+ "command": "openapi-generator generate -i api.yaml -o src/api",
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+Here, `build` always runs `generate-api-types` first within the same project.
+
+## Continuous tasks
+
+Some tasks, like development servers, never exit. If another task depends on a long-running process, it would wait forever. Mark these tasks as `continuous` so Nx starts them alongside their dependents instead of waiting for them to finish:
+
+{% tabs %}
+{% tabitem label="package.json" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "scripts": {
+ "dev": "vite dev",
+ "e2e": "playwright test",
+ },
+ "nx": {
+ "targets": {
+ "dev": {
+ "continuous": true,
+ },
+ "e2e": {
+ "dependsOn": ["dev"],
+ },
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="project.json" %}
+
+```jsonc
+// apps/my-app/project.json
+{
+ "targets": {
+ "serve": {
+ "command": "vite dev",
+ "continuous": true,
+ },
+ "e2e": {
+ "command": "playwright test",
+ "dependsOn": ["serve"],
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+Running `nx e2e my-app` starts the dev server and then runs the E2E tests against it.
+
+{% aside type="note" %}
+Substitute your own tools as needed. Any long-running process (like `next dev`, `webpack serve`, or a custom script) can be marked as `continuous`.
+{% /aside %}
+
+## Reducing repetition with target defaults
+
+When many projects share the same task configuration, defining it in every `project.json` is tedious. The `targetDefaults` property in `nx.json` lets you set defaults for all projects at once:
+
+```jsonc
+// nx.json
+{
+ "targetDefaults": {
+ "build": {
+ "dependsOn": ["^build"],
+ },
+ },
+}
+```
+
+Individual projects can still override these defaults when needed. The cascade order is: project-level config > target defaults > defaults.
+
+For more on reducing configuration, see [Reducing Configuration Boilerplate](/docs/getting-started/tutorials/reducing-configuration-boilerplate).
+
+## Learn more
+
+- [Project configuration reference](/docs/reference/project-configuration): all available target properties
+- [Task pipeline configuration](/docs/concepts/task-pipeline-configuration): deep dive on `dependsOn`
+- [Defining a task pipeline](/docs/guides/tasks--caching/defining-task-pipeline): step-by-step guide
+
+{% cards cols=2 %}
+{% card title="Previous: Managing Dependencies" description="Track dependencies between projects" url="/docs/getting-started/tutorials/managing-dependencies" /%}
+{% card title="Next: Running Tasks" description="Run tasks for one or many projects" url="/docs/getting-started/tutorials/running-tasks" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/crafting-your-workspace.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/crafting-your-workspace.mdoc
new file mode 100644
index 00000000000..e8f4ad07fb8
--- /dev/null
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/crafting-your-workspace.mdoc
@@ -0,0 +1,289 @@
+---
+title: Crafting Your Workspace
+description: Learn how to structure a monorepo workspace with Nx, including project organization, package manager workspaces, and TypeScript configuration.
+sidebar:
+ order: 1
+---
+
+{% llm_copy_prompt title="Tutorial 1/8: Set up an Nx workspace" %}
+Help me learn Nx step by step using this tutorial series.
+
+If my current directory already has nx.json, skip setup and teach me using my existing workspace.
+If I'm starting fresh, help me run create-nx-workspace and walk through the options.
+If I have an existing project without Nx, help me run nx init and verify it's set up correctly.
+
+After setup, verify with `cat nx.json` and walk me through what's in my workspace.
+
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
+
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+The Nx CLI is a task orchestrator, caching layer, and intelligence layer for monorepos. It works on top of your existing tools and repo structure. It doesn't replace your package manager, build tools, or test frameworks. It makes them faster and smarter.
+
+Nx works with any repo structure and plays well with tools you already use: pnpm workspaces, yarn workspaces, uv for Python, Gradle for Java, and more. The conventions shown below are recommendations, not requirements. Bring your own structure and Nx adapts to it.
+
+{% aside type="tip" title="Tutorial series" %}
+These tutorials work best when followed in order, but you can jump to any topic you need. Each page is self-contained with links to prerequisites.
+{% /aside %}
+
+{% llm_only %}
+IMPORTANT: Always use the CLI to create workspaces (`npx create-nx-workspace`). Do NOT use the cloud.nx.app browser flow, it requires interactive OAuth and is not suitable for AI agents. When helping users choose a preset, ask about their tech stack first.
+{% /llm_only %}
+
+## What is an Nx workspace?
+
+An Nx workspace is any directory that has an `nx.json` file at its root. This file tells Nx that the directory is a workspace and contains configuration for how Nx behaves: caching, task defaults, and plugins.
+
+A workspace can contain a single project or hundreds. Nx works with JavaScript/TypeScript, Java (Gradle), .NET, Go, and more.
+
+## Workspace structure
+
+Nx works with whatever folder structure you have. A common convention for JavaScript/TypeScript workspaces is separating **applications** from **packages** (shared libraries):
+
+{% filetree %}
+
+- my-workspace/
+ - apps/
+ - my-app/
+ - src/
+ - package.json
+ - tsconfig.json
+ - packages/
+ - shared-ui/
+ - src/
+ - package.json
+ - tsconfig.json
+ - nx.json
+ - package.json
+ - tsconfig.base.json
+ - tsconfig.json
+
+{% /filetree %}
+
+- **apps/**: Deployable applications (frontends, backends, CLIs)
+- **packages/**: Shared libraries consumed by apps or other packages
+- **nx.json**: Nx configuration (caching, task defaults, plugins)
+- **tsconfig.base.json**: Shared `compilerOptions` inherited by all projects
+- **tsconfig.json**: Root TypeScript configuration that references project-level `tsconfig.json` files
+
+You may also see `libs/` used in place of `packages/` in some Nx workspaces. Both work. The `packages/` convention aligns with common pnpm, yarn, and npm workspace conventions.
+
+This layout is a suggestion, not a requirement. You can organize projects however you like, including flat structures, nested directories, or patterns specific to your ecosystem. For non-JS workspaces, follow the monorepo conventions in your language (e.g., Gradle multi-project builds, uv workspaces). Nx identifies projects by their `package.json` or `project.json` files, not by folder names.
+
+Nx re-discovers projects automatically every time you run an `nx` command. No restart or registration step is needed when you add or remove a project.
+
+## Creating a workspace
+
+The fastest way to start is with `create-nx-workspace`:
+
+{% tabs syncKey="package-manager" %}
+{% tabitem label="npm" %}
+
+```shell
+npx create-nx-workspace@latest my-workspace
+```
+
+{% /tabitem %}
+{% tabitem label="pnpm" %}
+
+```shell
+pnpm dlx create-nx-workspace@latest my-workspace
+```
+
+{% /tabitem %}
+{% tabitem label="yarn" %}
+
+```shell
+yarn dlx create-nx-workspace@latest my-workspace
+```
+
+{% /tabitem %}
+{% tabitem label="bun" %}
+
+```shell
+bunx create-nx-workspace@latest my-workspace
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+The CLI walks you through choosing a starter template (React, Angular, Node, or a blank workspace) and configuring your stack.
+
+If you have an existing project, you can [add Nx to it](/docs/getting-started/start-with-existing-project) by running `nx init`. This adds an `nx.json` file to your workspace and optionally detects your tooling to configure plugins. Everything applies whether you created a new workspace or added Nx to an existing one.
+
+## Adding a project
+
+Create a new project by adding a directory with a `package.json`:
+
+```shell
+mkdir -p packages/my-lib
+```
+
+```jsonc
+// packages/my-lib/package.json
+{
+ "name": "@my-workspace/my-lib",
+}
+```
+
+Then add it as a dependency in the consuming project's `package.json`:
+
+```jsonc
+// apps/my-app/package.json
+{
+ "name": "@my-workspace/my-app",
+ "dependencies": {
+ "@my-workspace/my-lib": "workspace:*",
+ },
+}
+```
+
+The `@my-workspace` scope used in these tutorials is a placeholder. Your workspace will use whatever scope you chose during setup (e.g., `@org`, `@my-company`).
+
+After adding a new project, run your package manager's install command (e.g., `npm install`, `pnpm install`) to link it into the workspace.
+
+If you're using [Nx plugins](/docs/concepts/nx-plugins), you can also use generators to scaffold projects with boilerplate:
+
+```shell
+nx g @nx/js:lib packages/my-lib
+```
+
+For a full list of available generators, see [code generation](/docs/features/generate-code).
+
+## Package manager workspaces
+
+Nx builds on top of your package manager's workspace feature. Each project with a `package.json` is a workspace package that can depend on other packages in the workspace.
+
+{% tabs syncKey="package-manager" %}
+{% tabitem label="npm" %}
+
+```jsonc
+// package.json
+{
+ "workspaces": ["apps/*", "packages/*"],
+}
+```
+
+{% /tabitem %}
+{% tabitem label="pnpm" %}
+
+```yaml
+# pnpm-workspace.yaml
+packages:
+ - 'apps/*'
+ - 'packages/*'
+```
+
+{% /tabitem %}
+{% tabitem label="yarn" %}
+
+```jsonc
+// package.json
+{
+ "workspaces": ["apps/*", "packages/*"],
+}
+```
+
+{% /tabitem %}
+{% tabitem label="bun" %}
+
+```jsonc
+// package.json
+{
+ "workspaces": ["apps/*", "packages/*"],
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+This tells your package manager where to find projects. Nx reads this same configuration to discover projects in your workspace.
+
+{% aside type="note" title="Non-JavaScript workspaces" %}
+If you're not using a JS package manager (e.g., Python with uv, Java with Gradle), Nx can still discover projects via `project.json` files. Check your ecosystem's monorepo tooling for equivalent workspace support.
+{% /aside %}
+
+## How projects link to each other
+
+Package manager workspaces handle linking between projects. When you run `install`, your package manager symlinks local packages into `node_modules` so they can be imported like any npm package:
+
+```typescript
+import { Button } from '@my-workspace/shared-ui';
+```
+
+This works because `@my-workspace/shared-ui` resolves to the local `packages/shared-ui` directory via the symlink, not from the npm registry. Each project needs a `package.json` with a `name` field that matches what other projects import.
+
+Nx uses these same package relationships to automatically detect dependencies between projects, so no additional configuration is needed.
+
+For more details on how linking works, see your package manager's workspace documentation ([npm](https://docs.npmjs.com/cli/using-npm/workspaces), [pnpm](https://pnpm.io/workspaces), [yarn](https://yarnpkg.com/features/workspaces), [bun](https://bun.sh/docs/install/workspaces)).
+
+## TypeScript configuration
+
+For TypeScript workspaces, the recommended setup uses three levels of `tsconfig.json` files. This is the [solution-style project references](https://www.typescriptlang.org/docs/handbook/project-references.html) pattern recommended by the TypeScript team:
+
+**`tsconfig.base.json`** at the root shares `compilerOptions` across all projects:
+
+```jsonc
+// tsconfig.base.json
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "nodenext",
+ "moduleResolution": "nodenext",
+ "composite": true,
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "strict": true,
+ },
+}
+```
+
+**`tsconfig.json`** at the root lists all projects as references, so `tsc --build` knows about the full workspace:
+
+```jsonc
+// tsconfig.json
+{
+ "files": [],
+ "references": [
+ { "path": "./apps/my-app" },
+ { "path": "./packages/shared-ui" },
+ ],
+}
+```
+
+**`tsconfig.json`** in each project extends the base and declares its own references to other projects it depends on:
+
+```jsonc
+// apps/my-app/tsconfig.json
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "dist",
+ "rootDir": "src",
+ "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo",
+ },
+ "references": [{ "path": "../../packages/shared-ui" }],
+ "include": ["src/**/*"],
+}
+```
+
+This setup gives editors and language servers accurate type information per-project, enables incremental builds (only recompile what changed), and creates clear boundaries between projects. For more details, see [maintain TypeScript monorepos](/docs/features/maintain-typescript-monorepos).
+
+{% aside type="note" title="Workspaces using tsconfig path aliases" %}
+Some workspaces use TypeScript `paths` in `tsconfig.base.json` to link projects. This works but is not recommended for new workspaces. Path aliases were not designed for project linking, and solution-style project references work better with editors and build tools. See the [migration guide](/docs/technologies/typescript/guides/switch-to-workspaces-project-references) to switch.
+{% /aside %}
+
+## Non-JavaScript workspaces
+
+Nx is not limited to JavaScript. It works with any language or build tool:
+
+- **Gradle**: Nx detects Gradle projects and provides caching, affected analysis, and task orchestration. See the [Gradle tutorial](/docs/getting-started/tutorials/gradle-tutorial).
+- **Any tool**: If it runs from the command line, Nx can cache and orchestrate it.
+
+Nx adapts to your project layout rather than imposing one. Use the folder structure and dependency management conventions established by your language's ecosystem. Nx adds task orchestration, caching, and CI optimization on top of whatever you already have.
+
+{% cards cols=2 %}
+{% card title="Next: Managing Dependencies" description="Track dependencies between projects" url="/docs/getting-started/tutorials/managing-dependencies" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/managing-dependencies.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/managing-dependencies.mdoc
new file mode 100644
index 00000000000..8d8e0e8edcd
--- /dev/null
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/managing-dependencies.mdoc
@@ -0,0 +1,232 @@
+---
+title: Managing Dependencies
+description: Learn how Nx tracks dependencies between projects, how package manager workspaces handle internal packages, and strategies for managing external dependency versions.
+sidebar:
+ order: 2
+---
+
+{% llm_copy_prompt title="Tutorial 2/8: Understand project dependencies" %}
+Help me understand how my Nx workspace tracks dependencies between projects.
+Use my existing workspace and projects for hands-on examples.
+
+Run `nx graph` in my workspace and help me interpret the results. Show me which projects depend on each other and explain how Nx detects these relationships.
+
+If dependencies are missing or unexpected, help me debug by checking import paths, tsconfig paths, and package.json entries.
+
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
+
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+As your workspace grows, projects start depending on each other and on external packages. Nx automatically tracks these relationships so it can build projects in the right order, cache intelligently, and tell you what's affected by a change.
+
+{% aside type="note" title="Prerequisites" %}
+This tutorial assumes you have an Nx workspace with at least two projects. If you're starting fresh, complete [Crafting Your Workspace](/docs/getting-started/tutorials/crafting-your-workspace) first.
+{% /aside %}
+
+## Workspace libraries
+
+Workspace libraries are projects whose source lives in your workspace and are linked together by your package manager (see [Crafting Your Workspace](/docs/getting-started/tutorials/crafting-your-workspace) for how this works). In your project's `package.json`, workspace libraries use `workspace:*` (or `*` for npm) while external packages use version ranges:
+
+{% tabs syncKey="package-manager" %}
+{% tabitem label="npm" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "dependencies": {
+ "react": "^19.0.0",
+ "@my-workspace/shared-ui": "*",
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="pnpm" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "dependencies": {
+ "react": "^19.0.0",
+ "@my-workspace/shared-ui": "workspace:*",
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="yarn" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "dependencies": {
+ "react": "^19.0.0",
+ "@my-workspace/shared-ui": "workspace:*",
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="bun" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "dependencies": {
+ "react": "^19.0.0",
+ "@my-workspace/shared-ui": "workspace:*",
+ },
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+When one project imports from another, Nx detects the relationship automatically. No configuration required.
+
+```typescript
+// apps/my-app/src/app.tsx
+import { Button } from '@my-workspace/shared-ui';
+```
+
+Nx analyzes your JS/TS source code and `package.json` dependencies to understand how projects relate to each other. Nx uses these relationships to [run tasks](/docs/getting-started/tutorials/running-tasks) in the correct order.
+
+{% aside type="note" title="Non-JavaScript languages" %}
+For non-JS languages, Nx does not detect dependencies from source code imports. Declare relationships manually with `implicitDependencies` in `project.json`:
+
+```jsonc
+// apps/my-python-app/project.json
+{
+ "implicitDependencies": ["shared-lib"],
+}
+```
+
+You can also use [community plugins](/docs/plugin-registry) that provide dependency detection for your language.
+{% /aside %}
+
+### Buildable vs non-buildable libraries
+
+Workspace libraries come in two flavors, and the difference is in what their `package.json` `exports` field points to.
+
+**Non-buildable libraries** export their source code directly. Consumers compile the source as part of their own build. This is the simpler setup and works well for most workspace libraries.
+
+```jsonc
+// packages/shared-ui/package.json
+{
+ "name": "@my-workspace/shared-ui",
+ "exports": {
+ ".": "./src/index.ts",
+ },
+}
+```
+
+**Buildable libraries** export compiled artifacts. They have their own build step that produces output (e.g., to `dist/`), and consumers import the built result. This is useful for libraries that need to be published or that benefit from independent compilation. Use a conditional export so that tooling can still resolve to the source:
+
+```jsonc
+// packages/data-access/package.json
+{
+ "name": "@my-workspace/data-access",
+ "exports": {
+ ".": {
+ "development": "./src/index.ts",
+ "default": "./dist/index.js",
+ },
+ },
+}
+```
+
+The `development` condition points to source, while `default` points to the built output. Configure `customConditions` in your root `tsconfig.json` so your IDE and TypeScript language server resolve the `development` entry, giving you go-to-definition and type checking against the actual source:
+
+```jsonc
+// tsconfig.json
+{
+ "compilerOptions": {
+ "customConditions": ["development"],
+ },
+}
+```
+
+At build time, the bundler resolves the `default` entry and uses the compiled artifacts.
+
+Start with non-buildable libraries. They're simpler and avoid needing to rebuild libraries during development. Switch to buildable when you need to publish a library or want faster incremental builds in large workspaces.
+
+## Single version policy
+
+In a monorepo, some packages, especially frameworks like React, Angular, or Vue, must be the same version everywhere. Having two versions of React in the same app causes runtime errors.
+
+A **single version policy** means defining dependency versions once at the root and having all projects use that version. This prevents version conflicts and simplifies upgrades.
+
+**Catalogs** make this easier by letting you name a version once and reference it everywhere:
+
+{% tabs syncKey="package-manager" %}
+{% tabitem label="pnpm" %}
+
+```yaml
+# pnpm-workspace.yaml
+catalog:
+ react: ^19.0.0
+ react-dom: ^19.0.0
+```
+
+```jsonc
+// package.json
+{
+ "dependencies": {
+ "react": "catalog:",
+ "react-dom": "catalog:",
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="yarn" %}
+
+Define catalogs in `.yarnrc.yml`:
+
+```yaml
+# .yarnrc.yml
+catalogs:
+ default:
+ react: ^19.0.0
+ react-dom: ^19.0.0
+```
+
+```jsonc
+// package.json
+{
+ "dependencies": {
+ "react": "catalog:",
+ "react-dom": "catalog:",
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="npm" %}
+
+npm does not have catalog support. Enforce a single version policy by defining all dependencies in the root `package.json` and using tools like `syncpack` or the `@nx/dependency-checks` ESLint rule to catch version mismatches.
+
+{% /tabitem %}
+{% tabitem label="bun" %}
+
+Bun does not currently support catalogs. Define shared dependency versions in the root `package.json` and reference them using `workspace:*` for internal packages.
+
+{% /tabitem %}
+{% /tabs %}
+
+For a deeper comparison of dependency strategies, see [Dependency Management Strategies](/docs/concepts/decisions/dependency-management).
+
+## What Nx does (and doesn't do)
+
+Nx **tracks** dependencies. It builds the project graph, determines build order, and knows what's affected by a change. But Nx **does not install or resolve** dependencies. That's your package manager's job (npm, pnpm, yarn, or bun).
+
+Think of it this way:
+
+- **Package manager**: installs packages, resolves versions, manages `node_modules`
+- **Nx**: understands the relationships, orchestrates tasks in the right order, caches results
+
+{% cards cols=2 %}
+{% card title="Previous: Crafting Your Workspace" description="Set up and structure your Nx workspace" url="/docs/getting-started/tutorials/crafting-your-workspace" /%}
+{% card title="Next: Configuring Tasks" description="Define tasks and their dependencies" url="/docs/getting-started/tutorials/configuring-tasks" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/reducing-configuration-boilerplate.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/reducing-configuration-boilerplate.mdoc
new file mode 100644
index 00000000000..91d3f45efb3
--- /dev/null
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/reducing-configuration-boilerplate.mdoc
@@ -0,0 +1,373 @@
+---
+title: Reducing Configuration Boilerplate
+description: Learn how Nx plugins automatically infer tasks from your tooling configuration, eliminating the need to manually define targets, caching, inputs, and outputs.
+sidebar:
+ order: 7
+---
+
+{% llm_copy_prompt title="Tutorial 7/8: Reduce configuration with plugins" %}
+Help me reduce configuration boilerplate in my Nx workspace.
+Use my existing workspace and projects for hands-on examples.
+
+First, consolidate shared task config into `targetDefaults` in `nx.json`. Then show me how to use Nx plugins to automatically infer tasks from my tooling (Vite, Jest, ESLint, etc.) so I don't need to configure each project manually.
+
+Run `nx show project ` to see where each task's configuration comes from.
+
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
+
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+Manually configuring tasks, caching, inputs, and outputs for every project works, but it doesn't scale to dozens or hundreds of projects. Nx provides two mechanisms to reduce this boilerplate: `targetDefaults` for shared configuration and **plugins** for automatic task inference.
+
+The examples below use Vite and Vitest, but the concepts apply to any tool. Substitute your own build and test commands as needed.
+
+{% aside type="note" title="Prerequisites" %}
+This tutorial assumes you have an Nx workspace with configured tasks. If you're starting fresh, complete [Configuring Tasks](/docs/getting-started/tutorials/configuring-tasks) first.
+{% /aside %}
+
+## The scaling problem
+
+Consider a workspace with 20 libraries, each with verbose task configuration:
+
+{% tabs %}
+{% tabitem label="package.json" %}
+
+```jsonc
+// packages/my-lib/package.json
+{
+ "scripts": {
+ "build": "vite build",
+ "test": "vitest run",
+ },
+ "nx": {
+ "targets": {
+ "build": {
+ "cache": true,
+ "dependsOn": ["^build"],
+ "inputs": [
+ "{projectRoot}/src/**/*",
+ "{projectRoot}/vite.config.ts",
+ "{projectRoot}/tsconfig.json",
+ ],
+ "outputs": ["{projectRoot}/dist"],
+ },
+ "test": {
+ "cache": true,
+ "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/vitest.config.ts"],
+ "outputs": ["{projectRoot}/coverage"],
+ },
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="project.json" %}
+
+```jsonc
+// packages/my-lib/project.json
+{
+ "targets": {
+ "build": {
+ "command": "vite build",
+ "cache": true,
+ "dependsOn": ["^build"],
+ "inputs": [
+ "{projectRoot}/src/**/*",
+ "{projectRoot}/vite.config.ts",
+ "{projectRoot}/tsconfig.json",
+ ],
+ "outputs": ["{projectRoot}/dist"],
+ },
+ "test": {
+ "command": "vitest run",
+ "cache": true,
+ "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/vitest.config.ts"],
+ "outputs": ["{projectRoot}/coverage"],
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+That's a lot of repetition across 20 projects. And every time you change the Vite output directory, you'd need to update all of them.
+
+## Step 1: Target defaults
+
+Move shared configuration to `nx.json` so projects inherit defaults:
+
+```jsonc
+// nx.json
+{
+ "targetDefaults": {
+ "build": {
+ "cache": true,
+ "dependsOn": ["^build"],
+ },
+ "test": {
+ "cache": true,
+ },
+ },
+}
+```
+
+Now each project only needs to specify what's unique:
+
+{% tabs %}
+{% tabitem label="package.json" %}
+
+```jsonc
+// packages/my-lib/package.json
+{
+ "scripts": {
+ "build": "vite build",
+ "test": "vitest run",
+ },
+ "nx": {
+ "targets": {
+ "build": {
+ "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/vite.config.ts"],
+ "outputs": ["{projectRoot}/dist"],
+ },
+ "test": {
+ "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/vitest.config.ts"],
+ "outputs": ["{projectRoot}/coverage"],
+ },
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="project.json" %}
+
+```jsonc
+// packages/my-lib/project.json
+{
+ "targets": {
+ "build": {
+ "command": "vite build",
+ "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/vite.config.ts"],
+ "outputs": ["{projectRoot}/dist"],
+ },
+ "test": {
+ "command": "vitest run",
+ "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/vitest.config.ts"],
+ "outputs": ["{projectRoot}/coverage"],
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+Better, but you still repeat `inputs` and `outputs` across projects with the same tooling.
+
+## Step 2: Nx plugins (inferred tasks)
+
+Nx plugins can read your existing tooling configuration files, like `vite.config.ts`, `jest.config.ts`, or `eslint.config.mjs`, and automatically create tasks with the correct caching settings. No `project.json` needed.
+
+### Adding a plugin
+
+Try adding a plugin to your workspace:
+
+```shell
+nx add @nx/vite
+```
+
+This installs `@nx/vite` and registers it in `nx.json`. Some plugins may also need `nx sync` to update workspace configuration files (e.g., TypeScript project references). See [maintain TypeScript monorepos](/docs/features/maintain-typescript-monorepos) for details.
+
+After installing, check what tasks were inferred for one of your projects:
+
+```shell
+nx show project my-app
+```
+
+You should see tasks like `build`, `test`, and `serve` that were automatically created from your `vite.config.ts` file.
+
+{% aside type="note" title="Prefixed target names" %}
+Some plugins use prefixed names (e.g., `next:build`, `next:dev`) to avoid conflicting with existing `package.json` scripts. You can rename these to `build`, `dev`, etc. in the plugin options in `nx.json`, then remove the redundant scripts from `package.json`.
+{% /aside %}
+
+The plugin reads your Vite configuration and sets up correct caching, inputs, and outputs without any manual configuration.
+
+The plugin is registered in `nx.json`:
+
+```jsonc
+// nx.json
+{
+ "plugins": [
+ {
+ "plugin": "@nx/vite/plugin",
+ "options": {
+ "buildTargetName": "build",
+ "testTargetName": "test",
+ "serveTargetName": "serve",
+ },
+ },
+ ],
+}
+```
+
+Now, any project with a `vite.config.ts` automatically gets `build`, `test`, and `serve` tasks, with correct `inputs`, `outputs`, and caching, without any `project.json` configuration.
+
+### Seeing what's inferred
+
+Use `nx show project` to see all tasks for a project, including where they come from:
+
+```shell
+nx show project my-lib
+```
+
+{% project_details title="Project details for my-lib" %}
+
+```json
+{
+ "project": {
+ "name": "my-lib",
+ "type": "lib",
+ "data": {
+ "root": "packages/my-lib",
+ "targets": {
+ "build": {
+ "options": { "cwd": "packages/my-lib", "command": "vite build" },
+ "cache": true,
+ "dependsOn": ["^build"],
+ "inputs": ["production", "^production"],
+ "outputs": ["{projectRoot}/dist"],
+ "executor": "nx:run-commands",
+ "configurations": {},
+ "metadata": { "technologies": ["vite"] }
+ },
+ "test": {
+ "options": { "cwd": "packages/my-lib", "command": "vitest run" },
+ "cache": true,
+ "inputs": ["default", "^production"],
+ "outputs": ["{projectRoot}/coverage"],
+ "executor": "nx:run-commands",
+ "configurations": {},
+ "metadata": { "technologies": ["vite"] }
+ },
+ "lint": {
+ "cache": true,
+ "options": { "cwd": "packages/my-lib", "command": "eslint ." },
+ "inputs": ["default", "{workspaceRoot}/eslint.config.mjs"],
+ "executor": "nx:run-commands",
+ "configurations": {},
+ "metadata": { "technologies": ["eslint"] }
+ }
+ },
+ "name": "my-lib",
+ "sourceRoot": "packages/my-lib/src",
+ "projectType": "library",
+ "tags": [],
+ "implicitDependencies": [],
+ "metadata": { "technologies": ["react"] }
+ }
+ },
+ "sourceMap": {
+ "root": ["packages/my-lib/project.json", "nx/core/project-json"],
+ "targets": ["packages/my-lib/project.json", "nx/core/project-json"],
+ "targets.build": ["packages/my-lib/vite.config.ts", "@nx/vite/plugin"],
+ "targets.build.command": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.build.options": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.build.cache": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.build.inputs": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.build.outputs": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.test": ["packages/my-lib/vite.config.ts", "@nx/vite/plugin"],
+ "targets.test.command": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.test.options": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.test.cache": ["packages/my-lib/vite.config.ts", "@nx/vite/plugin"],
+ "targets.test.inputs": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.test.outputs": [
+ "packages/my-lib/vite.config.ts",
+ "@nx/vite/plugin"
+ ],
+ "targets.lint": ["packages/my-lib/eslint.config.mjs", "@nx/eslint/plugin"],
+ "targets.lint.command": [
+ "packages/my-lib/eslint.config.mjs",
+ "@nx/eslint/plugin"
+ ],
+ "targets.lint.options": [
+ "packages/my-lib/eslint.config.mjs",
+ "@nx/eslint/plugin"
+ ],
+ "targets.lint.cache": [
+ "packages/my-lib/eslint.config.mjs",
+ "@nx/eslint/plugin"
+ ],
+ "targets.lint.inputs": [
+ "packages/my-lib/eslint.config.mjs",
+ "@nx/eslint/plugin"
+ ]
+ }
+}
+```
+
+{% /project_details %}
+
+The project details view shows each task's source (plugin, `targetDefaults`, or `project.json`) and its computed settings.
+
+## How the configuration cascade works
+
+Task configuration can come from three sources, applied in this order:
+
+1. **Plugin-inferred**: automatic from tooling config (lowest priority)
+2. **targetDefaults**: shared defaults in `nx.json`
+3. **Project-level**: explicit `project.json` or `package.json` config (highest priority)
+
+Each layer can override the previous one. This means you can use plugins for sensible defaults and only add project-level config when a project needs something different.
+
+## This is optional
+
+Plugins are optional. The explicit task configuration from [Configuring Tasks](/docs/getting-started/tutorials/configuring-tasks) works perfectly well. Use plugins when:
+
+- You have many projects with the same tooling (Vite, Jest, ESLint, etc.)
+- You want caching configured automatically with correct `inputs`/`outputs`
+- You prefer minimal configuration files
+
+Stick with explicit configuration when:
+
+- You have unique build setups that plugins don't cover
+- You want full control over every task detail
+- Your team prefers explicit over implicit
+
+## Learn more
+
+- [Inferred tasks](/docs/concepts/inferred-tasks): how plugins detect and configure tasks
+- [Nx plugins](/docs/concepts/nx-plugins): the full plugin system
+- [Reduce repetitive configuration](/docs/guides/tasks--caching/reduce-repetitive-configuration): step-by-step guide
+- [Extending Nx](/docs/extending-nx/intro): create your own plugins
+
+{% cards cols=2 %}
+{% card title="Previous: Understanding Your Workspace" description="Explore projects, graphs, and debug issues" url="/docs/getting-started/tutorials/understanding-your-workspace" /%}
+{% card title="Next: Setting Up CI" description="Configure CI with remote caching and self-healing" url="/docs/getting-started/tutorials/self-healing-ci-tutorial" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/running-tasks.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/running-tasks.mdoc
new file mode 100644
index 00000000000..be61b925cb0
--- /dev/null
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/running-tasks.mdoc
@@ -0,0 +1,164 @@
+---
+title: Running Tasks
+description: Learn how to run tasks in your Nx workspace, including single tasks, multiple tasks in parallel, and how to pass arguments.
+sidebar:
+ order: 4
+---
+
+{% llm_copy_prompt title="Tutorial 4/8: Run tasks across your workspace" %}
+Help me run tasks in my Nx workspace efficiently.
+Use my existing workspace and projects for hands-on examples.
+
+Show me how to run a single task for one project, run multiple tasks across all projects with `nx run-many`, and understand how Nx orders task execution. Do not discuss caching or affected commands — those are covered in later tutorials.
+
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
+
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+You've [configured your tasks](/docs/getting-started/tutorials/configuring-tasks). Now how do you run them, for one project, for many, or only for what changed?
+
+The examples below use Vite and Vitest, but the concepts apply to any tool. Substitute your own build and test commands as needed.
+
+## Running a single task
+
+Given a project with tasks defined in `package.json` (or `project.json` for non-JS projects):
+
+{% tabs %}
+{% tabitem label="package.json" %}
+
+```jsonc
+// apps/my-app/package.json
+{
+ "name": "my-app",
+ "scripts": {
+ "build": "vite build",
+ "test": "vitest run",
+ },
+}
+```
+
+{% /tabitem %}
+{% tabitem label="project.json" %}
+
+```jsonc
+// apps/my-app/project.json
+{
+ "targets": {
+ "build": {
+ "command": "vite build",
+ },
+ "test": {
+ "command": "vitest run",
+ },
+ },
+}
+```
+
+{% /tabitem %}
+{% /tabs %}
+
+Run a task with `nx run :`:
+
+```shell
+nx run my-app:build
+```
+
+Or the shorthand, which works when the task name doesn't conflict with an Nx command:
+
+```shell
+nx build my-app
+```
+
+You can also `cd` into a project directory and run without specifying the project name:
+
+```shell
+cd apps/my-app
+nx build
+```
+
+Nx resolves the project from the current directory. Try running `nx build` or `nx test` in your own workspace to see it in action.
+
+## Running multiple tasks
+
+Use `run-many` to run one or more tasks across multiple projects:
+
+```shell
+# Run build for all projects that have a build task
+nx run-many --targets build
+
+# Run multiple tasks
+nx run-many --targets build test lint
+
+# Run tasks for specific projects only
+nx run-many --targets build --projects my-app
+```
+
+The `-t` and `-p` flags are shorthands for `--targets` and `--projects`.
+
+Nx runs tasks in parallel by default, respecting the [task dependencies](/docs/getting-started/tutorials/configuring-tasks) you've configured. For example, with this configuration:
+
+```jsonc
+// nx.json
+{
+ "targetDefaults": {
+ "build": {
+ "dependsOn": ["^build"],
+ },
+ },
+}
+```
+
+Running `nx run-many --targets build` builds dependencies first, then dependents:
+
+
+
+Nx handles the ordering automatically, even when running in parallel.
+
+## Passing arguments
+
+Pass arguments directly to the task:
+
+```shell
+# Use a named configuration
+nx build my-app --configuration=production
+
+# Forward arguments to the underlying tool
+nx test my-app --watch
+```
+
+For more details, see [pass args to commands](/docs/guides/tasks--caching/pass-args-to-commands).
+
+## Controlling parallelism
+
+By default, Nx runs tasks in parallel. Limit the number of concurrent tasks with `--parallel`:
+
+```shell
+nx run-many --targets build --parallel=3
+```
+
+Set `--parallel=1` to run tasks sequentially.
+
+## Running continuous tasks
+
+Some tasks run indefinitely, like development servers. When another task depends on a continuous task, Nx starts both concurrently. For example, running an e2e test that needs a dev server:
+
+```shell
+nx run my-app:e2e
+```
+
+This works when `e2e` depends on a `serve` task marked as `continuous` (configured in [Configuring Tasks](/docs/getting-started/tutorials/configuring-tasks)). Nx starts the server, waits for it to be ready, then runs the tests.
+
+## Nx Console
+
+[Nx Console](/docs/getting-started/editor-setup) is a VS Code and WebStorm extension that provides a visual interface for running tasks, exploring your project graph, and managing your workspace, all without memorizing CLI commands.
+
+## Learn more
+
+- [Run tasks](/docs/features/run-tasks): full feature documentation
+- [Pass args to commands](/docs/guides/tasks--caching/pass-args-to-commands): detailed argument handling
+
+{% cards cols=2 %}
+{% card title="Previous: Configuring Tasks" description="Define tasks and their dependencies" url="/docs/getting-started/tutorials/configuring-tasks" /%}
+{% card title="Next: Caching Tasks" description="Speed up tasks by replaying previous results" url="/docs/getting-started/tutorials/caching" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/self-healing-ci-tutorial.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/self-healing-ci-tutorial.mdoc
index 8d16529cc58..1b3867b4a9b 100644
--- a/astro-docs/src/content/docs/getting-started/Tutorials/self-healing-ci-tutorial.mdoc
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/self-healing-ci-tutorial.mdoc
@@ -1,51 +1,63 @@
---
title: 'Setting Up CI'
-description: Configure CI for your Nx workspace with remote caching and self-healing to keep your pipeline fast and reliable.
+description: Configure CI for your Nx workspace with remote caching, affected commands, distributed task execution, and self-healing to keep your pipeline fast and reliable.
sidebar:
label: 'Setting Up CI'
filter: 'type:Guides'
---
-This tutorial walks you through configuring CI for your Nx workspace. You'll set up a CI pipeline, enable remote caching to speed up runs, and configure self-healing CI to automatically fix failures.
+{% llm_copy_prompt title="Tutorial 8/8: Set up CI with Nx Cloud" %}
+Help me set up CI for my Nx workspace.
-What you'll learn:
+Connect to Nx Cloud with `nx connect`, generate a CI workflow with `nx g @nx/workspace:ci-workflow`, and walk me through remote caching, affected commands, and self-healing CI.
-- How to connect your workspace to Nx Cloud
-- How to generate a CI workflow for GitHub Actions
-- How remote caching avoids redundant work across CI runs
-- How self-healing CI detects and fixes failures automatically
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
-## Prerequisites
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+Connect your workspace to Nx Cloud, generate a CI workflow, and enable remote caching, affected commands, distributed task execution, and self-healing to keep your pipeline fast and reliable.
{% aside type="note" title="Prerequisites" %}
-- An existing Nx workspace (see our [React](/docs/getting-started/tutorials/react-monorepo-tutorial), [Angular](/docs/getting-started/tutorials/angular-monorepo-tutorial), or [TypeScript](/docs/getting-started/tutorials/typescript-packages-tutorial) tutorials)
+- An existing Nx workspace (see [Crafting Your Workspace](/docs/getting-started/tutorials/crafting-your-workspace) or the [Gradle tutorial](/docs/getting-started/tutorials/gradle-tutorial))
- A [GitHub account](https://github.com) with a repository for your workspace
- [Node.js](https://nodejs.org) (v20.19 or later)
{% /aside %}
-## Step 1: Connect to Nx Cloud
+## Connect to Nx Cloud
Connect your workspace to Nx Cloud to enable remote caching and CI features:
+{% aside type="note" title="Prerequisites for nx connect" %}
+Your workspace must be pushed to a Git provider (GitHub, GitLab, Bitbucket, or Azure DevOps) before running `nx connect`. After connecting, Nx Cloud opens a PR that adds `nxCloudId` to `nx.json`. Merge this PR before proceeding so CI runs appear on the Nx Cloud dashboard.
+{% /aside %}
+
```shell
-npx nx connect
+nx connect
```
This creates an Nx Cloud account (if you don't have one) and connects your workspace. Once connected, you can see your workspace in your [Nx Cloud organization](https://cloud.nx.app/orgs).
-## Step 2: Generate a CI workflow
+The access token is stored in `nx.json` and should be committed to your repository. It only grants cache read/write access, not admin access to your Nx Cloud organization.
+
+## Generate a CI workflow
Generate a CI workflow configuration for GitHub Actions:
```shell
-npx nx g ci-workflow
+nx add @nx/workspace
+nx g @nx/workspace:ci-workflow --ci=github
```
-This creates a `.github/workflows/ci.yml` file that runs your tasks through Nx and includes the `fix-ci` command for self-healing:
+The `@nx/workspace` package provides the CI workflow generator. Once installed, the generator creates a `.github/workflows/ci.yml` file. It also supports CircleCI, GitLab CI, Azure Pipelines, and Bitbucket Pipelines. Pass a different `--ci` value or run `nx g @nx/workspace:ci-workflow --help` to see all options.
+
+{% aside type="note" title="Generated output may differ" %}
+The generated workflow may differ from the example below depending on your workspace setup and Nx version. The key elements (affected command, remote caching, fix-ci) will be present.
+{% /aside %}
-```yaml {% meta="{24,25}" %}
+```yaml
# .github/workflows/ci.yml
name: CI
@@ -75,67 +87,69 @@ jobs:
- run: npm ci
- - run: npx nx run-many -t lint test build
+ - run: npx nx affected -t lint test build
- - run: npx nx-cloud fix-ci
+ - run: npx nx fix-ci
if: always()
```
-The `npx nx-cloud fix-ci` command at the end is responsible for enabling self-healing CI. It analyzes any failing tasks and automatically suggests fixes.
+This workflow includes several Nx CI features out of the box. The sections below explain each one.
-## Step 3: Install Nx Console
+## Remote caching
-You will need the [Nx Console](/docs/getting-started/editor-setup) editor extension for VS Code, Cursor, or IntelliJ to receive CI notifications and apply fixes directly from your editor.
+When Nx Cloud is connected, task results are cached remotely. If a task has already run with the same inputs (on any machine or CI run), the result is replayed instantly instead of running again.
-{% install_nx_console /%}
+This means:
-For the complete AI setup guide, see our [AI integration documentation](/docs/getting-started/ai-setup).
+- The second CI run on a PR is faster because unchanged tasks hit the cache
+- Developers pulling the latest `main` get cached results from CI
+- Build artifacts like `dist/` and test coverage are restored from cache, not recomputed
-## Step 4: Push a PR and see self-healing in action
+For more details, see [remote cache (Nx Replay)](/docs/features/ci-features/remote-cache).
-Create a branch, make a change (or introduce an intentional test failure), and push it:
+## Running only affected tasks
+
+The generated workflow uses `nx affected` instead of `nx run-many`. This compares the PR's changes against the base branch and only runs tasks for projects that could be impacted:
```shell
-git checkout -b my-feature
-git add .
-git commit -m 'my changes'
-git push origin my-feature
-# Don't forget to open a pull request on GitHub
+nx affected -t lint test build
```
-When CI runs and encounters a failure, Nx Console notifies you that the run has completed and that it has a suggested fix. You don't have to waste time **babysitting your PRs** — the fix can be applied directly from your editor.
+Nx determines the base and head commits using `NX_BASE` and `NX_HEAD` environment variables. The generated CI workflow configures these automatically through the `fetch-depth: 0` checkout, which gives Nx access to the full git history for comparison.
-### Fix CI from your editor
+On a PR, Nx compares the PR branch against `main` (or whatever `defaultBase` is set to in `nx.json`). On a push to `main`, it compares against the previous commit.
-From the Nx Console notification, click the `Show Suggested Fix` button. Review the suggested fix and approve it by clicking `Apply Fix`.
+For more details, see [affected](/docs/features/ci-features/affected).
-You don't have to leave your editor or do any manual work to fix it. This is the power of self-healing CI with Nx Cloud.
+## Distributing tasks across machines
-### Remote cache for faster time to green
+For larger workspaces, you can distribute task execution across multiple machines using Nx Agents. Instead of running all tasks on a single CI runner, Nx Cloud coordinates the work across a fleet of agents:
-After the fix has been applied and committed, CI will re-run automatically, and you will be notified of the results in your editor.
+```yaml
+# Add to your CI workflow
+- run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js"
+```
-When you view the results in Nx Cloud, you'll notice something interesting. Tasks for projects that weren't affected by your change were read from remote cache and did not have to run again, each taking less than a second to complete.
+Nx Agents automatically split tasks across the available agents, respecting task dependencies and maximizing parallelism. No configuration changes to your tasks are needed.
-This happens because Nx Cloud caches the results of tasks and reuses them across different CI runs. As long as the inputs for each task have not changed (e.g. source code), then their results can be replayed from Nx Cloud's [Remote Cache](/docs/features/ci-features/remote-cache).
+For more details, see [distribute task execution (Nx Agents)](/docs/features/ci-features/distribute-task-execution).
-This significantly speeds up the time to green for your pull requests, because subsequent changes to them have a good chance to replay tasks from cache.
+## Self-healing CI
-{% aside type="note" title="Remote Cache Outputs" %}
-Outputs from cached tasks, such as the `dist` folder for builds or `coverage` folder for tests, are also read from cache. Even though a task was not run again, its outputs are available. The [Cache Task Results](/docs/features/cache-task-results) page provides more details on caching.
-{% /aside %}
+The `npx nx fix-ci` command at the end of the workflow enables self-healing CI. When a task fails, Nx Cloud analyzes the failure and suggests a fix that you can apply directly from your editor (via [Nx Console](/docs/getting-started/editor-setup)).
-## Next steps
+This is useful for catching flaky tests, configuration drift, and other issues that can be auto-remediated without manual debugging.
+
+For more details, see [self-healing CI](/docs/features/ci-features/self-healing-ci).
-- Learn more about [Self-Healing CI](/docs/features/ci-features/self-healing-ci)
-- Learn about [Remote Cache](/docs/features/ci-features/remote-cache) and how it works
-- [Set up AI integration](/docs/getting-started/ai-setup) for enhanced AI-powered CI workflows
-- Learn more about the [underlying mental model of Nx](/docs/concepts/mental-model)
+## Next steps
-Also, make sure you
+- [Remote cache (Nx Replay)](/docs/features/ci-features/remote-cache): how remote caching works
+- [Affected](/docs/features/ci-features/affected): how Nx determines what changed
+- [Distribute task execution (Nx Agents)](/docs/features/ci-features/distribute-task-execution): run tasks across multiple machines
+- [Self-healing CI](/docs/features/ci-features/self-healing-ci): automatic failure detection and fixes
+- [AI integration](/docs/getting-started/ai-setup): enhance CI with AI-powered workflows
-- ⭐️ [Star us on GitHub](https://github.com/nrwl/nx) to show your support and stay updated on new releases!
-- [Join the Official Nx Discord Server](https://go.nx.dev/community) to ask questions and find out the latest news about Nx.
-- [Follow Nx on Twitter](https://twitter.com/nxdevtools) to stay up to date with Nx news
-- [Read our Nx blog](https://nx.dev/blog)
-- [Subscribe to our Youtube channel](https://www.youtube.com/@nxdevtools) for demos and Nx insights
+{% cards cols=2 %}
+{% card title="Previous: Reducing Configuration Boilerplate" description="Automate task configuration with plugins" url="/docs/getting-started/tutorials/reducing-configuration-boilerplate" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/getting-started/Tutorials/understanding-your-workspace.mdoc b/astro-docs/src/content/docs/getting-started/Tutorials/understanding-your-workspace.mdoc
new file mode 100644
index 00000000000..92f039086a4
--- /dev/null
+++ b/astro-docs/src/content/docs/getting-started/Tutorials/understanding-your-workspace.mdoc
@@ -0,0 +1,236 @@
+---
+title: Understanding Your Workspace
+description: Learn how to explore your Nx workspace, including listing projects, visualizing the project graph, inspecting task details, and debugging dependencies.
+sidebar:
+ order: 6
+---
+
+{% llm_copy_prompt title="Tutorial 6/8: Explore and debug your workspace" %}
+Help me explore and debug my Nx workspace.
+Use my existing workspace and projects for hands-on examples.
+
+Run `nx show projects` to list all projects, `nx graph` to visualize dependencies, and `nx show project ` to inspect task details. Help me understand why specific dependencies exist and debug any caching or configuration issues.
+
+For machine-readable output (useful for scripting or AI agents), use `nx show project --json`.
+
+Stay on-topic: only teach what's covered on this page. Do not introduce concepts from later tutorials.
+
+Tutorial: {pageUrl}
+{% /llm_copy_prompt %}
+
+As your workspace grows to dozens or hundreds of projects, you need tools to explore it, debug unexpected behavior, and verify your configuration. Nx provides several commands and visualizations for this.
+
+{% aside type="note" title="Prerequisites" %}
+This tutorial assumes you have an Nx workspace with projects and configured tasks. If you're starting fresh, complete [Crafting Your Workspace](/docs/getting-started/tutorials/crafting-your-workspace) first.
+{% /aside %}
+
+## The project graph
+
+The best starting point for understanding your workspace is `nx graph`. It opens an interactive visualization with tabs for projects, tasks, and project details:
+
+```shell
+nx graph
+```
+
+{% graph title="Project graph" height="400px" %}
+
+```json
+{
+ "projects": [
+ { "type": "app", "name": "my-app", "data": {} },
+ { "type": "app", "name": "admin", "data": {} },
+ { "type": "app", "name": "api", "data": {} },
+ { "type": "lib", "name": "shared-ui", "data": {} },
+ { "type": "lib", "name": "data-access", "data": {} },
+ { "type": "lib", "name": "auth", "data": {} },
+ { "type": "lib", "name": "utils", "data": {} },
+ { "type": "lib", "name": "models", "data": {} }
+ ],
+ "groupByFolder": false,
+ "workspaceLayout": { "appsDir": "apps", "libsDir": "packages" },
+ "dependencies": {
+ "my-app": [
+ { "target": "shared-ui", "source": "my-app", "type": "direct" },
+ { "target": "data-access", "source": "my-app", "type": "direct" },
+ { "target": "auth", "source": "my-app", "type": "direct" }
+ ],
+ "admin": [
+ { "target": "shared-ui", "source": "admin", "type": "direct" },
+ { "target": "data-access", "source": "admin", "type": "direct" },
+ { "target": "auth", "source": "admin", "type": "direct" }
+ ],
+ "api": [
+ { "target": "data-access", "source": "api", "type": "direct" },
+ { "target": "auth", "source": "api", "type": "direct" },
+ { "target": "models", "source": "api", "type": "direct" }
+ ],
+ "shared-ui": [
+ { "target": "utils", "source": "shared-ui", "type": "direct" }
+ ],
+ "data-access": [
+ { "target": "models", "source": "data-access", "type": "direct" },
+ { "target": "utils", "source": "data-access", "type": "direct" }
+ ],
+ "auth": [{ "target": "utils", "source": "auth", "type": "direct" }],
+ "utils": [],
+ "models": []
+ },
+ "affectedProjectIds": []
+}
+```
+
+{% /graph %}
+
+The project graph shows every project and the dependencies between them. You can:
+
+- **Search** for specific projects
+- **Filter** to show only affected projects or specific groups
+- **Click edges** between projects to see which files create the dependency (import statements, `package.json` references)
+
+### Why does this dependency exist?
+
+When you see an unexpected dependency in the graph, click the edge between the two projects. The sidebar shows which files contributed to the dependency:
+
+
+
+For scripting, write the graph to a JSON file:
+
+```shell
+nx graph --file=/tmp/graph.json
+```
+
+## The task graph
+
+Switch to the **Tasks** tab in the graph to visualize the task execution plan. Select a task (like `build`) to see which tasks run and in what order:
+
+
+
+You can also open this directly from the CLI:
+
+```shell
+nx build my-app --graph
+```
+
+This is useful for verifying that your `dependsOn` configuration is correct. Write the task graph to a file for analysis:
+
+```shell
+nx build my-app --graph=/tmp/task-graph.json
+```
+
+## Inspecting project details
+
+Click any project in the graph to see its details, or use the CLI:
+
+```shell
+nx show project my-app
+```
+
+{% project_details title="Project details" %}
+
+```json
+{
+ "project": {
+ "name": "my-app",
+ "type": "app",
+ "data": {
+ "root": "apps/my-app",
+ "targets": {
+ "build": {
+ "options": { "cwd": "apps/my-app", "command": "vite build" },
+ "cache": true,
+ "dependsOn": ["^build"],
+ "inputs": ["production", "^production"],
+ "outputs": ["{projectRoot}/dist"],
+ "executor": "nx:run-commands",
+ "configurations": {},
+ "metadata": { "technologies": ["vite"] }
+ },
+ "test": {
+ "options": { "cwd": "apps/my-app", "command": "vitest run" },
+ "cache": true,
+ "inputs": ["default", "^production"],
+ "outputs": ["{projectRoot}/coverage"],
+ "executor": "nx:run-commands",
+ "configurations": {},
+ "metadata": { "technologies": ["vite"] }
+ }
+ },
+ "name": "my-app",
+ "sourceRoot": "apps/my-app/src",
+ "projectType": "application",
+ "tags": [],
+ "metadata": { "technologies": ["react"] }
+ }
+ },
+ "sourceMap": {
+ "root": ["apps/my-app/project.json", "nx/core/project-json"],
+ "targets.build": ["apps/my-app/vite.config.ts", "@nx/vite/plugin"],
+ "targets.test": ["apps/my-app/vite.config.ts", "@nx/vite/plugin"]
+ }
+}
+```
+
+{% /project_details %}
+
+This shows every task, where its configuration comes from, its `inputs`, `outputs`, and `dependsOn`. To drill into a specific task:
+
+```shell
+nx show target my-app:build
+```
+
+Add `--json` to either command for machine-readable output.
+
+## Listing projects from the CLI
+
+```shell
+nx show projects
+```
+
+Filter by criteria:
+
+```shell
+# Only projects that have a build target
+nx show projects --with-target build
+
+# Only projects matching a pattern
+nx show projects --projects 'packages/*'
+```
+
+## Debugging cache behavior
+
+If a task isn't caching as expected, inspect its inputs and outputs:
+
+```shell
+nx show project my-app
+```
+
+Check the task's `inputs`. These are the files and values that contribute to the cache hash. If an input changes between runs, the cache is invalidated. Common causes of unexpected cache misses:
+
+- An untracked config file is included in inputs
+- An environment variable changed
+- A dependency was updated
+
+{% aside type="tip" title="Enforce correct inputs and outputs" %}
+Use [sandboxing](/docs/features/ci-features/sandboxing) to detect tasks that read files not listed in their `inputs` or write files not listed in their `outputs`. This catches configuration mistakes that lead to stale caches or missing artifacts.
+{% /aside %}
+
+## Nx Console
+
+[Nx Console](/docs/getting-started/editor-setup) brings all of these capabilities into your editor. In VS Code or WebStorm, you can:
+
+- Browse projects and their targets in a tree view
+- View the project graph inline
+- Run tasks with a visual interface
+- Inspect project details without leaving the editor
+
+{% install_nx_console /%}
+
+## Learn more
+
+- [Explore the graph](/docs/features/explore-graph): full graph exploration guide
+- [Mental model](/docs/concepts/mental-model): how Nx thinks about projects and tasks
+
+{% cards cols=2 %}
+{% card title="Previous: Caching Tasks" description="Speed up tasks by replaying previous results" url="/docs/getting-started/tutorials/caching" /%}
+{% card title="Next: Reducing Configuration Boilerplate" description="Automate task configuration with plugins" url="/docs/getting-started/tutorials/reducing-configuration-boilerplate" /%}
+{% /cards %}
diff --git a/astro-docs/src/content/docs/guides/Adopting Nx/adding-to-monorepo.mdoc b/astro-docs/src/content/docs/guides/Adopting Nx/adding-to-monorepo.mdoc
index 802977e84a2..6ef68184d71 100644
--- a/astro-docs/src/content/docs/guides/Adopting Nx/adding-to-monorepo.mdoc
+++ b/astro-docs/src/content/docs/guides/Adopting Nx/adding-to-monorepo.mdoc
@@ -13,7 +13,7 @@ powering Nx underneath. As a result, Lerna gets all the modern features such as
on [https://lerna.js.org/upgrade](https://lerna.js.org/upgrade).
{% /aside %}
-Nx has first-class support for [monorepos](/docs/getting-started/tutorials/typescript-packages-tutorial). If you have
+Nx has first-class support for [monorepos](/docs/getting-started/tutorials/crafting-your-workspace). If you have
an existing NPM/Yarn or PNPM-based monorepo setup, you can easily add Nx to get
- fast [task scheduling](/docs/features/run-tasks)
diff --git a/astro-docs/src/content/docs/reference/Deprecated/integrated-vs-package-based.mdoc b/astro-docs/src/content/docs/reference/Deprecated/integrated-vs-package-based.mdoc
index 56df7c1322f..9265673e470 100644
--- a/astro-docs/src/content/docs/reference/Deprecated/integrated-vs-package-based.mdoc
+++ b/astro-docs/src/content/docs/reference/Deprecated/integrated-vs-package-based.mdoc
@@ -39,7 +39,7 @@ Someone who appreciates the flexibility of a package-based repository will be mo
- Import existing projects into the repo without modifying their tooling
- Easily create new projects or tools with [code generators](/docs/features/generate-code)
-{% linkcard title="TypeScript Monorepo Tutorial" description="Add Nx to an existing TypeScript repo" href="/docs/getting-started/tutorials/typescript-packages-tutorial" /%}
+{% linkcard title="Learn Nx Tutorial" description="Add Nx to an existing TypeScript repo" href="/docs/getting-started/tutorials/crafting-your-workspace" /%}
## Integrated repos
@@ -54,8 +54,7 @@ Someone who appreciates the structure and consistency of an integrated repositor
- [Automate updating dependencies](/docs/features/automate-updating-dependencies) of the entire toolchain
{% cardgrid %}
-{% linkcard title="Tutorial: React Monorepo" description="Create a React monorepo with Nx" href="/docs/getting-started/tutorials/react-monorepo-tutorial" /%}
-{% linkcard title="Tutorial: Angular Monorepo" description="Create an Angular monorepo with Nx" href="/docs/getting-started/tutorials/angular-monorepo-tutorial" /%}
+{% linkcard title="Learn Nx Tutorial" description="Create a monorepo with Nx" href="/docs/getting-started/tutorials/crafting-your-workspace" /%}
{% /cardgrid %}
## Standalone applications
diff --git a/astro-docs/src/content/docs/technologies/angular/Guides/nx-and-angular.mdoc b/astro-docs/src/content/docs/technologies/angular/Guides/nx-and-angular.mdoc
index 41ab7564444..5caa80781af 100644
--- a/astro-docs/src/content/docs/technologies/angular/Guides/nx-and-angular.mdoc
+++ b/astro-docs/src/content/docs/technologies/angular/Guides/nx-and-angular.mdoc
@@ -42,7 +42,7 @@ Here's a quick side-by-side overview comparing the features between the Angular
| Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ |
| Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ |
| Support for single-project Workspaces | ✅ | ✅ |
-| First-Class [Monorepo Support](/docs/getting-started/tutorials/angular-monorepo-tutorial) | ❌\* | ✅ |
+| First-Class [Monorepo Support](/docs/getting-started/tutorials/crafting-your-workspace) | ❌\* | ✅ |
| [Enforced Module Boundaries](/docs/features/enforce-module-boundaries) | ❌ | ✅ |
| Interactive [Project Graph](/docs/features/explore-graph) | ❌ | ✅ |
| Task Graph | ❌ | ✅ |
@@ -416,4 +416,4 @@ You can also use [`nx import`](/docs/guides/adopting-nx/import-project) to bring
You can learn more about Angular & Nx by following our dedicated tutorials:
-- [Tutorial: Building Angular Apps in an Nx Monorepo](/docs/getting-started/tutorials/angular-monorepo-tutorial)
+- [Tutorial: Learn Nx](/docs/getting-started/tutorials/crafting-your-workspace)
diff --git a/astro-docs/src/content/docs/technologies/angular/introduction.mdoc b/astro-docs/src/content/docs/technologies/angular/introduction.mdoc
index 758c43bbf40..dc5e27c69ce 100644
--- a/astro-docs/src/content/docs/technologies/angular/introduction.mdoc
+++ b/astro-docs/src/content/docs/technologies/angular/introduction.mdoc
@@ -53,7 +53,7 @@ npx create-nx-workspace my-org --template=nrwl/angular-template
```
{% aside type="tip" title="Angular Tutorial" %}
-For a guided walkthrough, follow the [Angular Monorepo Tutorial](/docs/getting-started/tutorials/angular-monorepo-tutorial).
+For a guided walkthrough, follow the [Learn Nx Tutorial](/docs/getting-started/tutorials/crafting-your-workspace).
{% /aside %}
## Local development
@@ -144,7 +144,7 @@ See [Set Up CI](/docs/guides/nx-cloud/setup-ci) for a sample CI setup.
## What's next
{% cardgrid %}
-{% linkcard title="Angular Monorepo Tutorial" description="Build an Angular monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/angular-monorepo-tutorial" /%}
+{% linkcard title="Learn Nx Tutorial" description="Build a monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/crafting-your-workspace" /%}
{% linkcard title="Migrate from Angular CLI" description="Move an existing Angular CLI project into Nx." href="/docs/technologies/angular/migration/angular" /%}
{% linkcard title="Dynamic Module Federation" description="Load Angular remotes at runtime with dynamic federation." href="/docs/technologies/angular/guides/dynamic-module-federation-with-angular" /%}
{% linkcard title="Tailwind CSS with Angular" description="Add Tailwind CSS to Angular apps and libraries." href="/docs/technologies/angular/guides/using-tailwind-css-with-angular-projects" /%}
diff --git a/astro-docs/src/content/docs/technologies/react/introduction.mdoc b/astro-docs/src/content/docs/technologies/react/introduction.mdoc
index e28ca3638f4..242c2dd79ec 100644
--- a/astro-docs/src/content/docs/technologies/react/introduction.mdoc
+++ b/astro-docs/src/content/docs/technologies/react/introduction.mdoc
@@ -65,7 +65,7 @@ npx create-nx-workspace@latest --template=nrwl/react-template
```
{% aside type="tip" title="Tutorial" %}
-For a guided walkthrough, follow the [React Monorepo Tutorial](/docs/getting-started/tutorials/react-monorepo-tutorial).
+For a guided walkthrough, follow the [Learn Nx Tutorial](/docs/getting-started/tutorials/crafting-your-workspace).
{% /aside %}
### Generate a new application
@@ -153,7 +153,7 @@ nx connect
## What's next
{% cardgrid %}
-{% linkcard title="React Monorepo Tutorial" description="Build a React monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/react-monorepo-tutorial" /%}
+{% linkcard title="Learn Nx Tutorial" description="Build a monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/crafting-your-workspace" /%}
{% linkcard title="React Router Guide" description="Set up React Router in framework mode with Nx." href="/docs/technologies/react/guides/react-router" /%}
{% linkcard title="Module Federation with SSR" description="Configure Module Federation with server-side rendering." href="/docs/technologies/react/guides/module-federation-with-ssr" /%}
{% linkcard title="Next.js Plugin" description="Use Nx with Next.js for inferred tasks and generators." href="/docs/technologies/react/next/introduction" /%}
diff --git a/astro-docs/src/content/docs/technologies/react/next/introduction.mdoc b/astro-docs/src/content/docs/technologies/react/next/introduction.mdoc
index b6ce9503b7e..c90efe887d5 100644
--- a/astro-docs/src/content/docs/technologies/react/next/introduction.mdoc
+++ b/astro-docs/src/content/docs/technologies/react/next/introduction.mdoc
@@ -234,7 +234,7 @@ Next.js applications support [static HTML export](https://nextjs.org/docs/app/bu
{% cardgrid %}
{% linkcard title="Deploy Next.js to Vercel" description="Deploy your Next.js application to Vercel with Nx." href="/docs/technologies/react/guides/deploy-nextjs-to-vercel" /%}
{% linkcard title="Next.js Config Setup" description="Configure Next.js settings for your Nx workspace." href="/docs/technologies/react/next/guides/next-config-setup" /%}
-{% linkcard title="React Monorepo Tutorial" description="Build a React monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/react-monorepo-tutorial" /%}
+{% linkcard title="Learn Nx Tutorial" description="Build a monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/crafting-your-workspace" /%}
{% linkcard title="Generators Reference" description="Full API reference for @nx/next generators." href="/docs/technologies/react/next/generators" /%}
{% linkcard title="Executors Reference" description="Full API reference for @nx/next executors." href="/docs/technologies/react/next/executors" /%}
{% linkcard title="Migrations Reference" description="Full reference for @nx/next migrations." href="/docs/technologies/react/next/migrations" /%}
diff --git a/astro-docs/src/content/docs/technologies/react/remix/introduction.mdoc b/astro-docs/src/content/docs/technologies/react/remix/introduction.mdoc
index f9a9050093b..7b06029f7a0 100644
--- a/astro-docs/src/content/docs/technologies/react/remix/introduction.mdoc
+++ b/astro-docs/src/content/docs/technologies/react/remix/introduction.mdoc
@@ -253,7 +253,7 @@ nx connect
{% cardgrid %}
{% linkcard title="React Router Guide" description="React Router is the successor to Remix. Learn how to use it with Nx." href="/docs/technologies/react/guides/react-router" /%}
-{% linkcard title="React Monorepo Tutorial" description="Build a React monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/react-monorepo-tutorial" /%}
+{% linkcard title="Learn Nx Tutorial" description="Build a monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/crafting-your-workspace" /%}
{% linkcard title="Generators Reference" description="Full API reference for @nx/remix generators." href="/docs/technologies/react/remix/generators" /%}
{% linkcard title="Executors Reference" description="Full API reference for @nx/remix executors." href="/docs/technologies/react/remix/executors" /%}
{% linkcard title="Migrations Reference" description="Full reference for @nx/remix migrations." href="/docs/technologies/react/remix/migrations" /%}
diff --git a/astro-docs/src/content/docs/technologies/typescript/introduction.mdoc b/astro-docs/src/content/docs/technologies/typescript/introduction.mdoc
index c0b458f5a39..30f0c46cbef 100644
--- a/astro-docs/src/content/docs/technologies/typescript/introduction.mdoc
+++ b/astro-docs/src/content/docs/technologies/typescript/introduction.mdoc
@@ -91,7 +91,7 @@ pnpm create nx-workspace my-org --template nrwl/typescript-template
This creates a monorepo configured with [TypeScript Project References](https://www.typescriptlang.org/docs/handbook/project-references.html) and your package manager's [workspaces](https://docs.npmjs.com/cli/using-npm/workspaces) feature. [Nx automatically maintains the project references](/docs/features/maintain-typescript-monorepos) as you add and remove projects.
{% aside type="tip" title="Tutorial" %}
-For a guided walkthrough, follow the [TypeScript Packages Tutorial](/docs/getting-started/tutorials/typescript-packages-tutorial).
+For a guided walkthrough, follow the [Learn Nx Tutorial](/docs/getting-started/tutorials/crafting-your-workspace).
{% /aside %}
The `--template nrwl/typescript-template` uses the modern setup with workspaces and project references as of Nx 20.
@@ -338,7 +338,7 @@ For large monorepos with many TypeScript projects, [TSC batch mode](/docs/techno
## What's next
{% cardgrid %}
-{% linkcard title="TypeScript Packages Tutorial" description="Build a TypeScript monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/typescript-packages-tutorial" /%}
+{% linkcard title="Learn Nx Tutorial" description="Build a TypeScript monorepo step-by-step with Nx." href="/docs/getting-started/tutorials/crafting-your-workspace" /%}
{% linkcard title="Switch to Workspaces & Project References" description="Migrate from path aliases to the modern monorepo setup." href="/docs/technologies/typescript/guides/switch-to-workspaces-project-references" /%}
{% linkcard title="Compile to Multiple Formats" description="Build libraries to both ESM and CommonJS with Rollup." href="/docs/technologies/typescript/guides/compile-multiple-formats" /%}
{% linkcard title="Generators Reference" description="Full API reference for @nx/js generators." href="/docs/technologies/typescript/generators" /%}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 68621f8fc84..1c773af2002 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5836,10 +5836,6 @@ packages:
resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==}
engines: {node: '>=6.9.0'}
- '@babel/runtime@7.28.4':
- resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
- engines: {node: '>=6.9.0'}
-
'@babel/runtime@7.28.6':
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
engines: {node: '>=6.9.0'}
@@ -31171,8 +31167,6 @@ snapshots:
'@babel/runtime@7.28.3': {}
- '@babel/runtime@7.28.4': {}
-
'@babel/runtime@7.28.6': {}
'@babel/template@7.27.2':
@@ -54267,7 +54261,7 @@ snapshots:
redux@4.2.1:
dependencies:
- '@babel/runtime': 7.28.4
+ '@babel/runtime': 7.28.6
reflect-metadata@0.2.2: {}