@angular-devkit/schematics vs @angular/cli vs @nrwl/devkit vs yeoman-generator vs plop vs create-react-app
Web Development Tooling and Project Scaffolding Comparison
1 Year
@angular-devkit/schematics@angular/cli@nrwl/devkityeoman-generatorplopcreate-react-appSimilar Packages:
What's Web Development Tooling and Project Scaffolding?

These npm packages are essential tools for web development, providing various functionalities for project scaffolding, code generation, and development workflows. They help streamline the development process, enhance productivity, and maintain consistency across projects. Each package serves a unique purpose, catering to different frameworks and development needs, making them invaluable for developers looking to optimize their workflows and project setups.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
@angular-devkit/schematics9,355,54926,852258 kB2996 days agoMIT
@angular/cli3,686,18326,852694 kB2996 days agoMIT
@nrwl/devkit3,490,35624,7973.41 kB6715 months agoMIT
yeoman-generator1,013,1741,231138 kB53 months agoBSD-2-Clause
plop796,2357,30286.4 kB75a year agoMIT
create-react-app215,199103,11639.3 kB2,29518 days agoMIT
Feature Comparison: @angular-devkit/schematics vs @angular/cli vs @nrwl/devkit vs yeoman-generator vs plop vs create-react-app

Code Generation

  • @angular-devkit/schematics:

    @angular-devkit/schematics provides a powerful API for creating custom schematics that can generate, modify, or delete files and configurations in Angular projects. It allows developers to define complex workflows and automate project setups, ensuring consistency across applications.

  • @angular/cli:

    @angular/cli includes built-in commands for generating components, services, modules, and other Angular artifacts, significantly speeding up development. It follows Angular's best practices and ensures that generated code adheres to the framework's conventions.

  • @nrwl/devkit:

    @nrwl/devkit offers utilities for generating libraries and applications within a monorepo, allowing for efficient code sharing and management. It simplifies the process of creating and maintaining multiple related projects, enhancing collaboration among teams.

  • yeoman-generator:

    yeoman-generator provides a framework for creating reusable generators that can scaffold out entire projects or specific components. It supports various templating engines and can be tailored to fit any project requirement.

  • plop:

    plop allows developers to create custom file generators using templates, making it easy to automate repetitive tasks. It is highly customizable and can be integrated into any project, providing flexibility in code generation.

  • create-react-app:

    create-react-app provides a zero-configuration setup for new React applications, automatically generating the necessary files and folder structure. It simplifies the initial setup process, allowing developers to focus on writing code rather than configuring build tools.

Customization and Extensibility

  • @angular-devkit/schematics:

    @angular-devkit/schematics is highly customizable, allowing developers to create their own schematics tailored to specific project needs. This extensibility enables teams to enforce coding standards and project structures effectively.

  • @angular/cli:

    @angular/cli offers limited customization options, primarily focused on Angular projects. However, it can be extended with custom builders and schematics to fit specific workflows or requirements.

  • @nrwl/devkit:

    @nrwl/devkit is designed for extensibility in monorepo environments, allowing developers to create custom plugins and tools that enhance the development experience across multiple projects.

  • yeoman-generator:

    yeoman-generator is designed for extensibility, allowing developers to create complex generators that can scaffold out various project types. It supports multiple templating engines, making it adaptable to different development needs.

  • plop:

    plop is highly customizable, enabling developers to define their own templates and prompts for generating files. This flexibility makes it suitable for various project types and workflows.

  • create-react-app:

    create-react-app is less customizable out of the box, but it allows for ejecting the configuration if deeper customization is needed. This can be beneficial for advanced users who require specific build configurations.

