OpenSpec: the specification is Markdown, and the assistant writes it
OpenSpec structures requirements and change proposals so coding assistants can implement and verify work against an explicit specification.
At a glance
- What is it?
- OpenSpec makes a coding assistant produce a change proposal as four files before any code exists. The format has no special syntax, the command spelling changes per editor, and the cross-repository answer is still labelled beta.
- Who is it for?
- OpenSpec earns its place when the failure mode you are worried about is an assistant building the wrong thing confidently, because it forces a written artifact to exist before code and keeps that artifact in version control next to the code. Three things decide whether it fits your setup.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 26, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Verification sits in the expanded profile, not the default one
OpenSpec is described as structuring requirements and change proposals so coding assistants can implement and verify work against an explicit specification. The default profile delivers two commands: `/opsx:explore`, a no-stakes thinking partner that reads your code, weighs options and shapes a plan before anything is written, and `/opsx:propose <what-you-want-to-build>` for when you already know what you want. Everything else is opt-in.
The expanded set is `/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive` and `/opsx:onboard`, and you select it with `openspec config profile` before applying it with `openspec update`. That list contains the command named `verify`, which is the part of the promise most teams care about, and it is not what you get after `openspec init`. The consequence is that the propose half of the workflow is the default experience while the checking half needs two extra commands, so a team that reads the headline and stops there gets artifacts and no automated verification pass.
The same command has four spellings depending on your editor
`/opsx:propose` is the canonical name, and `openspec init` prints the form your tools expect. The variants are not cosmetic. Cursor and GitHub Copilot spell it `/opsx-propose`, Amazon Q uses `@opsx-propose`, and Codex uses `$openspec-propose`, with the project claiming support for 30 or more tools and growing.
The consequence is that a team on mixed editors runs the same workflow under two or three names, and anything that is not a human at a keyboard inherits the problem. A CI job, a shell script, a review checklist or a wiki page that tells someone to run `/opsx:propose` is wrong for at least one person in the room, and nothing in the repository corrects it at read time. `openspec init` is the only place the right spelling is guaranteed to be right for the tools you picked, which makes it worth keeping in the setup step rather than treating as boilerplate.
A change is four files in a directory, and the directory is the review unit
Running `/opsx:propose` creates `openspec/changes/<name>/` and fills it with four artifacts. `proposal.md` covers why the work is happening and what is changing, `specs/` holds the requirements and scenarios, `design.md` records the technical approach, and `tasks.md` is the implementation checklist. Later commands move through them, and an archive step exists to retire a change once it is done.
The consequence is a change of significant size before the first line of code. For work where the shape was already settled, that is overhead paid for a guarantee you did not need. For work where the shape was not settled, it is the whole point, because the disagreements that usually surface during implementation get argued over a document instead. The practical discipline this imposes is that the four documents have to stay in step, and nothing in the format mechanically checks that the tasks list matches the scenarios in the spec.
The specification is plain Markdown with SHALL, WHEN and THEN
There is no special syntax to learn. A requirement is a heading, a sentence using SHALL, and a scenario with WHEN and THEN lines, and this is the whole of it:
## ADDED Requirements
### Requirement: Theme selection
The app SHALL let users switch between light and dark themes,
defaulting to the system preference.
#### Scenario: User toggles dark mode
- **WHEN** the user clicks the theme toggle
- **THEN** the app switches to dark mode and persists the choicePlain Markdown is the reason this survives contact with a real repository: it diffs, it reviews, and a human reads it without training. The cost is that nothing enforces it. The README says the AI writes these and you review the plan before any code is written, which puts the entire quality gate on that review. A requirement phrased as a wish rather than an observable behaviour produces a scenario that cannot fail, and no tool will tell you so.
Stores is the cross-repository answer, and Stores is in beta
The pitch for teams is that the hard part moves. A feature spans an API server, a web app and a shared library, requirements are owned by one team and consumed by another, and planning starts before any code exists. Stores is the proposed answer: planning in a repository of its own, using the same `openspec/` shape of specs and changes, shared by `git push` like anything else.
The stated benefits are one change and one plan even when code lands in three repositories, a platform team owning specs that product teams reference read-only instead of a wiki that drifts, and capturing the plan before the code repos catch up. The label attached to all of it is beta, with a user guide under `docs/stores-beta/`. The consequence is direct: the single-repository workflow is the supported path, and the scenario most likely to draw a team in, features crossing several repos, is the part still marked experimental.
Node 20.19 is the floor, and the package ships prebuilt
The npm package is `@fission-ai/openspec`, MIT licensed, ESM, and it declares `node: >=20.19.0` in its engines field. Installation is a global install or the Homebrew formula:
npm install -g @fission-ai/openspec@latest
brew install openspecThen you initialise inside the project with `cd your-project` and `openspec init`. The published tarball carries `dist`, `bin` and `schemas`, and the single binary is `openspec`, pointing at `bin/openspec.js`, with the main export resolving to `dist/index.js`. A build step runs on `prepare` and again before publishing, so nobody installing the package compiles TypeScript.
The consequence is a hard runtime floor rather than a soft preference: anything on an older Node has to upgrade before the CLI will run, which matters most in a container base image you do not control. In exchange there is no build toolchain in the consuming project, and the alternative install paths cover pnpm, yarn, bun and Nix.
Releases check the packed version, then publish through changesets
The release path is `release:ci`, which runs `check:pack-version` and then `changeset publish`, with a `.changeset/` directory in the repository and a `regen:parity-hashes` script alongside it. Tests are Vitest, with a `vitest.setup.ts` and coverage and UI variants, linting is ESLint, and the package manager is pinned to pnpm 10.34.5, with `flake.nix` and `flake.lock` for Nix users.
The recent release titles describe what has been changing. v1.13.0 on 2026-09-09 was Apply warnings, safer archives, v1.13.1 on 2026-09-17 was Hardened CLI, safer archives, and v1.13.2 on 2026-09-23 was Verify and Windows archive fixes. Three releases in two weeks, two of them about archive handling and one about Windows, is a project correcting itself in public rather than coasting. The consequence for an adopter is that the current release notes are the most useful document in the repository, and that if you depend on archive or Windows behaviour you should read those three entries before pinning a version.
Editorial conclusion
OpenSpec earns its place when the failure mode you are worried about is an assistant building the wrong thing confidently, because it forces a written artifact to exist before code and keeps that artifact in version control next to the code. Three things decide whether it fits your setup. The verify workflow is not in the default profile, so the checking half of the promise is opt-in. The slash command has a different spelling in every editor, which breaks any automation that hardcodes it. And Stores, the feature that addresses multi-repository features and platform-owned requirements, is in beta. Before adopting it, run one real change end to end and check three things: whether you turn on the expanded profile, which command spelling your tools need, and how you will review specifications the assistant generated.
Frequently asked questions
What does OpenSpec do?
It structures requirements and change proposals so a coding assistant implements and verifies work against an explicit specification. Running `/opsx:propose` creates a directory under `openspec/changes/` containing proposal.md, a specs folder of requirements and scenarios, design.md and tasks.md, all before any code is written.
How do I install OpenSpec?
You need Node.js 20.19.0 or higher. Install it with `npm install -g @fission-ai/openspec@latest` or, on macOS or Linux, `brew install openspec`, then run `openspec init` in your project directory. A setup prompt is also provided for assistants to run the steps for you.
How do I use OpenSpec explore?
`/opsx:explore` is a no-stakes thinking partner that reads your code, weighs options and shapes a plan before any code gets written. It ships in the default profile alongside `/opsx:propose`, so it is available immediately after `openspec init`.
How do I use OpenSpec with Claude Code?
The canonical command is `/opsx:propose`, and the spelling depends on your tool: Cursor and GitHub Copilot use `/opsx-propose`, Amazon Q uses `@opsx-propose` and Codex uses `$openspec-propose`. The README does not give a separate spelling for any particular assistant, and `openspec init` prints the correct form for the tools you selected.
Who owns OpenSpec?
The package is published as `@fission-ai/openspec` under the MIT license with the author field set to OpenSpec Contributors, and the code lives in the Fission-AI GitHub organisation. The repository root carries MAINTAINERS.md, CONTRIBUTING.md, SECURITY.md and a CHANGELOG.md, and releases are published through changesets.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/fission-ai-openspec)