Skip to content

GrowthForms Workshop

GrowthForms: Building a TypeForm Competitor

Section titled “GrowthForms: Building a TypeForm Competitor”

Saturday 17th January 2026 | 10am UK

Build a complete form builder from scratch using spec-driven development. No drag-and-drop interfaces. No templates. Just Claude Code and a structured approach that scales.


GrowthPath Consulting Ltd has been using TypeForm to collect customer feedback and capture leads. But Hodl McDougall (the Honey Badger CEO) is fed up with the subscription costs.

“Three hundred quid a year for what’s basically a form connected to a database?” Hodl grumbled during the Monday stand-up. “We’ve been learning Claude Code for weeks now. Surely we can build our own?”

Flora McCombie needs the customer details form for lead capture. Angus Chalmers wants a feedback form for service improvement. The challenge is set: build GrowthForms in a single session.


GrowthForms UI Wireframe

GrowthForms - A TypeForm-style form builder with:

  • Form creation - Build multi-question forms without code
  • Multiple form types - Customer details, feedback, surveys
  • Local storage - All data persists in the browser
  • Clean UI - ShadCN components for a polished look
TechnologyPurpose
React + ViteFast development, hot reload
ShadCN/UIPre-built accessible components
localStorageBrowser-based persistence
TypeScriptType safety and autocompletion

Instead of drag-and-drop form building, we use Claude Code to build forms from specifications. This approach:

  1. Scales better - Specs can describe complex forms that would take ages to configure manually
  2. Is reproducible - Same spec, same result, every time
  3. Teaches transferable skills - The spec-driven workflow applies to any project

Spec-Driven Development Workflow

Each cycle follows the same pattern:

  1. PRD - The north star document describing the overall product
  2. User Story - A specific feature we’re building this cycle
  3. /specify - Generate a detailed specification from the user story
  4. /plan - Create an implementation plan from the spec
  5. /tasks - Break the plan into actionable tasks
  6. /implement - Execute the tasks with Claude Code
  7. Validate - Test the result, fix any issues

Speckit is the tool that powers our spec-driven workflow. It provides slash commands that integrate with Claude Code.

Install speckit globally using uv:

uv tool install specify-cli --from git+https://github.com/github/spec-kit.git

Navigate to where you want to create GrowthForms and run:

specify init growthforms --ai claude

This creates the project structure with speckit configuration.

If you already have a folder, use --here:

cd growthforms
specify init . --here --ai claude

Check everything is working:

specify check

Once initialised, these slash commands are available in Claude Code:

CommandPurpose
/speckit.constitutionSet up project principles (British English, TDD, etc.)
/speckit.specifyGenerate detailed spec from user story
/speckit.planCreate implementation plan from spec
/speckit.tasksBreak plan into actionable task list
/speckit.implementExecute all tasks
/speckit.clarifyRefine unclear requirements
/speckit.analyzeValidate consistency across artifacts

GrowthForms Architecture

Today’s build is entirely client-side. All form data lives in localStorage. In Week 3, we’ll add Supabase for proper persistence and multi-user support.


Throughout this workshop, you’ll see five techniques that make spec-driven development powerful:

Create a north star document for the project. Every feature references back to the PRD. When in doubt, ask: “Based on the PRD, what should we build next?“

A constitution encodes your project’s principles:

  • British English (colour, organisation)
  • Never use em dashes
  • Vertical slice development
  • Always use TDD

These rules persist across sessions and keep Claude Code consistent.

The CLAUDE.md file tells Claude Code about:

  • Tech stack and versions
  • Project structure
  • Commands to run
  • Reference docs for specific task types

After planning, output a structured plan document. Clear context before execution. Feed only the plan into the implementation phase. This prevents confusion and keeps Claude Code focused.

Every bug is an opportunity to strengthen the system. Don’t just fix the bug - update rules, commands, or reference docs to prevent it recurring.


Before we write any code, we need a Product Requirements Document. This is the “north star” that guides every decision.

📄 View the full PRD on GitHub →

The PRD covers:

  • Problem statement (why we’re building this)
  • User personas (Flora and Angus)
  • Functional requirements
  • Technical stack
  • Success criteria

📋 View full spec on GitHub →

Goal: Set up React + Vite + ShadCN + localStorage foundation

As a developer, I want a working React app with ShadCN components and localStorage persistence so I can build forms on top of it.

  • Vite project with React and TypeScript
  • ShadCN/UI component library installed
  • Basic layout with header and sidebar
  • localStorage helper functions

Why Vite over Create React App?

Vite is significantly faster for development. Hot module replacement is nearly instant, and the build process is optimised for modern browsers. Create React App has been deprecated in favour of frameworks like Next.js, but for a client-side app like this, Vite is the sweet spot.

Why ShadCN over other component libraries?

ShadCN isn’t a traditional component library - it’s a collection of components you copy into your project. This means:

  • Full control over the code
  • No version conflicts
  • Easy customisation
  • Smaller bundle size (only include what you use)

