Blog
Juri Strumpflohner
September 25, 2024

Introducing Nx Powerpack

Today we're introducing our latest product, Nx Powerpack, a suite of paid extensions for Nx, specifically designed around common enterprise needs. Now, before anyone draws the wrong conclusions:

  • No, we’re not going to restrict Nx’s license, lock you in, and then harvest. Nx remains MIT licensed and fully open source.
  • No, we’re not placing existing features behind a paywall. Nx Powerpack introduces new features on top of Nx (more about that below).
  • Yes, we still strongly believe in OSS and our community, and we will keep improving Nx more than ever; if anything, Powerpack will help us fund our OSS work on Nx core and ensure its long-term sustainability.

What about my open-source repo ?

Open source projects can continue to use Nx Cloud for free the same way they always have, and they can continue to use Nx with all its features. If you are an open-source maintainer and you want to use Powerpack, you will get a free license. Just reach out to us at powerpack-support@nrwl.io.

So this leaves us with: Nx products and their licenses

But why are we releasing Nx Powerpack under a commercial license? Read all about our strategy, the reasoning behind Powerpack and OSS funding in the blog post from our CEO, Jeff Cross: Evolving Nx.

But now to the fun, technical part! Nx Powerpack is a bundle that - in this very first release - comes with three major features:

Let’s dive in!

Get an Nx Powerpack License

All Powerpack features require a dedicated commercial license. You can get one here: Nx Powerpack.

Once you have your license, run the following command

npx nx activate-powerpack <your-license>

Codeowners for Monorepos

Setting up Codeowners is highly recommended when designing a monorepo. If you’re not familiar, Codeowners is a common feature of VCS providers (such as GitHub, GitLab, Bitbucket, etc.), allowing you to enforce specific code reviewers to approve PRs. This functionality is especially important in a monorepo, where you manage multiple projects with multiple teams. You want to ensure the right people are reviewing the code being submitted.

Here’s a simple example of a GitHub CODEOWNERS definition:

