How it works
High-level architecture of the FivFold CLI engine: packages, detection, manifests, pipeline, VFS, AST, and plugins.
Package structure
FivFold is built as a monorepo with three main packages. The core engine is shared; the UI and API CLIs orchestrate it for their respective domains.
@fivfold/core
Shared engine: VFS, StrategyPipeline, TemplateEngine, Manifests, TsMorphEngine, Detection, Workspace. Used by both CLIs. No framework or database specifics—fully agnostic.
@fivfold/ui
init, add, list, agents, setup. Uses VFS + loadUiManifest for copy-based scaffolding. No StrategyPipeline—templates are copied directly into your project.
@fivfold/api
init, add, list. Uses full pipeline (VFS + StrategyPipeline + TemplateEngine + manifests + AST) for manifest-based Kits. Legacy registry mode for older modules.
Architecture
The FivFold CLI is an extensible scaffolding engine. It does not hardcode every stack permutation. Instead, it uses manifests to describe Kits, a Strategy Pattern to compose generators, and a Virtual File System to stage changes before committing.

Shared config
Both CLIs read from fivfold.json. Run @fivfold/ui init first if you use both; the API init merges its config into the existing file in a monorepo setup.
Pipeline
When you run npx @fivfold/api add <module>:
Detect
package.json to detect framework and ORM. Skip prompts when detected.Load manifest
Run strategies
VFS stage
Commit
--dry-run, flush to disk atomically. Then run npm install for new dependencies.UI vs API
API uses StrategyPipeline for manifest-based Kits. UI uses VFS + manifests for copy-based scaffolding—no pipeline, just direct template copy.
Manifests
Kits are defined by declarative JSON/YAML schemas (manifests). The manifest specifies dependencies to install, template files to copy, and AST mutation targets. The CLI acts as an agnostic orchestrator—it does not hardcode every Kit.
Manifest-driven
Modern Kits use .kit.json manifests in ui/manifests/ and api/manifests/. Declarative, extensible, and easy to add new Kits.
Legacy registry
Older modules may use registry JSON. Still supported for backward compatibility. New Kits use manifest-driven approach.
Manifest structure
A .kit.json typically includes: files (templates to copy), shadcnDependencies (primitives to add), astMutations (targets for code injection), and optional auth provider configuration when applicable.
Strategy Pattern
FivFold avoids hardcoding directories for every stack permutation. Instead, it uses interchangeable strategy classes. Each strategy implements IGeneratorStrategy and generates files for its layer. The pipeline composes them based on the user's selection.
domain
Framework-agnostic entities, DTOs, ports (interfaces).
framework
Modules, controllers, routes, middleware—adapts to your chosen framework.
orm
Entities, repositories, schema—adapts to your chosen data layer.
auth / delivery
Auth adapters when applicable; HTTP transport wiring.
StrategyPipeline runs strategies in order. Each receives a GeneratorContext with the VFS, template engine, manifest, and stack config. Strategies write to the VFS—they never touch the disk directly.
// Simplified flow
const pipeline = new StrategyPipeline([
getStrategy('domain'),
getStrategy('framework'),
getStrategy('orm'),
getStrategy('auth'), // Optional, when applicable
]);
await pipeline.run(ctx);Virtual File System
The VFS ensures no partial writes. All file creations, modifications, and deletions are staged in memory first. Only after all generators complete successfully does the VFS flush to disk in a single transaction. If any step fails, nothing is written.
Stage
stageCreate, stageModify, or stageDelete. Nothing hits disk.Preview or commit
--dry-run, call preview(root) to see the diff. Otherwise, call commit(root) to write atomically.From @fivfold/core:
stageCreate(path, content)— Stage a new filestageModify(path, content)— Stage an overwritestageDelete(path)— Stage a deletionpreview(rootDir)— Human-readable diff for dry runcommit(rootDir)— Write all staged ops to disk
npx @fivfold/api add <module> --dry-runAST Engine
For existing files, FivFold never uses regex or .replace(). That would be fragile and could destroy user modifications. Instead, it uses Abstract Syntax Tree (AST) manipulation via ts-morph: parse the file, inject the node, serialize back.
Existing vs new files
AST mutations apply only to existing files (e.g. app entry, module registration). New files use Handlebars templating.
Built-in mutations include:
- Register module in app — Add a module to app imports
- Register middleware — Add middleware to the app
- Add import if not present — Inject an import statement when missing
Plugin Architecture
FivFold has two packages today: @fivfold/ui and @fivfold/api. The architecture is being prepared for a unified, language-agnostic future.
Orchestrator
Terminal input, VFS, manifest resolution, pipeline orchestration. Framework and database agnostic.
Plugins
Language-specific logic (e.g. ts-morph for Node/TypeScript) will live in isolated plugins. The orchestrator stays agnostic; plugins do the heavy lifting.