localStorage considerations

localStorage is synchronous and blocks the main thread. For our use case (small amounts of form data), this is fine. For larger applications, you’d consider IndexedDB or a proper database.


📋 View full spec on GitHub →

Goal: Sidebar with dropdown listing saved forms

As a user, I want to see all my forms in a sidebar dropdown so I can switch between them easily.

  • Collapsible sidebar component
  • Form list fetched from localStorage
  • Create new form button
  • Active form highlighting

Form List Architecture

Component composition in React

We’re building small, focused components that compose together. The sidebar doesn’t know about forms - it just renders what it’s given. The form list doesn’t know about the sidebar - it just displays items. This separation makes testing easier and components more reusable.

State management decisions

For a small app like this, React’s built-in useState and useContext are sufficient. Redux or Zustand would be overkill. The rule: start simple, add complexity only when pain points emerge.

Accessibility in navigation

ShadCN components come with ARIA labels and keyboard navigation built in. The dropdown is accessible by default - you can navigate with Tab and Arrow keys, and screen readers announce the state correctly.


📋 View full spec on GitHub →

Goal: End-to-end form with name, email, phone, company fields

As Flora (Customer Success), I want to create a customer details form that collects name, email, phone, and company information so I can capture leads for GrowthPath.

Flora’s lead capture form with:

  • Full name field (required)
  • Email address field (required, validated)
  • Phone number field (optional)
  • Company name field (optional)
  • Submit button with loading state
  • Success confirmation

Customer Details Form Flow

Form validation approaches

There are several ways to validate forms in React:

  • Native HTML5 validation - Built into browsers, limited customisation
  • Controlled components with manual validation - Full control, more code
  • Libraries like React Hook Form or Formik - Powerful but adds dependencies

For this workshop, we’ll use controlled components with ShadCN’s form components, which provide a good balance of control and convenience.

Email validation regex

The “correct” email regex is notoriously complex. For practical purposes, checking for an @ symbol and a dot in the domain is usually sufficient. The best validation is sending a confirmation email.

UX for optional fields

Marking required fields with asterisks is common but not always clear. We’ll label optional fields explicitly - “(optional)” - which research shows improves completion rates.


📋 View full spec on GitHub →

Goal: End-to-end form with rating, comments, NPS score

As Angus (Operations), I want to create a feedback form with star rating, comments, and NPS score so I can measure customer satisfaction with GrowthPath’s services.

Angus’s service feedback form with:

  • Star rating (1-5, required)
  • Comments text area (optional)
  • NPS score (0-10, required)
  • Submit with validation
  • Thank you message

Feedback Form Flow

Star ratings UX

Star ratings seem simple but have nuances:

  • Should clicking star 3 select stars 1-3, or just star 3?
  • How do you handle half stars?
  • What’s the hover state?

We’ll implement the most common pattern: clicking star 3 fills stars 1-3, hover preview shows what would be selected.

NPS (Net Promoter Score)

NPS asks: “How likely are you to recommend us to a friend or colleague?” on a 0-10 scale.

  • Promoters (9-10) - Loyal enthusiasts
  • Passives (7-8) - Satisfied but unenthusiastic
  • Detractors (0-6) - Unhappy customers

NPS = % Promoters - % Detractors

It’s a controversial metric (critics say it’s oversimplified) but widely used because it’s easy to benchmark.

Text area sizing

Long text inputs should grow with content up to a maximum height, then scroll. This prevents the jarring experience of a tiny box that scrolls immediately.


Coming Up in Week 3: Project Management Tool

Section titled “Coming Up in Week 3: Project Management Tool”

We’ll build a Monday.com-style project board, introducing:

  • Supabase - PostgreSQL database with real-time subscriptions
  • Drag and drop - React DnD for kanban boards
  • Multiple users - Shared project state

The GrowthForms data model translates well to a database - we’ll migrate the localStorage approach to Supabase.

The capstone build: a HubSpot-style CRM with:

  • Authentication - User accounts and sessions
  • Contacts and deals - Full CRUD operations
  • Pipeline views - Visual deal progression
  • Search - Full-text search across records

Four weeks, four tools. Each one builds on the previous.


Track progress through each cycle on the Kanban board:

📊 GrowthForms Project Board →

Columns: Specify → Plan → Tasks → Implement → Validate → Done

CycleIssueDescription
PRD#1Product Requirements Document
1#2Infrastructure Setup
2#3Navigation System
3#4Customer Details Form
4#5Feedback Form

We’ll create this repo live during the workshop. The finished code will be pushed to:

github.com/highlandhodl/growthforms (created during stream)


The recording will be posted here after the livestream.


All streams are recorded and uploaded to YouTube within a few hours. Subscribe to get notified when recordings are available.

Subscribe to @coengineers on YouTube →

The live experience is better though - you can ask questions and see the debugging in real time.