| title | spec-podcast-site |
|---|---|
| description | A modern podcast website built with Spec Kit and Spec-Driven Development |
This repository is a small static web app project used to practice
Spec-Driven Development with GitHub's
Spec Kit. The target application is a
modern podcast website for the fictional show Signal & Static, built as a
Next.js static export with embedded mock episode data.
The workflow starts with intent, turns that intent into a constitution and feature specification, then keeps iterating through plan, tasks, and implementation. The aim is to make design decisions explicit before writing the app code.
Important
Start with the project wiki. It explains the why behind this repo, not just the how. In particular, read the Methodology Comparison, which contrasts three ways of organizing software work:
- Classic DevOps / Azure DevOps — Epic → Feature → Story → Task
- Spec-Driven Development (SDD) — the loop this repo follows
- RPI (Research → Plan → Implement) from HVE-core engineering
The comparison shows where each approach fits and how they compose, and makes the case for choosing SDD on a greenfield project like this one.
| Page | What it covers |
|---|---|
| Home | Overview and navigation |
| Getting Started | Install Spec Kit, run and validate locally |
| Spec-Driven Development | The SDD loop and its artifacts |
| Why Spec-Driven Development | Rationale, benefits, and trade-offs |
| Methodology Comparison | Classic DevOps vs SDD vs RPI |
| Architecture | Tech choices, routes, and content model |
| Project Constitution | The non-negotiable principles |
| Testing and Validation | The checks that guard the spec |
Install the specify CLI from the Spec Kit repository:
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@v0.11.1Verify the command is available:
specify --helpCreate a new Spec Kit project with:
specify init spec-podcast-siteThat initialization creates the .specify/ workspace, prompt files, templates,
and integration hooks used by the rest of the workflow.
The constitution captures the non-negotiable rules for the project. For this static podcast site, the constitution requires:
- Static output that can be hosted without a custom server
- Source-controlled content and configuration
- Accessibility by default
- Deterministic, lightweight delivery
- Minimal dependencies and tooling
Current constitution: .specify/memory/constitution.md
Use this loop for each feature:
- Specify the feature
/speckit.specify Describe the feature in product termsOutput: a feature spec under specs/<feature>/spec.md.
- Clarify and refine the spec
Resolve open questions directly when the reasonable default is clear. Update the requirements checklist so the spec is ready for planning.
- Plan the feature
/speckit.plan Describe the technical approach and constraintsOutput: plan.md, research.md, data-model.md, quickstart.md, and
route or API contracts.
- Add implementation tasks
/speckit.tasksOutput: tasks.md, organized by user story so work can proceed in small,
testable slices.
- Implement the plan
/speckit.implementThe implementation follows the generated tasks, validates each slice, and keeps changes aligned with the constitution and plan.
- Iterate
Repeat the cycle for new features or significant changes. Update specs and plans before changing implementation behavior.
The active feature is the modern podcast site:
- specs/001-modern-podcast-site/spec.md
- specs/001-modern-podcast-site/plan.md
- specs/001-modern-podcast-site/research.md
- specs/001-modern-podcast-site/data-model.md
- specs/001-modern-podcast-site/contracts/site-routes.md
- specs/001-modern-podcast-site/quickstart.md
The planned app uses Next.js App Router with static export, no database, no runtime API, and 20 embedded mock podcast episodes.
Install dependencies once, then use the npm scripts.
npm install
npm run devThe development server runs at http://localhost:3000.
app/holds the App Router routes:/,/episodes,/about, and/faq. The/episodespage offers in-browser keyword search and category filtering with a live result count and a single reset control (no network calls). Each episode also has its own static detail page at/episodes/<slug>/, and an unmatched address resolves to a friendly not-found page (app/not-found.tsx).src/components/holds shared UI components.src/content/holds the typed, source-controlled content: podcast profile, 20 episodes (one featured), and FAQ items.src/styles/globals.cssholds the design tokens and responsive styles.public/assets/holds the static artwork.tests/holds the Playwright content, accessibility, and responsive suites.
npm run type-check # TypeScript, no emit
npm run lint # ESLint flat config
npm run build # static export to out/
npm run test:e2e # responsive navigation and content contract
npm run test:a11y # axe accessibility scan of all four pagesnpm run build emits a fully static bundle to out/ with one index.html
per route. The site has no server runtime, no live feed, and no secrets in the
client bundle. Episode actions are mocked in-page rather than linking out.