m2s2-cli
The official CLI for scaffolding and working with M²S² design system projects. Create new React or Angular applications pre-wired with M²S² components, generate components, and keep your installation up to date — all from the terminal.
Table of Contents
Installation
Shell installer (macOS / Linux)
|
PowerShell (Windows)
irm https://github.com/M2S2-Engineering-Group/m2s2-cli/releases/latest/download/m2s2-cli-installer.ps1 | iex
npm / npx
# Install globally
# Or run without installing
Cargo
Verify installation
Commands
m2s2 new
Scaffold a new project pre-configured with the M²S² design system.
Arguments
| Argument | Description |
|---|---|
<name> |
Project directory name |
Options
| Flag | Description |
|---|---|
--framework <react|angular> |
Framework to scaffold. Prompted interactively if omitted. |
--skip-install |
Skip running npm install after writing project files. |
Examples
# Interactive framework selection
# Explicit framework
# Skip npm install (useful in CI or offline environments)
What gets generated
React
my-app/
├── src/
│ ├── main.tsx # BrowserRouter + M2S2Provider
│ ├── App.tsx # Navbar + Footer wired with M²S² configs
│ └── App.scss
├── index.html
├── package.json # @m2s2/react-lib, @m2s2/tokens, Vite, TypeScript
├── vite.config.ts
├── tsconfig.json
└── .gitignore
Angular
my-app/
├── src/
│ ├── main.ts
│ ├── styles.scss
│ ├── index.html
│ └── app/
│ ├── app.component.ts # Standalone, imports NavbarComponent + FooterComponent
│ ├── app.component.html
│ ├── app.component.scss
│ ├── app.routes.ts
│ └── app.config.ts
├── package.json # @m2s2/ng-lib, @m2s2/tokens, Angular 21
├── angular.json
├── tsconfig.json
├── tsconfig.app.json
└── .gitignore
m2s2 generate component
Scaffold a new component inside an existing M²S² project.
Run this command from your project root. The framework is detected automatically by reading package.json — no flag needed if your project was created with m2s2 new.
Arguments
| Argument | Description |
|---|---|
<name> |
Component name. Accepts any casing — MyCard, my-card, and myCard all produce the same output. |
Options
| Flag | Description |
|---|---|
--framework <react|angular> |
Override framework detection. |
--path <dir> |
Override the output directory. A subdirectory named after the component is always created inside <dir>. |
Examples
# Auto-detect framework from package.json
# Kebab-case input — same result
# Override output directory
# Override framework
What gets generated
React — written to src/components/<Name>/
src/components/HeroSection/
├── HeroSection.tsx # Typed props interface, BEM className application
├── HeroSection.scss # Scoped class stub (.hero-section)
└── index.ts # Barrel re-export
Angular — written to src/app/components/<name>/
src/app/components/hero-section/
├── hero-section.component.ts # Standalone component, app-hero-section selector
├── hero-section.component.html # BEM wrapper div
└── hero-section.component.scss # Scoped class stub (.hero-section)
m2s2 upgrade
Check for and install a newer version of the CLI.
Options
| Flag | Description |
|---|---|
--check |
Print available version without installing. |
Examples
# Check if an update is available
# Download and install the latest version
The upgrade command hits the GitHub Releases API, compares the latest release tag against the running binary version, and — if a newer version exists — runs the official installer script for your platform. Restart your terminal after upgrading.
Building from Source
Prerequisites: Rust 1.85+ (edition 2024), Node.js 18+ for running scaffolded projects.
# Debug build
# Run directly
# Optimised release build (matches the distributed binary)
The binary is written to target/debug/m2s2 (debug) or target/dist/m2s2 (dist profile).
Templates
All scaffold and generate templates live under templates/ and are embedded into the binary at compile time via rust-embed. Changes to template files require a rebuild to take effect.
templates/
├── react/ # m2s2 new --framework react
├── angular/ # m2s2 new --framework angular
└── generate/
├── react/ # m2s2 generate component (React)
└── angular/ # m2s2 generate component (Angular)
Testing
# Run all tests
# Lint
# Format check
End-to-end smoke test (no npm install required):
# Scaffold a React project and inspect the output
# Generate a component inside it
Project Structure
src/
├── main.rs # CLI entry point, command routing
├── scaffold/
│ └── mod.rs # Template engine (rust-embed + Handlebars)
└── commands/
├── mod.rs
├── new.rs # m2s2 new
├── upgrade.rs # m2s2 upgrade
└── generate/
├── mod.rs # m2s2 generate (subcommand router)
└── component.rs # m2s2 generate component
Workflows
CI (ci.yml)
Runs on every push to main and every pull request.
| Job | Description |
|---|---|
build |
Compiles the crate for macOS (arm64), Linux (x86_64), and Windows (x86_64) in a matrix. |
test |
Runs cargo test on Linux. |
clippy |
Runs cargo clippy -- -D warnings. |
fmt |
Runs cargo fmt --check. |
Release (release-plz.yml + release.yml)
Releases are fully automated from conventional commits — no manual tagging required.
- Merge to
main—release-plzreads conventional commit history and opens a Release PR with a bumped version and generated CHANGELOG. - Merge the Release PR —
release-plzpushes the version tag and publishes the crate to crates.io. - Tag push —
release.yml(cargo-dist) triggers and builds platform binaries in parallel:aarch64-apple-darwinx86_64-apple-darwinaarch64-unknown-linux-gnux86_64-unknown-linux-gnux86_64-pc-windows-msvc
- GitHub Release created — all binaries, checksums, shell installer, and PowerShell installer are attached.
publish-npm.ymltriggers — publishes@m2s2/clito npm.
Template Sync (template-sync.yml)
Keeps scaffold template dependencies in sync with the latest published M²S² library versions.
Triggers:
- Weekly — every Monday at 08:00 UTC.
repository_dispatch— fired automatically by the design system CI whenever@m2s2/react-lib,@m2s2/ng-lib, or@m2s2/tokenspublishes a new release.
When a version change is detected, the workflow opens a pull request updating the pinned package versions in templates/react/package.json.hbs and templates/angular/package.json.hbs. Merging that PR flows through the normal release pipeline.
Required Repository Secrets
| Secret | Used By | Description |
|---|---|---|
APP_ID |
release-plz.yml |
GitHub App ID for bypassing branch protection on release commits. |
APP_PRIVATE_KEY |
release-plz.yml |
GitHub App private key. |
NPM_TOKEN |
publish-npm.yml |
npm access token with publish rights to the @m2s2 scope. |
CARGO_REGISTRY_TOKEN |
release-plz.yml |
crates.io API token for publishing m2s2-cli. |
Contributing
Commit messages follow the Conventional Commits specification — this is what release-plz uses to determine version bumps and generate the CHANGELOG.
| Prefix | Version bump |
|---|---|
fix: |
Patch |
feat: |
Minor |
feat!: / BREAKING CHANGE |
Major |
chore:, docs:, refactor: |
No release |
# Good examples