CLI to create projects from a catalog (architectures, project types, agents) with structure contracts. Agents can be local or downloaded from GitHub on select.
arkctl create my-app
arkctl adopt
arkctl check
arkctl list
arkctl list --stack react,ui
arkctl add architecture ./my-arch
arkctl add project ./my-template
arkctl add agent --agents karpathy
arkctl remove agent --agents karpathy
arkctl update
arkctl doctor| Concept | Role |
|---|---|
| Architecture | Contract (feature-first, hexagonal, clean, Laravel / Django / FastAPI variants, …): layout, naming, forbidden paths, import rules |
| Project type | Template that implements an architecture (+ stack tags) |
| Agent | Portable pack: local manifest, remote guidelines, Agent Skills, or tool-skills |
At arkctl create, you pick a language first (PHP, Python, TypeScript, …), then a framework family for that language (Laravel, Django, FastAPI, …), then an architecture. Custom arches go in the user catalog (arkctl add architecture); create and check read them from the registry with no special-case code.
| Kind | Install |
|---|---|
local |
From built-in catalog → agents/<id>/SYSTEM.md |
guidelines |
GitHub file (e.g. AGENTS.md) → merge into project docs |
skill |
GitHub skill folder → .agents/skills/<id>/ |
tool-skill |
Same as skill + optional post-install (e.g. npx react-doctor) |
Remote locator form: owner/repo//path@ref
npm install
npm run build
node dist/cli.js list
node dist/cli.js list --stack lib
node dist/cli.js list --stack react,next
node dist/cli.js create demo --stack lib,typescript --architecture feature-first --agents karpathy,feature-owner
node dist/cli.js create hex --stack lib,typescript --architecture hexagonal
node dist/cli.js create clean-demo --stack lib,typescript --architecture clean
node dist/cli.js create web --project react-next
node dist/cli.js create api --stack laravel,php --architecture laravel-ddd --depth minimal
node dist/cli.js create api-full --stack laravel,php --architecture laravel-ddd --depth full --bootstrap ddev
node dist/cli.js create api-vsa --stack laravel,php --architecture laravel-vertical-slice --depth minimal
node dist/cli.js create dj --stack django,python --architecture django-services --depth minimal
node dist/cli.js create dj-full --stack django,python --architecture django-ddd --depth full --bootstrap uv
node dist/cli.js create fa --stack fastapi,python --architecture fastapi-modules --depth minimal
node dist/cli.js create fa-full --stack fastapi,python --architecture fastapi-clean --depth full --bootstrap uv
node dist/cli.js create php-app --language php --stack php --architecture php-hexagonal --depth minimal
node dist/cli.js create py-app --language python --stack python --architecture python-src --depth minimal
node dist/cli.js create api-nest --stack nest,typescript,api --architecture nest-modules --depth minimal
node dist/cli.js create web-nuxt --stack vue,nuxt,web,typescript --architecture nuxt-feature --depth minimal
node dist/cli.js create app-rn --stack react-native,expo,mobile,typescript --architecture expo-feature --depth minimal
node dist/cli.js create sf --stack symfony,php --architecture symfony-clean --depth minimal
node dist/cli.js create svc --stack go --architecture go-internal --depth minimal
node dist/cli.js create mobile --stack flutter,dart --architecture flutter-feature --depth minimal
node dist/cli.js create rs --stack rust --architecture rust-crate --depth minimal
node dist/cli.js check ./demo
node dist/cli.js check --json
node dist/cli.js check --format sarif--project alone skips language/framework/architecture prompts (architecture is derived). --language / -l picks the language bucket (e.g. python). --stack accepts a full tag set (laravel,php), a language (python), or a framework tag (django). --architecture / --arch then picks among templates for that family.
On Laravel, Symfony, Django, FastAPI, NestJS, Nuxt, Expo, Flutter, Go, Rust, plain PHP, and plain Python stacks, --depth minimal|full chooses an Ark skeleton or a real tool bootstrap. Full mode also needs --bootstrap:
- Laravel:
laravel-installer|composer|sail|ddev - Symfony:
symfony-cli|composer|host - Django:
uv|host|poetry|cookiecutter-django|django-admin - FastAPI:
uv|host|poetry|cookiecutter - NestJS:
nest-cli|host - Nuxt:
nuxi|host - Expo:
create-expo-app|host - Flutter:
flutter-create|host - Go:
go-mod|host - Rust:
cargo-init|host - PHP (no framework):
composer|host - Python (no framework):
uv|host|poetry
In non-interactive shells (no TTY), pass required flags (name, --project, or --language/--stack + --architecture, etc.). Agent prompts are skipped (no agents) unless you pass --agents / --preset. Cancelled prompts exit with code 1.
Remote agents are cached under ~/.ark/cache (override with ARK_CACHE_DIR).
node dist/cli.js list --group matt-pocock
node dist/cli.js create demo --project ts-lib --preset matt-pocock-core
node dist/cli.js add agent --dir ./demo --agents no-ai-slopSome agents (tool-skill) and presets declare follow-up commands or notes (e.g. npx react-doctor, gstack ./setup, Matt Pocock /setup-matt-pocock-skills).
By default Ark writes them to .agents/POSTINSTALL.md and does not run shell commands. Pass --run-postinstall to execute those commands during create or add agent:
node dist/cli.js create web --project react-next --agents react-doctor --run-postinstall
node dist/cli.js add agent --dir ./web --agents react-doctor --run-postinstallPreset notes (Matt Pocock, gstack) land in the same POSTINSTALL.md Notes section.
Custom architectures and project types live under ~/.ark/catalog (override with ARK_CATALOG_DIR or --catalog). They merge with the built-in catalog; same id → user wins.
~/.ark/catalog/
registry.yaml
architectures/
my-arch/
manifest.yaml
…
projects/
my-stack/
manifest.yaml
template/
Register packs:
# Architecture (local copy or GitHub locator; fetched on create/check)
arkctl add architecture ./path/to/arch-pack
arkctl add architecture me/ark-packs//architectures/hexagonal@main
# Project template (local copy or GitHub locator; fetched on create)
arkctl add project ./path/to/pack
arkctl add project me/ark-templates//projects/my-stack@main
arkctl add project ./pack --id my-stack --stacks react,typescript
arkctl add architecture ./my-arch --id my-arch
arkctl add project ./pack --id my-stack --architecture my-arch
arkctl list
arkctl create app --stack <tags> --architecture my-arch --project my-stack
arkctl check ./app
arkctl check --json
arkctl check --format sarif
# Add agents later (into an existing scaffold)
arkctl add agent --dir ./app --preset matt-pocock-core
arkctl add agent --dir ./app --agents karpathy,feature-ownerA project pack needs manifest.yaml (with implements.architecture already in the catalog) and a template root (source.root, usually ./template). An architecture pack needs manifest.yaml plus the declared layout/tree/conventions files. Layer-only arches use roots + import deny rules; repeating units use optional modules in tree.schema.yaml.
| Preset | Contents |
|---|---|
matt-pocock-core |
Setup + grill + TDD + review + specs + implement (+ handoff) |
gstack-lite |
Plan/review/investigate/safety/ship Markdown skills (no Bun) |
gstack-full |
Official gstack setup (git clone + ./setup, needs Bun) |
node dist/cli.js create app --project ts-lib --preset gstack-lite
node dist/cli.js create app --project ts-lib --preset gstack-full
node dist/cli.js list --group gstackAfter create with this preset: run /setup-matt-pocock-skills once in your agent (see also .agents/POSTINSTALL.md).
| Id | Style |
|---|---|
feature-first |
Domain in features/<name>/, public API + shared/ |
hexagonal |
domain/, application/ (ports), `adapters/inbound |
clean |
domain/, application/, infrastructure/ |
laravel-folder-by-feature |
app/{Feature}/ with Controllers, Models, Routes |
laravel-vertical-slice |
app/Features/{Slice}/ with Action.php entrypoint |
laravel-nwidart |
Modules/{Module}/ via nwidart/laravel-modules |
laravel-internachi |
app-modules/{module}/ Composer path packages |
laravel-ddd |
app/Domains/{Domain}/{Domain,Application,Infrastructure}/ |
django-apps |
apps/{app}/ with models.py + apps.py |
django-services |
apps/{app}/ with services.py + selectors.py |
django-rapid |
RAPID: data/, interfaces/, readers/, actions/ |
django-ddd |
domains/{domain}/{domain,application,infrastructure}/ |
fastapi-tiangolo |
app/api/, app/crud.py, app/models.py, app/core/ |
fastapi-layered |
api/, services/, repositories/, models/, schemas/ |
fastapi-modules |
src/{feature}/ with router.py + service.py |
fastapi-clean |
domain/, application/, infrastructure/, presentation/ |
php-layered |
Vanilla PHP: src/{Controller,Service,Repository,Model}/ |
php-hexagonal |
Vanilla PHP: src/{Domain,Application,Infrastructure}/ |
php-feature |
Vanilla PHP: src/Features/{Feature}/Action.php |
python-src |
PyPA src/{package}/ library/CLI layout |
python-clean |
domain/, application/, infrastructure/ |
python-hexagonal |
domain/, application/, adapters/ |
python-feature |
features/{feature}/ public __init__.py |
nest-modules |
NestJS src/{feature}/ feature modules |
nest-clean |
NestJS src/{domain,application,infrastructure}/ |
nest-hexagonal |
NestJS src/{domain,application,adapters}/ |
nuxt-feature |
Nuxt 4 app/features/ + shared/ |
expo-feature |
Expo Router src/app/ + src/features/ + src/shared/ |
symfony-standard |
Symfony Flex src/Controller/ |
symfony-clean |
Symfony src/{Domain,Application,Infrastructure}/ |
symfony-hexagonal |
Symfony clean with HTTP under Infrastructure/Http/ |
go-internal |
Go cmd/ + internal/ |
go-clean |
Go internal/{domain,application,infrastructure}/ |
go-hexagonal |
Go internal/{domain,application,adapters}/ |
flutter-feature |
Flutter lib/features/ + lib/shared/ |
flutter-clean |
Flutter lib/{domain,data,presentation}/ |
rust-crate |
Rust idiomatic src/ crate |
rust-clean |
Rust src/{domain,application,infrastructure}/ |
rust-hexagonal |
Rust src/{domain,application,adapters}/ |
| Id | Architecture | Stacks | Unlocks (interactive) |
|---|---|---|---|
ts-lib |
feature-first | lib, typescript |
general agents only |
ts-lib-hexagonal |
hexagonal | lib, typescript |
general agents only |
ts-lib-clean |
clean | lib, typescript |
general agents only |
react-next |
feature-first | react, next, web, ui, typescript |
Hallmark, Vercel React/Next skills, React Doctor |
laravel-folder-by-feature |
laravel-folder-by-feature | laravel, php |
Laravel pack |
laravel-vertical-slice |
laravel-vertical-slice | laravel, php |
Laravel pack |
laravel-nwidart |
laravel-nwidart | laravel, php |
Laravel pack |
laravel-internachi |
laravel-internachi | laravel, php |
Laravel pack |
laravel-ddd |
laravel-ddd | laravel, php |
Laravel pack |
django-apps |
django-apps | django, python |
Django pack |
django-services |
django-services | django, python |
Django pack |
django-rapid |
django-rapid | django, python |
Django pack |
django-ddd |
django-ddd | django, python |
Django pack |
fastapi-tiangolo |
fastapi-tiangolo | fastapi, python |
FastAPI pack |
fastapi-layered |
fastapi-layered | fastapi, python |
FastAPI pack |
fastapi-modules |
fastapi-modules | fastapi, python |
FastAPI pack |
fastapi-clean |
fastapi-clean | fastapi, python |
FastAPI pack |
php-layered |
php-layered | php |
Vanilla PHP |
php-hexagonal |
php-hexagonal | php |
Vanilla PHP |
php-feature |
php-feature | php |
Vanilla PHP |
python-src |
python-src | python |
Vanilla Python |
python-clean |
python-clean | python |
Vanilla Python |
python-hexagonal |
python-hexagonal | python |
Vanilla Python |
python-feature |
python-feature | python |
Vanilla Python |
nest-modules |
nest-modules | nest, typescript, api |
NestJS pack |
nest-clean |
nest-clean | nest, typescript, api |
NestJS pack |
nest-hexagonal |
nest-hexagonal | nest, typescript, api |
NestJS pack |
nuxt-feature |
nuxt-feature | vue, nuxt, web, typescript |
Nuxt pack |
react-native-expo |
expo-feature | react-native, expo, mobile, typescript |
Vercel React Native |
symfony-standard |
symfony-standard | symfony, php |
Symfony pack |
symfony-clean |
symfony-clean | symfony, php |
Symfony pack |
symfony-hexagonal |
symfony-hexagonal | symfony, php |
Symfony pack |
go-internal |
go-internal | go |
Go pack |
go-clean |
go-clean | go |
Go pack |
go-hexagonal |
go-hexagonal | go |
Go pack |
flutter-feature |
flutter-feature | flutter, dart |
Flutter pack |
flutter-clean |
flutter-clean | flutter, dart |
Flutter pack |
rust-crate |
rust-crate | rust |
Rust pack |
rust-clean |
rust-clean | rust |
Rust pack |
rust-hexagonal |
rust-hexagonal | rust |
Rust pack |
TanStack: tanstack-spa (guidelines) and tanstack-intent (tool-skill, runs npx @tanstack/intent install).
no-ai-slop,no-ai-slop-skill,llm-guidelines,codequality,clean-code(all stacks)- Laravel pack:
laravel-best-practices,laravel-database(stacks:laravel,php) - Django pack:
django-best-practices,django-orm(stacks:django,python) - FastAPI pack:
fastapi-best-practices(stacks:fastapi,python) - Vanilla Python:
python-best-practices(stacks:python) - Vanilla PHP:
php-best-practices(stacks:php) - Symfony:
symfony-best-practices(stacks:symfony,php) - Go:
go-best-practices(stacks:go) - Flutter:
flutter-best-practices(stacks:flutter,dart) - Rust:
rust-best-practices(stacks:rust) - TanStack:
tanstack-spa(stacks:react,web,typescript);tanstack-intenttool-skill (stacks:react,next,web,typescript)
karpathy: multica-ai/andrej-karpathy-skillsponytail: DietrichGebert/ponytail (AGENTS.md)hallmark: Nutlope/hallmarkvercel-react-best-practices,vercel-composition-patterns,vercel-web-design-guidelines,vercel-react-native: vercel-labs/agent-skillsreact-doctor: millionco/react-doctor (tool-skill)tanstack-intent: local tool-skill wrapping@tanstack/intent
karpathy and ponytail share exclusive group minimalism (warning if both selected).
Machine-readable output for pipelines (no Clack text):
arkctl check --json
arkctl check --format sarifExit 1 when any issue has severity error; warnings alone exit 0.
Composite GitHub Action:
- uses: manuelebeh/ark-cli/.github/actions/ark-check@v0.5.0
with:
path: .
format: jsonInputs: path (default .), format (json | sarif | text), optional catalog, version (npm arkctl version, default 0.5.0). Example workflow: .github/workflows/ark-check.yml.example.
Bind an existing repo (detect stacks + score architectures, write ark.project.yaml, then check):
arkctl adopt
arkctl adopt --architecture feature-first --project ts-lib --yes
arkctl adopt --jsonRefresh GitHub cache under ~/.ark/cache (or ARK_CACHE_DIR):
arkctl update
arkctl update --dry-run
arkctl update --agents --dir ./my-appRemove agents (inverse of arkctl add agent):
arkctl remove agent --agents karpathy,feature-ownerEnvironment diagnostics:
arkctl doctor
arkctl doctor --dir . --strict
arkctl doctor --jsonRun unit tests:
npm testv0.5: Flutter/Dart + Rust packs + import checking, Symfony + Go packs, Nest/Nuxt/Expo packs + CLI bootstrap, Django + FastAPI packs, Python import checking, shared depth/bootstrap, arkctl check --json / --format sarif, GitHub Action, adopt / update / remove agent / doctor, npm test. v0.4: GitHub download + cache, stack-filtered agent selection, remote skill/guidelines install, user catalog + arkctl add, multi-architecture create (feature-first, hexagonal, clean, five Laravel approaches), optional --run-postinstall.