Skip to main content
The GitHub Copilot Agent Toolkit is built around three core components that work together to accelerate development: Agents for structured workflows, Skills for domain-specific guidance, and a Demo App that showcases best practices.

Design Principles

The toolkit is designed with these goals:
  1. Small, Reviewable Changes: Agents and skills guide Copilot to make minimal, focused edits
  2. Consistent Patterns: Reusable conventions across components, features, and state management
  3. Spec-Driven Development: Multi-phase planning before implementation
  4. Decoupled Architecture: Clear separation between UI primitives, compositions, and domain logic

Three Main Components

1. Agents (Planning & Workflow)

Agents are multi-phase workflows stored in .github/agents/. They guide GitHub Copilot through structured feature development:
.github/agents/
├── requirements.agent.md  # Phase 1: Gather and document requirements
├── plan.agent.md          # Phase 2: Create technical design
└── task.agent.md          # Phase 3: Break down into tasks
How it works:
1

Requirements Phase

The Requirements Agent clarifies the feature, captures user stories, defines acceptance criteria (using EARS syntax), and identifies constraints. It produces a requirements document under specs/features/{NNN}-{feature-name}/requirements.md.
2

Plan Phase

The Plan Agent converts approved requirements into technical design decisions: component structure, state management approach, API contracts, and integration points.
3

Task Phase

The Task Agent breaks the approved design into an ordered, implementation-ready task list with file paths and verification steps.
Each agent is phase-scoped: it only produces its own artifact and never jumps ahead to implementation. This prevents rework and ensures stakeholder alignment at each stage.

2. Skills (Domain Expertise)

Skills are reusable knowledge modules stored in .github/skills/. They provide best practices for specific technologies and patterns:
.github/skills/
├── react-best-practices/      # React composition patterns
├── next-best-practices/       # Next.js App Router conventions
├── ui-components/             # shadcn/ui and Tailwind guidance
├── vercel-composition-patterns/  # Component composition strategies
├── zustand/                   # State management patterns
└── web-project-conventions/   # File structure and naming
Example: Zustand Skill The Zustand skill enforces the decoupled actions pattern:
// ✅ Correct: State in store, actions as plain functions
import { create } from 'zustand';

interface ProjectState {
  projects: Project[];
  selectedId: string | null;
}

const store = create<ProjectState>(() => ({
  projects: [],
  selectedId: null,
}));

// Actions are plain functions, not in the store
export const selectProject = (id: string) => {
  store.setState({ selectedId: id });
};

export const useProjects = () => store(state => state.projects);
This pattern keeps components from re-rendering when actions change and makes testing easier.

3. Demo App (Reference Implementation)

The web/ directory contains a working Next.js application that demonstrates toolkit patterns:
web/
├── app/                 # Next.js App Router (routes only)
   ├── layout.tsx      # Root layout with providers
   ├── page.tsx        # Routes render feature components
   └── globals.css     # Global styles and CSS variables
├── components/
   ├── ui/             # Primitives (Button, Card, Heading)
   ├── blocks/         # Compositions (ThemeProvider, ThemeToggle)
   └── lib/            # Utilities (cn helper, etc.)
├── features/
   ├── home/           # Home feature (HomePage component)
   └── shared/         # Cross-feature code (API clients, auth)
└── public/             # Static assets
Dependency Direction:
Features → Components (UI, Blocks) → Shared
         → Stores (Zustand)
         
✅ Features import from components and shared
✅ Blocks compose UI primitives
❌ Components never import from features
❌ Features don't cross-import (use shared instead)

Tech Stack Decisions

Bun serves as both runtime and package manager:
  • Faster installs than npm/yarn/pnpm
  • Native TypeScript execution
  • Built-in bundler and test runner
  • Drop-in Node.js replacement
All scripts in package.json use bun commands:
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "lint": "oxlint",
    "format": "oxfmt"
  }
}
The App Router provides:
  • Server Components by default (better performance)
  • Streaming and Suspense built-in
  • Simplified data fetching
  • File-based routing with layouts
Route modules stay thin by rendering feature components:
app/page.tsx
import { HomePage } from "@/features/home/home-page";

export default function Home() {
  return <HomePage />;
}
shadcn/ui is not a package dependency—it’s a collection of copy-paste components:
  • Built on Base UI primitives (accessible by default)
  • Full TypeScript support
  • Tailwind-based styling
  • Customizable (you own the code)
Components live in web/components/ui/ and use class-variance-authority (CVA) for variants:
const buttonVariants = cva(
  "inline-flex items-center justify-center...",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        outline: "border-border bg-background",
        ghost: "hover:bg-muted",
      },
      size: {
        default: "h-9 px-2.5",
        sm: "h-8 px-2.5",
        lg: "h-10 px-3",
      },
    },
  }
);
Zustand with the decoupled actions pattern provides:
  • No hook for actions (avoids re-renders)
  • Plain functions (easy to test)
  • Tree-shakeable (unused actions removed from bundle)
  • TypeScript-first
This pattern is enforced by the Zustand skill:
// Store: state only
const store = create<State>(() => ({ count: 0 }));

// Actions: plain functions outside the store
export const increment = () => {
  store.setState(s => ({ count: s.count + 1 }));
};

// Selectors: atomic, granular
export const useCount = () => store(s => s.count);
oxlint and oxfmt replace ESLint and Prettier:
  • Written in Rust (10-100x faster)
  • Zero config needed
  • Compatible with existing rules
  • Bun-native execution
Run from the repo root:
bun run lint    # oxlint for linting
bun run format  # oxfmt for formatting

How the Pieces Fit Together

Here’s a typical workflow using all three components:
1

Run the Requirements Agent

Define what to build:
@requirements Create a user dashboard with profile stats
The agent researches existing patterns (using skills), clarifies goals with you, and produces specs/features/001-user-dashboard/requirements.md.
2

Run the Plan Agent

Create the technical design:
@plan specs/features/001-user-dashboard/requirements.md
The agent consults skills (React, Next.js, Zustand) to design:
  • Component hierarchy (features/dashboard/)
  • State management approach (Zustand store)
  • UI components (reuse existing shadcn/ui primitives)
3

Run the Task Agent

Generate implementation tasks:
@task specs/features/001-user-dashboard/plan.md
The agent produces an ordered task list with file paths and verification steps.
4

Implement with Copilot

As you work through tasks, Copilot uses skills to:
  • Create components following web-project-conventions
  • Build UI with ui-components guidance
  • Manage state using zustand patterns
  • Apply react-best-practices and next-best-practices
Skills are always available to Copilot during implementation. Agents reference skills during planning, and Copilot applies them during coding.

Quality Standards

The toolkit enforces quality through both automation and guidance: Automated Checks:
  • Type checking: tsc --noEmit
  • Linting: bun run lint (oxlint)
  • Formatting: bun run format (oxfmt)
Guidance from AGENTS.md:
## Golden Rules
- Make small, correct, reviewable changes
- Keep diffs minimal; don't refactor unrelated code
- Prefer existing repo patterns over general best practices
- Don't add dependencies unless clearly necessary
- Use Bun-native APIs where possible
All agents and skills reinforce these rules to keep changes focused and consistent.

Next Steps

Build Your First Feature

Use the 3-phase agent workflow to create a new feature

Work with UI Components

Learn shadcn/ui conventions and component placement rules

Manage State

Master the Zustand decoupled actions pattern

Explore Skills

Browse all available skills for React, Next.js, and more

Build docs developers (and LLMs) love