7/25/2018 - 4:59 PM

Custom Nx workspace schematic to build a custom 'state' library.

Custom Nx workspace schematic to build a custom 'state' library.


We want to build a custom schematic for company Aero that will internally do two things:

  • build a new ngrx library using Nx workspace naming conventions
  • generate ngrx state-management files; include the *.facade.* files

Important: This example is valid ONLY for Nx v6.2.x or higher!

Steps to Build/Use Custom Schematics

  1. Use the following command to generate a custom schematic called ngrx-lib.

This custom workspace schematic will:

  • Generate a Nx library
  • Generate NgRx files inside a folder called +state.
  • Generate NgRx Facade files for the new NgRx state management files
ng g workspace-schematic ngrx-lib
  1. Then open the new empty schematic at /tools/schematics/ngrx-lib/index.ts and replace the contents with your own custom logic.

The schematic code for our requirements is here :

import {
} from '@angular-devkit/schematics';
import * as path from 'path';

 * Build a new custom Nx library with ngrx files.
 * Using Nx workspace conventions, these custom libraries are 'state' libraries since 
*  they will manage ngrx state, REST endpoints, etc.
export default function(schema: any): Rule {
  const PREFIX = 'state-';
  if (!'state-') && ( != 'state')) {
    // custom libraries managing state must have name conventions: 'state' or 'state-<name>' = PREFIX +;

  const name =;
  const libPath = ? path.join(, :;
  const moduleName = ? `${}-${}` :;
  const module = path.join('libs',libPath, 'src/lib', `${moduleName}.module.ts`);

  return chain([
    externalSchematic('@nrwl/schematics', 'lib', {
      directory :,
      tags : ? `state, ${}` : 'state, aero'
    externalSchematic('@nrwl/schematics', 'ngrx', {
      directory: '+state',
      facade : true
  1. Now you can use the custom workspace schematic (in your workspace).

In our example, we want a new state library called for airports and we want to group that library in a directory called trip-planner:

npm run workspace-schematic ngrx-lib airports -- --directory=trip-planner
# or 
yarn  workspace-schematic ngrx-lib planes --directory=trip-planner

Note the extra -- when using npm. This is required so these options are considered options for the workspace-schematic instead of npm itself.

This would output to the console something similar to:

create libs/trip-planner/state-planes/karma.conf.js (508 bytes)
create libs/trip-planner/state-planes/tsconfig.lib.json (828 bytes)
create libs/trip-planner/state-planes/tsconfig.spec.json (283 bytes)
create libs/trip-planner/state-planes/tslint.json (252 bytes)

create libs/trip-planner/state-planes/src/index.ts (205 bytes)
create libs/trip-planner/state-planes/src/test.ts (700 bytes)

create libs/trip-planner/state-planes/src/lib/trip-planner-state-planes.module.ts (720 bytes)
create libs/trip-planner/state-planes/src/lib/trip-planner-state-planes.module.spec.ts (445 bytes)

create libs/trip-planner/state-planes/src/lib/+state/planes.actions.ts (727 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.effects.spec.ts (1158 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.effects.ts (833 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.facade.spec.ts (2848 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.facade.ts (606 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.reducer.spec.ts (1130 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.reducer.ts (960 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.selectors.spec.ts (1596 bytes)
create libs/trip-planner/state-planes/src/lib/+state/planes.selectors.ts (962 bytes)

Notice how trip-planner-state-planes.module.ts has export class TripPlannerStatePlanesModule and uses the <grouping-folder>-<library-name>.module.ts convention. This allows developers to easily determine the folder and library associated with that ngModule.