Scaffold modern app stacks in seconds using reusable preset modules.
No boilerplate. No lock-in. Just clean, repeatable setup.
Docs: https://antarmukhopadhyaya.github.io/forge-dev/
npx @antardev/forge-dev init next-saas-pro my-app
cd my-app
npm run devForge generates structure, not business logic.
Setting up the same project foundations repeatedly is slow and inconsistent.
Forge solves this by:
- Running preset-driven scaffolding flows
- Keeping presets portable and versionable
- Supporting local and remote preset modules
- Detecting your environment automatically with
npx @antardev/forge-dev doctor
- express-ts-prisma-postgres
- express-ts-drizzle-postgres
- next-saas-pro
- expo-nativewind-supabase
- tanstack-start
- mern-stack
Remote presets require the --trust flag to prevent accidental execution of untrusted code.
- Built-in preset modules under
src/presets/builtins/<preset>/preset.yaml. - Workspace custom preset modules under
./presets/custom/<preset>/preset.yaml. - Custom preset modules under
~/.forge/presets/custom. - Trusted remote preset import via
npx @antardev/forge-dev init <github-url> --trust. - Variable prompts with defaults and choice options.
- Conditional steps via
ifin preset steps. - Generic runtime metadata for non-Node presets, including
languageand custom install commands. - Template rendering via Handlebars.
- Per-language formatter routing with graceful fallback.
- Doctor cache for runtime/package manager/formatter detection.
- Dry run mode for safe previews.
- Node.js 20+
- npm
npm install -g @antardev/forge-dev
npx @antardev/forge-dev --helpnpm install
npx @antardev/forge-dev listDry run first when trying a new preset:
npx @antardev/forge-dev init mern-stack my-app --dry-runScaffold a project from a preset.
Options:
-d, --dry-run: preview steps without writing files.-v, --verbose: verbose logs.-y, --yes: skip prompts and use defaults.--trust: required for trusted remote preset sources.
Examples:
npx @antardev/forge-dev init next-saas-pro my-saas-app
npx @antardev/forge-dev init express-ts-drizzle-postgres my-api
npx @antardev/forge-dev init expo-nativewind-supabase my-app
npx @antardev/forge-dev init ens my-app
npx @antardev/forge-dev init expo-nw my-app
npx @antardev/forge-dev init mern-stack my-app
npx @antardev/forge-dev init ./presets/my-team/preset.yaml team-app
npx @antardev/forge-dev init github.com/owner/custom-preset my-app --trustExample output:
✔ Project ready
Next steps:
1. Configure environment variables
2. Run auth setup
3. Run database setup
4. Start development
Shows available presets with source and optional tags.
Creates a custom preset module at:
~/.forge/presets/custom/<name>/preset.yaml~/.forge/presets/custom/<name>/meta.json~/.forge/presets/custom/<name>/templates/README.md.tpl
Top-level shortcut to bring your own preset by scaffolding a local preset module.
When run in an interactive terminal, Forge prompts for the runtime and related
stack settings. Use --yes to skip prompts and accept defaults.
Flags:
-y, --yes: skip prompts and use defaults.--runtime <runtime>: record the target runtime in the starter YAML.--language <language>: record the language in the starter YAML.--package-manager <package-manager>: record the package manager in the starter YAML.--install-command <command>: set a custom installer command prefix for install steps.
Creates:
./presets/custom/<name>/preset.yaml./presets/custom/<name>/meta.json./presets/custom/<name>/templates/README.md.tpl
Example:
npx @antardev/forge-dev scaffold my-team-api
npx @antardev/forge-dev init my-team-api app-nameScaffolds a project-local preset module so you can edit templates and YAML in the same repo without context switching.
This command remains available; it is equivalent to npx @antardev/forge-dev scaffold <name>.
Creates:
./presets/custom/<name>/preset.yaml./presets/custom/<name>/meta.json./presets/custom/<name>/templates/README.md.tpl
Example:
npx @antardev/forge-dev preset scaffold my-team-api
npx @antardev/forge-dev init my-team-api app-nameRemoves matching custom preset entries by preset name or alias from custom preset directories.
Important:
- Built-in presets cannot be removed.
- Only custom presets are removable.
Examples:
npx @antardev/forge-dev preset remove next-app
npx @antardev/forge-dev preset remove my-team-starterShows detected local environment and writes cache to ~/.forge/doctor.json.
npx @antardev/forge-dev doctor
npx @antardev/forge-dev doctor --refreshDoctor tracks:
- Node and package managers (
npm,pnpm,yarn) - Languages: Python, Go
- Tools: Git
- Formatters:
prettier,black,gofmt,google-java-format
next-saas-pro is intentionally setup-only (no business logic), including:
- Next.js TS app base
- Better Auth
- Better Auth Drizzle adapter
- Better Auth organizations plugin
- Drizzle ORM (Postgres)
- API route handler for
/api/auth/[...all] - env placeholders and drizzle config
Installed by preset:
- dependencies:
better-auth,@better-auth/drizzle-adapter,drizzle-orm,pg,dotenv - devDependencies:
drizzle-kit,@types/pg
Each preset is a self-contained module:
src/presets/builtins/<preset>/
preset.yaml
templates/
meta.json (optional)
Custom presets follow the same structure in either:
./presets/custom/<preset>/~/.forge/presets/custom/<preset>/
Preset aliases can be declared directly in preset.yaml:
name: expo-nativewind-supabase
aliases:
- ens
- expo-nw
- expo-nativewindBenefits:
- Portable and publishable as a unit.
- Cleaner template resolution (
./templates/...). - Easier plugin ecosystem evolution.
When running npx @antardev/forge-dev init <preset>:
- explicit path-like value (
/,\\,.yaml,.yml) ./presets/<name>.yaml./presets/custom/<name>.yaml~/.forge/presets/custom/**(recursive)- built-in module:
src/presets/builtins/<name>/preset.yaml
If a preset path is used, Forge caches it for reuse by short name.
Minimal example:
name: my-team-api
description: "Express + Drizzle API scaffold"
version: "1.0"
runtime: node
packageManager: npm
aliases:
- mta
variables:
project:
type: string
prompt: "Project name"
default: "my-api"
database:
type: choice
prompt: "Database"
options: [postgres, mysql]
default: postgres
steps:
- run: npm init -y
- install:
deps: [express, zod]
- install:
deps: [typescript, tsx]
dev: true
- file:
path: src/index.ts
template: ./templates/index.ts.tpl
vars:
appName: "{{project}}"
- env:
PORT: "3000"
- run: echo "Using Postgres"
if:
database: postgres
postRun:
- npm run devTop-level fields:
name: Preset identifier.aliases: Optional alternate names users can pass tonpx @antardev/forge-dev init.description: Human-friendly description used in listing and metadata.version: Optional preset version string for your own tracking.runtime: Required runtime. Supported:node,python,go.packageManager: Optional Node package manager override (npm,pnpm,yarn).variables: Optional input variables collected before steps execute.steps: Required ordered execution plan.postRun: Optional commands shown as next-step hints.
Variable formats:
type: string: Free-text input. Supports optionalpromptanddefault.type: choice: Select fromoptions. Supportspromptand optionaldefault.
Supported steps entries:
run: Execute a shell command.cd: Change working directory.install: Install dependencies. Usedepsarray and optionaldev: true.file: Render a template file. Usetemplateand optionalvarsmap.env: Set environment variables used by later steps.
Conditional execution:
- Any step can include an
ifobject to match variable values before running. - Example:
if: { database: postgres }.
Template path behavior:
- Paths beginning with
./are resolved relative to the preset YAML file. - This keeps custom presets portable as self-contained modules.
meta.json (optional but recommended):
{
"name": "my-team-api",
"description": "Express + Drizzle API scaffold",
"tags": ["custom", "api"]
}name: Display name override for list output.description: Description override for list output.tags: Optional tags shown innpx @antardev/forge-dev list.
Forge applies formatter-by-language on generated files:
- JS/TS:
prettier --write - Python:
black - Go:
gofmt -w - Java:
google-java-format --replace
Important behavior:
- Forge does not auto-install formatter tools.
- If formatter is missing, Forge logs a warning and continues.
- Scaffolding never hard-fails due to missing formatter binaries.
For Node runtime presets:
- Install steps use detected/requested manager (
npm,pnpm,yarn). - Run commands are rewritten at execution time when needed.
Examples:
npm install,npm run --prefix,npx,npm create.
npm run lint
npm test
npm run build
npx @antardev/forge-dev list- Run
npx @antardev/forge-dev list. - Verify preset name/path.
- Validate YAML syntax.
Expected when formatter tools are not installed globally.
Install the formatter you want, then run npx @antardev/forge-dev doctor --refresh.
You must pass --trust for GitHub preset URLs.
Ensure npm run build completed and copied assets into dist.
MIT