.github/CODEOWNERS
1/docs/ @doc-owner 2/apps/orders @orders-team 3/apps/products @products-team 4/libs/orders/** @orders-team 5/libs/products/** @products-team 6/libs/shared/** @infra-team 7

One of the downsides of how codeowners works on today's VCS providers is that they are folder-based. That requires you to map your project paths to your codeowner files and keep maintaining that as you change your monorepo structure. And this is exactly what we're going to automate.

In a monorepo you reason based on projects. That's what you pass to your Nx run commands, what you see on the project graph and also where owners should be defined. To get started install the Codeowners Powerpack plugin:

npx nx add @nx/powerpack-owners

This will allow you to define an owners section in your nx.json where you can define owners at the project level or even leverage project tags. Here's a small example:

nx.json
1{ 2 ... 3 "owners": { 4 "format": "github", 5 "patterns": [ 6 { 7 "description": "CI configuration", 8 "owners": ["@devops"], 9 "files": [".github/workflows/**"] 10 }, 11 { 12 "description": "Order team", 13 "owners": ["@team-orders"], 14 "projects": ["tag:scope:orders"] 15 }, 16 { 17 "description": "Product team", 18 "owners": ["@team-products"], 19 "projects": ["tag:scope:products"] 20 }, 21 { 22 "description": "Design team", 23 "owners": ["@team-design"], 24 "projects": ["tag:scope:design-system"] 25 } 26 ] 27 }, 28 ... 29} 30

A dedicated nx sync command automatically synchronizes these definitions to a CODEOWNERS file that matches your VCS provider:

.github/CODEOWNERS
1 2# CI configuration 3.github/workflows/** @devops 4 5# Design team 6/libs/shared/ui/angular/form-controls/ @team-design 7 8# Design team 9/libs/shared/ui/react/form-controls/ @team-design 10 11# Product team 12/libs/products/feat-product-detail/ @team-products 13 14# Order team 15/libs/orders/feat-current-orders/ @team-orders 16 17... 18

Read all about how to configure Codeowners for your project in our docs.

Self-hosted Cache Storage

A continuous effort on our Nx core is to improve speed. Last year, we began rewriting performance-critical parts of Nx into Rust, and more core components are being rewritten. As part of this effort, we also changed how we manage local cache, moving from a file-based to a database-based approach. In addition to small performance gains from reduced I/O, this opens up many opportunities for improving local cache handling, such as keeping only relevant cache based on usage, more easily controlling maximum cache size, and optimizing task orchestration by running failed tasks earlier.

As part of this new approach we're also going to deprecate custom task runners in Nx 20. I bring this up because it might affect users that relied on 3rd party tools that hooked into the task runners API.

To fill in on the custom task runner API we're providing a new Powerpack plugin that allows you to use S3 or a network drive as your storing mechanism for your Nx cache.

Here's an example of how to get started with Amazon S3 based remote caching. First add the Powerpack plugin:

npx nx add @nx/powerpack-s3-cache

This will update your nx.json to add the new cache section.

nx.json
1{ 2 ... 3 "s3": { 4 "bucket": "your-s3-bucket-name", 5 "region": "us-east-1" 6 } 7} 8

To then leverage the S3 powered remote cache on CI, follow the official AWS documentation. Here's a short example snippet using OIDC to authenticate with AWS on GitHub Actions:

.github/workflows/ci.yml
1name: CI 2... 3permissions: 4 id-token: write 5 ... 6 7env: 8 NX_DB_CACHE: true 9 10jobs: 11 main: 12 runs-on: ubuntu-latest 13 steps: 14 ... 15 16 - name: 'Configure AWS Credentials' 17 uses: aws-actions/configure-aws-credentials@v4.0.2 18 with: 19 role-to-assume: arn:aws:iam::123456789123:role/GhAIBucketUserRole 20 aws-region: us-east-1 21 22 ... 23 24 - run: pnpm exec nx affected -t lint test build 25

Similarly you can set up network file based caching using the nx add @nx/powerpack-shared-fs-cache package and by setting the cacheDirectory path in your nx.json.

Read all about how to set up S3 or network drive based caching for your Nx workspace in our docs.

Workspace Conformance (Beta)

We're releasing the @nx/powerpack-conformance plugin in an early preview. This new package focuses specifically on the maintainability of your monorepo. It allows you to encode your organization's standards so they can be enforced automatically. In this first version, the workspace conformance package ships with:

To get started, install the following package:

npx nx add @nx/powerpack-conformance

This allows you to define conformance rules in your nx.json. Here is an example:

nx.json
1{ 2 ... 3 "conformance": { 4 "rules": [ 5 { 6 "rule": "@nx/powerpack-conformance/enforce-module-boundaries", 7 "projects": ["!remix-app-e2e"], 8 "options": {} 9 }, 10 { 11 "rule": "@nx/powerpack-conformance/ensure-owners", 12 "projects": ["!remix-app-e2e"] 13 }, 14 { 15 "rule": "./tools/local-conformance-rule.ts" 16 } 17 ] 18 } 19} 20

You can also define rules locally, as shown in the example above, which are simple TypeScript files:

1import { createConformanceRule } from '@nx/powerpack-conformance'; 2 3const rule = createConformanceRule({ 4 name: 'local-conformance-rule-example', 5 category: 'security', 6 reporter: 'project-reporter', 7 implementation: async (context) => { 8 return { 9 severity: 'low', 10 details: { 11 violations: [], 12 }, 13 }; 14 }, 15}); 16 17export default rule; 18

You can then run nx conformance to execute the conformance checks:

Screenshot of the conformance check output

In this first preview release, you'll only be able to run workspace conformance rules on a single workspace. In future iterations, you will be able to connect it to your existing Nx Cloud organization, allowing you to upload conformance rules and run them across connected workspaces.

Read all the details on how to get started with workspace conformance rules in our docs.

Learn More