Clojure Project Scaffolding
Create minimal project structure to get started. This is scaffolding, NOT code generation.
Philosophy
CRITICAL: This tool creates the bare minimum to start coding:
- Directory structure
- Build configuration (bb.edn, deps.edn, shadow-cljs.edn as needed)
- Hello world examples with
(comment ...)blocks - Basic .gitignore and README
DO NOT:
- Generate custom endpoints, routes, or pages
- Make assumptions about business logic
- Add features not explicitly requested
- Take creative liberties with code
The user will build their app with forj and REPLs after scaffolding.
Usage Modes
Direct Mode (Power Users)
Skip questions with flags:
/clj-init my-app --api --db postgres --web
/clj-init my-app --mobile
/clj-init my-app --api --mobile
/clj-init my-app --script
/clj-init my-app --flutter
/clj-init my-app --htmx simpleui --db postgres
/clj-init my-app --htmx biff
Flags:
| Flag | Module | Description |
|---|---|---|
--api |
api | Clojure server with Ring/Reitit |
--db postgres |
db-postgres | PostgreSQL with next.jdbc |
--db sqlite |
db-sqlite | SQLite with next.jdbc |
--htmx simpleui |
htmx-simpleui | HTMX with SimpleUI (lightweight) |
--htmx biff |
(external) | HTMX with Biff (uses Biff generator) |
--web |
web | ClojureScript web (Reagent/Re-frame) |
--mobile |
mobile | Expo + ClojureScript |
--script |
script | Babashka script only |
--flutter |
flutter | ClojureDart Flutter (mobile/desktop/web) |
Examples:
/clj-init api-server --api --db postgres→ REST API + PostgreSQL/clj-init my-site --web→ Web frontend only/clj-init my-tool --script→ Babashka script/clj-init my-app --flutter→ ClojureDart Flutter app/clj-init my-app --htmx simpleui→ HTMX web app with SimpleUI/clj-init my-app --htmx biff→ Triggers Biff flow (external generator)
Guided Mode (Interactive)
/clj-init
/clj-init my-app
If no flags provided, ask questions to determine modules.
Question Flow (Guided Mode)
Step 1: Project Name
If not provided, ask in plain text:
"What would you like to name the project?"
CRITICAL: Do NOT use AskUserQuestion tool for the project name. Just output the question as text. The name is free-form text, not multiple choice.
Step 2: Backend
Question: "Do you need a backend/API?" Options:
- Yes - Clojure server
- No - Frontend only or script
If Yes, ask:
Question: "What kind of interface?" Options:
- API only - REST endpoints with Ring/Reitit
- HTMX web app - Server-rendered HTML
- Separate frontend - API that serves a SPA or mobile app
If HTMX selected, ask:
Question: "Which HTMX framework?" Options:
- Biff - Full-featured web framework (opinionated, batteries included)
- SimpleUI - Lightweight library on Ring/Reitit
If Biff selected: See Biff Flow below - uses external generator.
If API only, SimpleUI, or Separate frontend, ask:
Question: "Database?" Options:
- None - No database
- PostgreSQL - With next.jdbc and HoneySQL
- SQLite - Lightweight, file-based
Step 3: Frontend
Only ask if "Separate frontend" was selected OR if user said No to backend.
Question: "Do you need a frontend?" Options:
- None - Backend/script only
- ClojureScript - Web and/or mobile with Expo
- Flutter - ClojureDart (mobile/desktop/web)
If ClojureScript selected, ask:
Question: "Which platforms?" Options:
- Web only - Browser app with Reagent/Re-frame
- Mobile only - Expo/React Native
- Both - Web and mobile
Note: Flutter uses ClojureDart (a different Clojure dialect). It cannot be combined with ClojureScript frontends, but works fine with a Clojure backend.
Step 4: Script-Only
If user selected No backend AND No frontend → Script project (Babashka only)
Biff Flow
Biff is an opinionated full-stack framework with its own project generator. We don't scaffold it directly.
When user selects Biff:
Output this message:
"Biff has its own project generator. Please run this command in another terminal:
clj -M -e '(load-string (slurp "https://biffweb.com/new.clj"))'Follow the prompts to create your project. Let me know when you're done and what you named the project."
Wait for user to confirm completion and provide project name.
Once they confirm (e.g., "done, called it myapp"):
- Run
validate_projectwith path./myappandfix=true - Ask about permissions (see After Scaffolding)
- Tell them:
cd myapp && claude /clj-repl
- Run
IMPORTANT: Do NOT try to run Biff's generator programmatically. Let the user interact with it directly.
Module Selection
Based on answers, determine modules for scaffold_project:
| Configuration | Modules |
|---|---|
| Script only | ["script"] |
| API only | ["api"] |
| API + PostgreSQL | ["api", "db-postgres"] |
| API + SQLite | ["api", "db-sqlite"] |
| HTMX (Biff) | Use Biff flow (not scaffold_project) |
| HTMX (SimpleUI) | ["api", "htmx-simpleui"] |
| HTMX (SimpleUI) + PostgreSQL | ["api", "htmx-simpleui", "db-postgres"] |
| HTMX (SimpleUI) + SQLite | ["api", "htmx-simpleui", "db-sqlite"] |
| Web only | ["web"] |
| Mobile (Expo) only | ["mobile"] |
| Web + Mobile (Expo) | ["web", "mobile"] |
| Flutter only | ["flutter"] |
| API + Web | ["api", "web"] |
| API + Mobile (Expo) | ["api", "mobile"] |
| API + Web + Mobile (Expo) | ["api", "web", "mobile"] |
| API + Flutter | ["api", "flutter"] |
| API + PostgreSQL + Web | ["api", "db-postgres", "web"] |
| API + PostgreSQL + Flutter | ["api", "db-postgres", "flutter"] |
Creating the Project
CRITICAL: Use the scaffold_project MCP tool. Do NOT manually write files.
Once you have the project name and modules list:
scaffold_project with:
project_name: "my-app"
modules: ["api", "web"]
output_path: "." (optional, defaults to current directory)
The tool handles everything:
- Merges configs from all modules (deps.edn, bb.edn, shadow-cljs.edn, package.json)
- Substitutes version placeholders from versions.edn
- Copies source files with namespace substitution
- Handles module dependencies (e.g., db-postgres requires api)
Validation (REQUIRED)
After scaffold_project succeeds, run validation:
validate_project with path="./my-app" fix=true
This tool handles:
- bb.edn repl task - Adds
:override-builtin trueif missing - deps.edn resolution - Verifies dependencies resolve
- npm install - Runs if package.json exists but node_modules doesn't
- Java version - Reports if Java version is below 21 for shadow-cljs
DO NOT tell the user the project is ready until validate_project returns success: true.
After Scaffolding
Step 1: Ask About Permissions
Question: "Would you like to enable forj tool permissions for this project?" Options:
- Yes (Recommended) - Auto-approve forj MCP tools and bb tasks
- No - I'll approve tools manually as needed
If Yes, create .claude/settings.local.json in the project:
mkdir -p ./my-app/.claude
Then write this file:
{
"permissions": {
"allow": [
"Bash(bb:*)",
"Bash(mkdir:*)",
"Bash(pgrep:*)",
"Bash(pkill:*)",
"Bash(lsof:*)",
"mcp__forj__repl_eval",
"mcp__forj__discover_repls",
"mcp__forj__reload_namespace",
"mcp__forj__doc_symbol",
"mcp__forj__eval_at",
"mcp__forj__eval_comment_block",
"mcp__forj__run_tests",
"mcp__forj__analyze_project",
"mcp__forj__validate_changed_files",
"mcp__forj__track_process",
"mcp__forj__stop_project",
"mcp__forj__list_tracked_processes",
"mcp__forj__view_repl_logs"
]
}
}
Step 2: Report Success
Tell the user:
- Project created at
./my-app - Dependencies verified ✓
- Permissions configured (if they chose yes)
- Next step:
For Clojure/ClojureScript projects:
cd my-app && claude /clj-repl
For Flutter projects:
cd my-app
bb flutter # Run app with hot reload + REPL
ClojureDart is initialized automatically during scaffolding. REPL starts automatically - watch for 🤫 ClojureDart REPL listening on port XXXXX in output, then connect with nc localhost XXXXX.
If project has BOTH backend AND Flutter:
cd my-app && claude /clj-repl # For the Clojure backend
# In another terminal:
bb flutter # For Flutter frontend
IMPORTANT: Do NOT offer to start the REPL from the current session. The user should exit and restart Claude Code in the new project directory so that:
- Hooks detect the correct project type
- REPL starts in the correct working directory
- File paths are relative to the project root
STOP HERE. Do not start building or generating code. The scaffolding is complete.
Available Modules
| Module | Description | Provides |
|---|---|---|
| base | Common files | .gitignore, README.md |
| script | Babashka script | bb.edn, hello-world src |
| api | Ring/Reitit server | deps.edn, bb.edn, core.clj, routes.clj |
| htmx-simpleui | HTMX with SimpleUI | simpleui dep, htmx, hiccup views |
| db-postgres | PostgreSQL support | next.jdbc, honeysql, pg driver |
| db-sqlite | SQLite support | next.jdbc, honeysql, sqlite driver |
| web | ClojureScript web | shadow-cljs.edn, package.json, reagent, re-frame |
| mobile | Expo mobile | shadow-cljs.edn, package.json, app.json, expo config |
| flutter | ClojureDart Flutter | deps.edn (git dep), bb.edn, main.cljd |
Modules automatically include their dependencies (e.g., api includes base, htmx-simpleui includes api).
Notes:
- The
fluttermodule uses ClojureDart (a different Clojure dialect). It can be combined with backend modules (api,db-*) but NOT with ClojureScript frontend modules (web,mobile). - The
htmx-simpleuimodule is for server-rendered HTML apps. It cannot be combined withwebormobilemodules (no ClojureScript needed). - For Biff (full-featured HTMX framework), use the Biff flow instead of scaffold_project.
DevOps (Optional)
Only if user asks, add basic deployment configs:
- Dockerfile - Simple multi-stage build
- Procfile - For Railway/Heroku
- .github/workflows/test.yml - Basic CI
Do NOT add complex infrastructure. Keep it simple.
Future Enhancements
- Electric - Full-stack reactive apps
- GraphQL - Lacinia integration module