As productive as mother Earth! (Original 📷 by Markus Spiske)
Angular Schematics is a workflow tool for the modern web — official introduction article
There are many articles on how to build your own Angular schematics but in this one we’re going to focus on using available schematics to the fullest! 💪
Most of the time we will be using
@schematics/angularwhich are provided in Angular CLI out of the box.
angular.jsonfile so that we don’t need to specify all the flags all the time
--moduleflag (scoping to lazy-loaded modules)
ng addto add libraries like Angular Material (or others)
BONUS: Useful commands
BONUS+: Amazing code completion capabilities!
FUN FACT: In the beginning all I had in mind was 6 distinct useful tips and see how it ended up. We have 7 main points and 2 bonuses 🤦 But schematics just have so many cool features that there was no other way 😂
Most of the schematics commands in Angular CLI come with the shortcut version. For example, instead of
ng generate service service-name we can simply write
ng g s service-name.
Less letters = lower probability of typos, yaay🎉!
Also, schematics used to be documented in the GitHub Wiki of the Angular CLI repository but this was improved. Official schematics documentation is now available as a part of angular.io together with the rest of the docs which is very convenient! Check them out to see all the available commands and their shortcut versions!
Angular CLI comes with great support for multiple apps and libraries in a single workspace. This feature can be easily missed because by default Angular CLI will generate new project with a default application directly in the project root in the
Standard workspace generated using ng new app-name
CLI will create new
projects folder when we decide to add more libraries later during the development process. This will lead to a inconsistent code structure where original app doesn’t follow paths and conventions compared to the ones added later.
This can be prevented by creating our new workspace with
ng new --createApplication=false flag.
What we get is an empty workspace. Then we can continue with the
ng generate application our-first-app (or
library our-first-library ).
That way, all the code in the workspace will be located in the predictable location inside of
projects folder! Great! 🎉🎉🎉
Minimal workspace generated by the Angular CLI with ng new cli-test — — createApplication=false
As mentioned above, Angular CLI currently supports multiple apps and libraries in the single workspace (by default inside of the
The libraries and apps can be added by running
ng generate library library-name and
ng generate application app-name respectively.
You can go with the multiple independent npm packages or monorepo, that’s up to your subjective preferences. Both have their distinctive advantages and disadvantages.
The Angular CLI will generate libraries which will get their own
package.json file in the
dist folder after they were built by
ng-packager. Such a library can be easily published to npm independently from the rest of the projects in the workspace. This supports multiple npm packages scenario out of the box
On the other hand, tools like
@nrwl/nx help us to implement similar structure in a monorepo fashion. Choose what works best for your use-case!
Using schematics in a workspace with single app is very straight forward. Every call to
ng generate will generate desired entity in the specified path inside of the one and only app. What would happen with multiple apps and libraries in a single workspace?
angular.json file contains the
defaultProject property which specifies which project will be implicitly assumed when executing any Angular CLI command. This is valid also for the things like
ng build or
Example of a top level structure of angular.json file with one app and one lib project
We can also specify
--project <my-project-name> flag as a part of these commands to make it run in a desired app or library… The command will then look like this:
ng g c path/some-component --project some-app
PRO TIP: It might be worth it to change
angular.jsonfile when working mostly on a single app (or lib) to prevent unnecessary typing or create additional npm script in
package.jsonwhich will do that for us. For example,
"ng-my-lib": "ng run --project my-lib"which we can then use like this
npm run ng-my-lib -- test. Note the
--npm pipe to pass in a sub-command.
Angular CLI comes with default set of schematics implemented in the
@schematics/angular npm package which gives us ability to generate apps or components.
The schematics itself are actually framework independent
Many people, organizations and open source libraries already implemented and provided their own schematics in the npm registry for our use.
A good example of this could be NgRx state management library which ships its own schematics in the
@ngrx/schematics npm package. So how can we use this additional 3rd party schematics?
This one is the most straight forward solution. Once we installed additional schematics package in our workspace we can simply call them using
ng g <schematics-package-name>:<schematics-name> [...options]. Or to imagine it from a more practical angle —
ng g @ngrx/schematics:action feature-name/entity-name --spec=true …
Comparison between using ng g versus schematics
Schematics can be executed even without the help of Angular CLI. In that case we can just run
schematics @ngrx/schematics:action feature-name/entity-name.
How to make
schematics command available in our environment will be discussed in the BONUS section 😉
Follow me on Twitter to get notified about the newest Angular blog posts and interesting frontend stuff!🐤
angular.jsonfile so that we don’t need to specify all the flags all the time
Many of the schematics which we use to generate entities like components or services support vast amount of additional configuration flags.
For example, with components we can set flag for
--inlineTemplate so that we have whole implementation inside of the component typescript file.
A single project usually contains many components so we would need to repeat these flags manually and quite often if we wanted to preserve unified code style…
Luckily, Angular CLI has support for defining default values of the schematics options!
Example of how to define workspace and project specific schematics defaults
The default values are defined inside of the
schematics object and they are defined per individual schematic. Every schematic is defined by the package name and the respective schematic.
In the example above we’re providing defaults for the
component schematics from the package
This approach is great because it is flexible enough to allow us to specify defaults for multiple schematics packages like popular 3rd party
@ngrx/schematicspackages or even our own custom built
schematics object can be defined as a top level property and in that case defaults will be applied for the
ng g call WITHOUT
--project flag. Project specific
schematics defaults can be configured too and will be activated only when using
ng g together with the
--project some-project flag.
Some schematics collections (like
ngrx) enable us to call original Angular CLI schematics (like
service) next to all the new schematics they are bringing to the table.
In that case we can set such a collection as a default Angular CLI schematics collection using
ng config cli.defaultCollection <schematics-package> . The
defaultCollection property will be added into
Setting default schematics collection in angular.json file will enable us to call provided schematics without the need to specify their package name in every ng g call
Setting default collection enables us to execute schematics from that collection without the need to specify the schematics package name in the call. That way we can call
ng g action feature/action-name instead of
ng g @ngrx/schematics:action feature/action-name which is great!
--moduleflag (scoping to lazy-loaded modules)
Service generation has changed and the services generated by Angular CLI 6+ use new
providedIn: 'root' syntax by default.
Service generated using ng generate service some/path/feature
Such a service doesn’t have to be specified in
providers:  array of any
@NgModule which is nice convenience. Even better, library services provided in the root will be tree-shaken automatically if they were not explicitly imported by the consumer app!
This is great improvement compared to previous dependency injection style using
providers:  array when all the provided services would always end up in the bundle regardless of whether they were used at all!
Providing service using the old style
_providers: _has still its place when we want to get unique instance of the service per created component or when we want to scope service to lazy loaded module.
Before it was possible to
ng generate service some-feature and specify
--module ../some.module flag but this is no longer supported in Angular CLI 7+.
In case we want to scope our service to some component or module we have to remove the content of the
@Injectable() decorator. Then we can import the service to the desired module and add it manually to the
providers: [ ] array.
Adjusting service dependency injection registration to scope it to the lazy loaded module
ng add”to add libraries like Angular Material (or others)
Until now, we have been mostly talking about the execution of various schematics which were already available in our workspace. The schematics themselves usually created couple of new files and maybe added some import statement here and there to wire stuff up…
But what about libraries that need more extensive setup work?
Schematics cover our back yet again! The helps comes in the form of
ng add command and the corresponding (special)
ng-add schematics implemented in the particular schematics package!
The most common example probably would be Angular Material, a great component library used in many Angular projects. Angular Material setup process is a bit more complicated….
Such a nontrivial setup process is best handled using
The selection capability is called “prompts” and is a new feature of Angular CLI 7+
ng add we would have to install the package manually and then spend couple of minutes reading the docs to figure out how to set everything up!
PRO TIP: It still might be worth it to add
ng-addschematics to your open source library even if it doesn’t do much more than
npm installthe package. That way people can add it using the usual workflow! Check out example how to implement this minimal
ng-addschematics in the @angular-extensions/model library.
Schematics are independent from the Angular CLI and can be executed outside of the workspace. All we have to do is to install
npm i -g @angular-devkit/schematics-cli which will give as
schematics command which we can run in our terminal of choice.
Another possibility would be to us npx. Unfortunately, in our case the package name and the command name are not the same so the execution would be quite cumbersome…
npx -p [@angular](http://twitter.com/angular "Twitter profile for @angular")-devkit/schematics schematics <command> and therefore I recommend to use global npm installation instead.
schematics --list-schematics schematics-package-name:
This command lists all available schematics from the specified package. The package has to be installed and available in the
node_modules/ folder of the folder from where the command was executed. (Please note that the package name ends with
schematics --list-schematics @ngrx/schematics: in the workspace of the project generated by Angular CLI with installed
We might have noticed that the first line of the
angular.json looks a bit funny…
Example of code completion in the angular.json file powered by the Json Schema
The $schema property is responsible for the super awesome code completion capabilities!
Let’s say we would like to add defaults to another schematics of our project. All we have to do is hit code completion key shortcut of our editor of choice and we would get the list of possible values!
Very often together with a helpful description!
Example of a property description provided by the code completion capabilities of the IDE
I hope you enjoyed this article and will get more productive by using Angular Schematics in your projects!
Please support this guide with your 👏👏👏 using the 👏 button on the left side and help to spread it to a wider audience 🙏. Also, don’t hesitate to ping me if you have any questions using the article responses or Twitter DMs @tomastrajan
Starting an Angular project? Check out Angular NgRx Material Starter!
Angular NgRx Material Starter with built in best practices, theming and much more!
And never forget, future is bright
Obviously the bright future (📸 by James Donaldson)
If you made it this far, feel free to check out some of my other articles about Angular and frontend software development in general…
The Best Way To Unsubscribe RxJS Observable In The Angular Applications!_There are many different ways how to handle RxJS subscriptions in Angular applications and we’re going to explore their…_blog.angularindepth.com
The Ultimate Answer To The Very Common Angular Question: subscribe() vs | async Pipe_Most of the popular Angular state management libraries like NgRx expose application state in a form of a stream of…_blog.angularindepth.com
Total Guide To Angular 6+ Dependency Injection — providedIn vs providers:[ ] 💉_Let’s learn when and how to use new better Angular 6+ dependency injection mechanism with new providedIn syntax to make…_medium.com