Architecture

Overview

NanoForge Schematics is built on top of the Angular DevKit Schematics framework. It provides code generation templates that scaffold NanoForge projects, including project structure, configuration, client and server base code, Docker support, and dynamically generated main entry points. The package is published to npm as @nanoforge-dev/schematics and ships both ESM and CommonJS bundles.

Technology Stack

ComponentTechnology
LanguageTypeScript (strict mode)
Schematic frameworkAngular DevKit Schematics 21.x
Build tooltsdown
Module formatsESM + CJS
TargetESNext
Package managerpnpm 10.x
Node version25
LinterESLint 9.x
FormatterPrettier 3.x
CI/CDGitHub Actions

Project Structure

src/
+-- index.ts                        # Public API exports
+-- defaults.ts                     # Default option values
+-- collection.json                 # Schematics collection manifest
+-- libs/                           # Schematic implementations
+   +-- application/                # Application scaffolding
+   +-- configuration/              # Config file generation
+   +-- part-base/                  # Client/server base structure
+   +-- part-main/                  # Main file code generation
+   +-- docker/                     # Dockerfile generation
+   +-- component/                  # Component generation
+   +-- system/                     # System generation
+-- utils/                          # Shared utilities
+    +-- formatting.ts               # String formatting helpers
+    +-- name.ts                     # Package name resolution
+    +-- object.ts                   # Deep merge utilities
+    +-- type.ts                     # Shared type definitions
+    +-- config/                     # Configuration helpers
+    +-- main/                       # Main file generation
+```

## Factory Pattern

Each schematic follows a three-phase factory pattern:

1. **Transform** - Convert raw schema input into validated internal options with defaults applied.
2. **Generate** - Load template files from `files/`, interpolate options into the templates, and produce a virtual file tree.
3. **Merge** - Combine the generated file tree into the target project directory using Angular DevKit merge strategies.

Each factory module exports a `main` function that receives the schema and returns an Angular DevKit `Rule`.

## Collection Manifest

The `collection.json` file registers all available schematics. Each entry specifies the factory function, a
description, and the JSON Schema used for input validation.

```json
{
  "schematics": {
    "application": {
      "factory": "./libs/application/application.factory#main",
      "description": "Create a NanoForge Base application.",
      "schema": "./libs/application/schema.json"
    },
    "configuration": {
      "factory": "./libs/configuration/configuration.factory#main",
      "description": "Create a NanoForge Configuration.",
      "schema": "./libs/configuration/schema.json"
    },
    "part-base": {
      "factory": "./libs/part-base/part-base.factory#main",
      "description": "Create a NanoForge Base for client or server.",
      "schema": "./libs/part-base/schema.json"
    },
    "part-main": {
      "factory": "./libs/part-main/part-main.factory#main",
      "description": "Create a Main file for client or server.",
      "schema": "./libs/part-main/schema.json"
    },
    "docker": {
      "factory": "./libs/docker/docker.factory#main",
      "description": "Create a Dockerfile for the application.",
      "schema": "./libs/docker/schema.json"
    },
    "component": {
      "factory": "./libs/component/component.factory#main",
      "description": "Create a NanoForge component.",
      "schema": "./libs/component/schema.json"
    },
    "system": {
      "factory": "./libs/system/system.factory#main",
      "description": "Create a NanoForge system.",
      "schema": "./libs/system/schema.json"
    }
  }
}

Build Pipeline

The project uses tsdown for bundling. The build produces:
  • A main bundle from src/index.ts in both ESM and CJS formats
  • Per-schematic ESM bundles from each *.factory.ts
  • Type declarations (.d.ts and .d.cts)
  • Source maps
The postbuild step copies non-TypeScript assets into dist/ using cpx2.
# Full build
pnpm run build

# Internally this runs:
# 1. tsc --noEmit
# 2. tsdown
# 3. copy:collection
# 4. copy:lib