Community and Ecosystem

  • @angular-devkit/schematics:

    @angular-devkit/schematics benefits from a strong community of Angular developers, providing numerous pre-built schematics and resources for users to leverage in their projects.

  • @angular/cli:

    @angular/cli has a large user base and extensive documentation, making it easy for developers to find help and resources. The Angular community actively contributes to its development and improvement.

  • @nrwl/devkit:

    @nrwl/devkit is supported by the Nx community, which focuses on monorepo development. It provides a wealth of resources, plugins, and best practices for managing large-scale applications.

  • yeoman-generator:

    yeoman-generator has a mature community with many existing generators available for various frameworks and libraries. This extensive ecosystem allows developers to leverage existing work and contribute their own generators.

  • plop:

    plop has a growing community and offers various templates and examples shared by users. While not as large as some other tools, it provides enough resources for developers to get started quickly.

  • create-react-app:

    create-react-app is widely adopted in the React community, with extensive documentation and a plethora of tutorials available. Its popularity ensures that developers can easily find support and resources.

Learning Curve

  • @angular-devkit/schematics:

    @angular-devkit/schematics has a moderate learning curve, especially for those unfamiliar with Angular's architecture. Understanding how to create and use schematics effectively may take some time for new users.

  • @angular/cli:

    @angular/cli is relatively easy to learn, especially for developers already familiar with Angular. Its command structure is intuitive, making it accessible for beginners.

  • @nrwl/devkit:

    @nrwl/devkit may have a steeper learning curve for those new to monorepo concepts. However, once understood, it significantly simplifies managing multiple projects.

  • yeoman-generator:

    yeoman-generator has a moderate learning curve, particularly for those unfamiliar with generator concepts. However, once learned, it offers powerful capabilities for scaffolding projects.

  • plop:

    plop has a low learning curve, as it focuses on simple file generation and templating. Developers can quickly grasp its concepts and start using it effectively in their projects.

  • create-react-app:

    create-react-app is designed for ease of use, making it an excellent choice for beginners. Its straightforward setup allows developers to start building React applications quickly without extensive configuration.

Integration

  • @angular-devkit/schematics:

    @angular-devkit/schematics integrates seamlessly with Angular CLI, allowing developers to extend the CLI's capabilities with custom schematics for their projects.

  • @angular/cli:

    @angular/cli is tightly integrated with Angular applications, providing a comprehensive toolset for development, testing, and deployment.

  • @nrwl/devkit:

    @nrwl/devkit is designed for integration with Nx, enhancing the capabilities of Angular and React applications in monorepo setups, making it easier to manage dependencies and shared code.

  • yeoman-generator:

    yeoman-generator can be used with any project type, providing a flexible solution for scaffolding applications and components across various frameworks.

  • plop:

    plop can be integrated into any project, regardless of the framework, allowing developers to automate file generation within their existing workflows.

  • create-react-app:

    create-react-app integrates well with React's ecosystem, providing a solid foundation for building applications with popular libraries and tools.

How to Choose: @angular-devkit/schematics vs @angular/cli vs @nrwl/devkit vs yeoman-generator vs plop vs create-react-app
  • @angular-devkit/schematics:

    Choose @angular-devkit/schematics if you need to create custom Angular schematics for generating and modifying Angular applications and libraries. It is ideal for developers looking to automate repetitive tasks and enforce project standards.

  • @angular/cli:

    Choose @angular/cli for a comprehensive command-line interface to create, build, and manage Angular applications. It is suitable for developers who want a robust set of commands and built-in tools for Angular development.

  • @nrwl/devkit:

    Choose @nrwl/devkit if you are working in a monorepo setup, especially with Angular or React applications. It provides powerful tools for managing multiple projects and libraries within a single repository, enhancing collaboration and code sharing.

  • yeoman-generator:

    Choose yeoman-generator if you are looking for a robust scaffolding tool that can be used with any project type. It is suitable for developers who want to create custom generators for various frameworks and libraries.

  • plop:

    Choose plop if you need a simple and flexible tool for generating files and boilerplate code through templates. It is ideal for developers who want to automate repetitive coding tasks without being tied to a specific framework.

  • create-react-app:

    Choose create-react-app for quickly setting up new React applications with sensible defaults. It is perfect for developers who want to get started with React without dealing with complex configurations or build setups.

