Add a UI/UX design phase (/define-design, /update-design) and a platform app generation phase (/generate-app web|flutter|winui3) to the workflow, positioned between /setup-project and /add-feature. - commands: define-design, generate-app, update-design - add-feature: check docs/design/ before implementation; update design files first when a feature changes the UI - skills: ui-design, design-tokens, platform-ui-generation - docs/design/ structure documented (source of truth = ui-blueprint.json; SVGs are references only; generated UI follows design-tokens.json) - README and AGENTS.md updated with the new workflow
15 KiB
opencode Spec-Driven Development Boilerplate
A spec-driven development boilerplate for opencode, converted from the Claude Code boilerplate that accompanies the book "Practical Claude Code Introduction."
It gives opencode a structured workflow for turning ideas into production code through persistent design documents, per-task steering files, AI skills, subagents, and slash commands.
Table of Contents
- What Is Spec-Driven Development?
- Conversion Summary (Claude Code → opencode)
- Prerequisites
- Quick Start
- Directory Structure
- Configuration Overview
- Usage Workflow
- Design & App Generation
- Commands Reference
- Skills Reference
- Agents Reference
- Customizing the Boilerplate
- Troubleshooting
- License
What Is Spec-Driven Development?
Spec-driven development separates "what to build" from "how to build it":
- Persistent documents (
docs/) — the north-star design (PRD, functional design, architecture, etc.) - Steering files (
.steering/) — per-task plans created fresh for each piece of work - Implementation — the agent follows
tasklist.md, updating progress as it goes - Verification — tests, lint, typecheck, and a retrospective
opencode loads the right skill automatically based on what you're doing, so you don't have to think about the process — just describe what you want.
Conversion Summary (Claude Code → opencode)
| Claude Code | opencode | Notes |
|---|---|---|
CLAUDE.md |
AGENTS.md |
Referenced via instructions in opencode.json |
.claude/settings.json |
opencode.json |
Permissions converted to opencode's permission schema |
.claude/agents/*.md |
.opencode/agent/*.md |
Added mode: subagent; model: sonnet removed (inherits default) |
.claude/commands/*.md |
.opencode/command/*.md |
Tool-call syntax (Bash(), Grep(), Skill()) converted to natural instructions; $ARGUMENTS added |
.claude/skills/*/SKILL.md |
.opencode/skills/*/SKILL.md |
allowed-tools frontmatter removed (not an opencode field) |
Skill('steering') calls |
Auto-loaded by description | opencode surfaces skills via description matching |
TodoWrite / Edit tool refs |
todowrite / edit |
Lowercased to match opencode tool names |
| Claude Code devcontainer feature | curl … opencode.ai/install |
Replaced Anthropic feature with opencode install script |
All skill templates and guides were preserved verbatim except for .claude/ path references and
"Claude Code" mentions, which were updated to .opencode/ and "opencode" respectively.
Prerequisites
- Node.js v18+ (v24.11.0 recommended)
- npm
- opencode — install with:
See https://opencode.ai/docs for alternatives (npm, Homebrew, etc.)curl -fsSL https://opencode.ai/install | bash - Docker (only if using the Dev Container)
Quick Start
Option A — Dev Container (recommended)
- Open this folder in VS Code.
- When prompted, click "Reopen in Container" (or run the command Dev Containers: Reopen in Container).
- The container automatically:
- Installs Node.js LTS
- Runs
npm install - Installs opencode
- Open a terminal and start opencode:
opencode
Option B — Manual setup
# 1. Install dependencies
npm install
# 2. Set up Git hooks
npm run prepare
# 3. Start opencode
opencode
Directory Structure
.
├── opencode.json # opencode config (permissions, instructions)
├── AGENTS.md # Project instructions (loaded into every session)
├── package.json # Node.js project + scripts
├── tsconfig.json # TypeScript config
├── eslint.config.js # ESLint flat config
├── vitest.config.ts # Vitest config (80% coverage threshold)
├── .prettierrc / .prettierignore
├── .gitignore
├── .husky/pre-commit # Runs lint-staged + typecheck before commit
├── .devcontainer/devcontainer.json
├── prompt.md # Example MVP prompt
│
├── src/ # Source code
│ ├── example.ts
│ └── example.test.ts
│
├── docs/ # Persistent design documents
│ ├── ideas/
│ │ └── initial-requirements.md # Brainstorming notes (pre-PRD)
│ └── design/ # UI/UX design spec (created by /define-design)
│ ├── design-brief.md
│ ├── design-tokens.json
│ ├── ui-blueprint.json # source of truth for UI
│ ├── platform-mapping.md
│ └── screens/*.svg # visual references only
│
├── .steering/ # Per-task steering files (created by /add-feature)
│ └── .gitkeep
│
└── .opencode/ # opencode configuration
├── agent/ # Subagent definitions
│ ├── doc-reviewer.md
│ └── implementation-validator.md
├── command/ # Slash commands
│ ├── setup-project.md
│ ├── define-design.md
│ ├── generate-app.md
│ ├── update-design.md
│ ├── add-feature.md
│ └── review-docs.md
└── skills/ # Task-specific skills
├── prd-writing/ (SKILL.md + template.md)
├── functional-design/ (SKILL.md + template.md + guide.md)
├── architecture-design/ (SKILL.md + template.md + guide.md)
├── repository-structure/ (SKILL.md + template.md + guide.md)
├── development-guidelines/(SKILL.md + template.md + guides/)
├── glossary-creation/ (SKILL.md + template.md + guide.md)
├── ui-design/ (SKILL.md)
├── design-tokens/ (SKILL.md)
├── platform-ui-generation/(SKILL.md)
└── steering/ (SKILL.md + templates/)
Configuration Overview
opencode.json
The main configuration file. Key sections:
{
"$schema": "https://opencode.ai/config.json",
"instructions": ["AGENTS.md"], // Loaded into every session
"permission": {
"skill": "allow", // Skills are auto-available
"bash": { // Common dev commands pre-approved
"*": "ask",
"npm *": "allow",
"npx *": "allow",
"git *": "allow",
// ...
}
}
}
After editing
opencode.json, quit and restart opencode — config is loaded once at startup.
AGENTS.md
The project memory file. opencode reads it on every session. It defines:
- The technology stack
- The spec-driven development principles
- The directory structure
- The development process and workflow
Agents (.opencode/agent/)
Subagents run in isolated contexts via the task tool. They don't consume the main session's context.
Commands (.opencode/command/)
Slash commands invoked in the opencode TUI with /command-name. Each command is a prompt template
that opencode executes.
Skills (.opencode/skills/)
Skills are loaded automatically based on their description field. You don't invoke them by name —
opencode surfaces the right skill when the task matches.
Usage Workflow
1. Initial project setup
Run the setup command to automatically create all six persistent design documents:
> /setup-project
This creates (automatically, end-to-end):
docs/product-requirements.md(PRD)docs/functional-design.mddocs/architecture.mddocs/repository-structure.mddocs/development-guidelines.mddocs/glossary.md
The PRD is based on the brainstorming notes in docs/ideas/initial-requirements.md. Edit that file
first if you have your own idea, or replace it.
2. Define the UI/UX design
> /define-design
Creates the design specification under docs/design/ (design brief, design tokens, UI blueprint,
platform mapping, and SVG wireframes). You'll be asked about target platform, visual style, main
screens, navigation, branding, and accessibility; if you don't specify, sensible defaults are proposed.
The design source of truth is docs/design/ui-blueprint.json. SVG files are visual references only.
3. Generate the app
> /generate-app web
> /generate-app flutter
> /generate-app winui3
Scaffolds the initial application for the selected target from the design spec — app shell, theme (from tokens), routes, screens, and reusable components. No feature logic is implemented here.
4. Add a feature
> /add-feature User authentication
This fully autonomous workflow:
- Creates
.steering/[YYYYMMDD]-[feature-name]/withrequirements.md,design.md,tasklist.md - Reads the design spec (
docs/design/) and updates it first if the feature changes the UI - Generates the steering files (planning mode of the steering skill)
- Implements every task in
tasklist.md, marking each[ ]→[x]as it goes - Launches the
implementation-validatorsubagent for quality review - Runs
npm test,npm run lint,npm run typecheck - Records a retrospective and reconciles all six persistent docs with the feature
5. Review a document
> /review-docs docs/product-requirements.md
Launches the doc-reviewer subagent to evaluate the document from five perspectives:
completeness, clarity, consistency, implementability, and measurability.
6. Day-to-day editing
You don't always need a command — just ask in normal conversation:
> Add a new feature to the PRD
> Review the performance requirements in architecture.md
> Add a new domain term to glossary.md
opencode loads the appropriate skill automatically.
Design & App Generation
Recommended workflow:
- Run
/setup-project - Run
/define-design - Review
docs/design/ - Run
/generate-app web,/generate-app flutter, or/generate-app winui3 - Use
/add-featureto add features - Use
/update-designwhenever a feature changes the UI
Source of truth:
- The design source of truth is
docs/design/ui-blueprint.json. - SVG files (
docs/design/screens/*.svg) are only visual references. - Generated UI should follow
docs/design/design-tokens.json— no hard-coded values. - No platform-specific implementation is generated before
/generate-appis executed.
See docs/design/README.md for the full structure.
Commands Reference
| Command | Description | Example |
|---|---|---|
/setup-project |
Create the six persistent documents automatically | /setup-project |
/define-design |
Create the UI/UX design spec under docs/design/ |
/define-design |
/generate-app |
Scaffold the initial app for a target platform | /generate-app web |
/update-design |
Update the design spec when a feature changes the UI | /update-design add a profile screen |
/add-feature |
Implement a feature end-to-end (autonomous) | /add-feature User profile editing |
/review-docs |
Detailed document review via subagent | /review-docs docs/architecture.md |
Skills Reference
| Skill | When it loads | Output |
|---|---|---|
prd-writing |
Creating a Product Requirements Document | docs/product-requirements.md |
functional-design |
Creating a functional design document | docs/functional-design.md |
architecture-design |
Designing the system architecture | docs/architecture.md |
repository-structure |
Defining the directory layout | docs/repository-structure.md |
development-guidelines |
Creating coding conventions / implementing code | docs/development-guidelines.md |
glossary-creation |
Creating a project glossary | docs/glossary.md |
ui-design |
Creating the design brief, UI blueprint, and SVG wireframes | docs/design/ files |
design-tokens |
Creating and maintaining design tokens | docs/design/design-tokens.json |
platform-ui-generation |
Converting design files into Web/Flutter/WinUI 3 code | generated app code |
steering |
Planning, implementing, and retrospecting on a task | .steering/[date]-[name]/ files |
Each skill folder contains a SKILL.md (instructions) plus template.md and/or guide.md (reference
material the skill points to).
Agents Reference
| Agent | Mode | Purpose |
|---|---|---|
doc-reviewer |
subagent | Reviews document quality across 5 dimensions; outputs a scored report with prioritized improvements |
implementation-validator |
subagent | Validates code against the spec; checks quality, test coverage, security, performance; runs lint/test/typecheck |
Agents are launched via the task tool (e.g., by the /add-feature and /review-docs commands).
They run in an isolated context window.
Customizing the Boilerplate
Change the model
Agents inherit the default model from opencode.json. To pin a specific model for a subagent, add
model to its frontmatter:
---
description: ...
mode: subagent
model: anthropic/claude-sonnet-4-6
---
Or set a global default in opencode.json:
{
"model": "anthropic/claude-sonnet-4-6"
}
Model IDs use the
provider/model-idformat. See https://opencode.ai/config.json for the full schema.
Adjust permissions
Edit the permission block in opencode.json. For example, to allow all bash commands:
{
"permission": { "bash": "allow" }
}
Add a new skill
- Create
.opencode/skills/my-skill/SKILL.md - Add frontmatter with
nameanddescription(the description controls when opencode loads it) - Add any companion
template.mdorguide.mdfiles - Restart opencode
Add a new command
- Create
.opencode/command/my-command.md - Add
descriptionfrontmatter + a prompt body (use$ARGUMENTSfor user input) - Restart opencode
Add a new agent
- Create
.opencode/agent/my-agent.md - Add
descriptionandmode: subagentfrontmatter + a prompt body - Restart opencode
Troubleshooting
opencode won't start after editing config
opencode validates opencode.json strictly and refuses to start on invalid fields. To recover:
# Skip the project config and start from globals only
OPENCODE_DISABLE_PROJECT_CONFIG=1 opencode
Then fix the broken file and restart normally.
Skills not loading
- Ensure each
SKILL.mdhas adescriptionin its frontmatter — skills without one are filtered out. - Ensure the folder name matches the
namefield. - Restart opencode after adding or changing skills.
Commands not appearing
- Command files must be directly inside
.opencode/command/(not in subdirectories). - Restart opencode after adding commands.
Dev Container: opencode command not found
The install script adds opencode to ~/.opencode/bin/ and updates your shell profile. If the command
isn't found in a new terminal:
export PATH="$HOME/.opencode/bin:$PATH"
opencode
Or create a permanent symlink:
sudo ln -sf "$HOME/.opencode/bin/opencode" /usr/local/bin/opencode
License
MIT — see LICENSE.