Starting by Creating a New Workspace

After we have installed Nx, let’s create a new workspace.

create-nx-workspace myorg

Nx is just an extension for the Angular CLI, so create-nx-workspace simple runs ng new myorg --collection=@nrwl/schematics and handles common pitfalls of using global npm packages. This command will create an empty workspace for us.

apps/

libs/

tools/

angular.json

nx.json

package.json

tsconfig.json

tslint.json

The apps and libs folders contain all the projects in the workspace.

An app is something that we can run, either in the browser or on the server. Often building an app creates an optimized bundle. Apps cannot be reused in other apps.

is something that we can run, either in the browser or on the server. Often building an app creates an optimized bundle. Apps cannot be reused in other apps. A lib is a reusable piece of code with well-defined public API. We cannot run a lib. We can only use it in another lib or in an app.

Creating Apps

Say we are tasked with building an app for managing tickets. We can start by generating the app, like this: ng g app tuskdesk

apps/

tuskdesk/

src/

app/

assets/

environments/

favicon.ico

index.html

main.ts

polyfills.ts

styles.css

test.ts

browserslist

karma.conf.js

tsconfig.app.json

tsconfig.spec.json

tslint.json

tuskdesk-e2e/

libs/

tools/

angular.json

nx.json

package.json

tsconfig.json

tslint.json

If you have used the Angular CLI, this should all look familiar: same configuration files, same folders. And this is because when generating an app, Nx runs a CLI command under the hood.

Now, imagine we also need to create the admin UI for managing tickets. We decided that it is a good idea to build it as a separate app to keep our consumer-facing application as lightweight and clean as possible.

ng g app tuskdesk-admin

apps/

tuskdesk/

tuskdesk-e2e/

tuskdesk-admin/

tuskdesk-admin-e2e/

libs/

tools/

angular.json

nx.json

package.json

tsconfig.json

tslint.json

To make things a bit more interesting, let’s say the two apps have a similar shell component.

and

The example is contrived, but illustrates an important point. It’s not uncommon to have basically the same component (or any piece of code) that is used in multiple contexts and apps.

If we had developed the two apps in two separate repositories, extracting the two shell components into a reusable one would have been difficult. We would have had to create a new project, set up testing, CI, deploy it to a private npm registry, etc.. As a result, we would have probably decided not to do it. Too hard to justify.

When using Nx, it’s a matter of minutes.

Creating Libs

In Nx, we share code by using libs. So let’s create one called ui-shell .

ng g lib ui-shell apps/

tuskdesk/

tuskdesk-e2e/

tuskdesk-admin/

tuskdesk-admin-e2e/

libs/

ui-shell/

src/

lib/

ui-shell.module.ts

ui-shell.module.spec.ts

index.ts

test.ts

karma.conf.js

tsconfig.lib.json

tsconfig.spec.json

tslint.json

tools/

angular.json

nx.json

package.json

tsconfig.json

tslint.json

Let’s generalize our component, and move it into ui-shell .

apps/

tuskdesk/

tuskdesk-e2e/

tuskdesk-admin/

tuskdesk-admin-e2e/

libs/

ui-shell/

src/

lib/

shell.component.ts

ui-shell.module.ts

ui-shell.module.spec.ts

index.ts

test.ts

karma.conf.js

tsconfig.lib.json

tsconfig.spec.json

tslint.json

tools/

angular.json

nx.json

package.json

tsconfig.json

tslint.json

Finally, we can update both the applications by importing the ui-shell lib and using the component.

Extracting this component took just a few minutes, and we can apply the whole refactoring in a single commit. Everything in the repository will always be consistent: before the refactoring and after the refactoring.