README for @angular-devkit/schematics

Schematics

A scaffolding library for the modern web.

Description

Schematics are generators that transform an existing filesystem. They can create files, refactor existing files, or move files around.

What distinguishes Schematics from other generators, such as Yeoman or Yarn Create, is that schematics are purely descriptive; no changes are applied to the actual filesystem until everything is ready to be committed. There is no side effect, by design, in Schematics.

Glossary

| Term | Description | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Schematics | A generator that executes descriptive code without side effects on an existing file system. | | Collection | A list of schematics metadata. Schematics can be referred by name inside a collection. | | Tool | The code using the Schematics library. | | Tree | A staging area for changes, containing the original file system, and a list of changes to apply to it. | | Rule | A function that applies actions to a Tree. It returns a new Tree that will contain all transformations to be applied. | | Source | A function that creates an entirely new Tree from an empty filesystem. For example, a file source could read files from disk and create a Create Action for each of those. | | Action | An atomic operation to be validated and committed to a filesystem or a Tree. Actions are created by schematics. | | Sink | The final destination of all Actions. | | Task | A Task is a way to execute an external command or script in a schematic. A Task can be used to perform actions such as installing dependencies, running tests, or building a project. A Task is created by using the SchematicContext object and can be scheduled to run before or after the schematic Tree is applied. |

Tooling

Schematics is a library, and does not work by itself. A reference CLI is available on this repository, and is published on NPM at @angular-devkit/schematics-cli. This document explains the library usage and the tooling API, but does not go into the tool implementation itself.

The tooling is responsible for the following tasks:

  1. Create the Schematic Engine, and pass in a Collection and Schematic loader.
  2. Understand and respect the Schematics metadata and dependencies between collections. Schematics can refer to dependencies, and it's the responsibility of the tool to honor those dependencies. The reference CLI uses NPM packages for its collections.
  3. Create the Options object. Options can be anything, but the schematics can specify a JSON Schema that should be respected. The reference CLI, for example, parses the arguments as a JSON object and validates it with the Schema specified by the collection.
  4. Schematics provides some JSON Schema formats for validation that tooling should add. These validate paths, html selectors and app names. Please check the reference CLI for how these can be added.
  5. Call the schematics with the original Tree. The tree should represent the initial state of the filesystem. The reference CLI uses the current directory for this.
  6. Create a Sink and commit the result of the schematics to the Sink. Many sinks are provided by the library; FileSystemSink and DryRunSink are examples.
  7. Output any logs propagated by the library, including debugging information.

The tooling API is composed of the following pieces:

Engine

The SchematicEngine is responsible for loading and constructing Collections and Schematics. When creating an engine, the tooling provides an EngineHost interface that understands how to create a CollectionDescription from a name, and how to create a SchematicDescription.

Schematics (Generators)

Schematics are generators and part of a Collection.

Collection

A Collection is defined by a collection.json file (in the reference CLI). This JSON defines the following properties:

| Prop Name | Type | Description | | ----------- | -------- | --------------------------- | | name | string | The name of the collection. | | version | string | Unused field. |

Schematic

Operators, Sources and Rules

A Source is a generator of a Tree; it creates an entirely new root tree from nothing. A Rule is a transformation from one Tree to another. A Schematic (at the root) is a Rule that is normally applied on the filesystem.

Operators

FileOperators apply changes to a single FileEntry and return a new FileEntry. The result follows these rules:

  1. If the FileEntry returned is null, a DeleteAction will be added to the action list.
  2. If the path changed, a RenameAction will be added to the action list.
  3. If the content changed, an OverwriteAction will be added to the action list.

It is impossible to create files using a FileOperator.

Provided Operators

The Schematics library provides multiple Operator factories by default that cover basic use cases:

| FileOperator | Description | | -------------------------------- | -------------------------------------------------------------------- | | contentTemplate<T>(options: T) | Apply a content template (see the Templating section) | | pathTemplate<T>(options: T) | Apply a path template (see the Templating section) |

Provided Sources

The Schematics library additionally provides multiple Source factories by default:

| Source | Description | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | empty() | Creates a source that returns an empty Tree. | | source(tree: Tree) | Creates a Source that returns the Tree passed in as argument. | | url(url: string) | Loads a list of files from the given URL and returns a Tree with the files as CreateAction applied to an empty Tree. | | apply(source: Source, rules: Rule[]) | Apply a list of Rules to a source, and return the resulting Source. |

Provided Rules

The schematics library also provides Rule factories by default:

| Rule | Description | | ------------------------------------------- | -------------------------------------------------------------------------------------- | | noop() | Returns the input Tree as is. | | chain(rules: Rule[]) | Returns a Rule that's the concatenation of other Rules. | | forEach(op: FileOperator) | Returns a Rule that applies an operator to every file of the input Tree. | | move(root: string) | Moves all the files from the input to a subdirectory. | | merge(other: Tree) | Merge the input Tree with the other Tree. | | contentTemplate<T>(options: T) | Apply a content template (see the Template section) to the entire Tree. | | pathTemplate<T>(options: T) | Apply a path template (see the Template section) to the entire Tree. | | template<T>(options: T) | Apply both path and content templates (see the Template section) to the entire Tree. | | filter(predicate: FilePredicate<boolean>) | Returns the input Tree with files that do not pass the FilePredicate. |

Templating

As referenced above, some functions are based upon a file templating system, which consists of path and content templating.

The system operates on placeholders defined inside files or their paths as loaded in the Tree and fills these in as defined in the following, using values passed into the Rule which applies the templating (i.e. template<T>(options: T)).

Path Templating

| Placeholder | Description | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | __variable__ | Replaced with the value of variable. | | __variable@function__ | Replaced with the result of the call function(variable). Can be chained to the left (__variable@function1@function2__ etc). |

Content Templating

| Placeholder | Description | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | <%= expression %> | Replaced with the result of the call of the given expression. This only supports direct expressions, no structural (for/if/...) JavaScript. | | <%- expression %> | Same as above, but the value of the result will be escaped for HTML when inserted (i.e. replacing '<' with '&lt;') | | <% inline code %> | Inserts the given code into the template structure, allowing to insert structural JavaScript. | | <%# text %> | A comment, which gets entirely dropped. |

Examples

Simple

An example of a simple Schematics which creates a "hello world" file, using an option to determine its path:

import { Tree } from '@angular-devkit/schematics';

export default function MySchematic(options: any) {
  return (tree: Tree) => {
    tree.create(options.path + '/hi', 'Hello world!');
    return tree;
  };
}

A few things from this example:

  1. The function receives the list of options from the tooling.
  2. It returns a Rule, which is a transformation from a Tree to another Tree.

Templating

A simplified example of a Schematics which creates a file containing a new Class, using an option to determine its name:

// files/__name@dasherize__.ts

export class <%= classify(name) %> {
}
// index.ts

import { strings } from '@angular-devkit/core';
import {
  Rule,
  SchematicContext,
  SchematicsException,
  Tree,
  apply,
  branchAndMerge,
  mergeWith,
  template,
  url,
} from '@angular-devkit/schematics';
import { Schema as ClassOptions } from './schema';

export default function (options: ClassOptions): Rule {
  return (tree: Tree, context: SchematicContext) => {
    if (!options.name) {
      throw new SchematicsException('Option (name) is required.');
    }

    const templateSource = apply(url('./files'), [
      template({
        ...strings,
        ...options,
      }),
    ]);

    return branchAndMerge(mergeWith(templateSource));
  };
}

Additional things from this example:

  1. strings provides the used dasherize and classify functions, among others.
  2. The files are on-disk in the same root directory as the index.ts and loaded into a Tree.
  3. Then the template Rule fills in the specified templating placeholders. For this, it only knows about the variables and functions passed to it via the options-object.
  4. Finally, the resulting Tree, containing the new file, is merged with the existing files of the project which the Schematic is run on.