GitHub Copilot Integration
VDK integration with GitHub's AI-powered coding assistant through VS Code workspace configuration
GitHub Copilot Integration
GitHub Copilot is GitHub's AI-powered coding assistant that provides intelligent code suggestions. VDK CLI integrates with GitHub Copilot through VS Code workspace configuration and JSON-based guideline files to enhance its project awareness.
Overview
GitHub Copilot integration creates:
- JSON Guidelines:
.github/copilot/
directory with structured configuration files - VS Code Workspace: Enhanced workspace settings for Copilot
- Custom Instructions: Project-specific coding guidelines and patterns
- Context Enhancement: Rich project context for better suggestions
Setup
Prerequisites
- VS Code with GitHub Copilot extension
- GitHub Copilot subscription
- VDK CLI installed and configured
Automatic Setup
# Initialize VDK with GitHub Copilot integration
vdk init --ide-integration
# Or setup GitHub Copilot specifically
vdk integrations --setup github-copilot
Manual Setup
# Check if GitHub Copilot is detected
vdk integrations --scan
# Setup GitHub Copilot integration
vdk integrations --setup github-copilot
# Verify setup
vdk integrations --list
Generated Files
.github/copilot/
Directory Structure
.github/
└── copilot/
├── instructions.json # Main Copilot instructions
├── guidelines.json # Coding guidelines
├── patterns.json # Code patterns and examples
├── technologies.json # Technology-specific rules
└── workspace.json # Workspace configuration
Instructions File (.github/copilot/instructions.json
)
{
"version": "2.0.1",
"name": "Next.js Project Instructions",
"description": "GitHub Copilot instructions for Next.js TypeScript project",
"created": "2024-01-15T10:30:00Z",
"updated": "2024-01-15T10:30:00Z",
"project": {
"name": "my-nextjs-app",
"type": "web-application",
"framework": "nextjs",
"language": "typescript",
"description": "Next.js 15 application with TypeScript, Tailwind CSS, and Prisma"
},
"context": {
"overview": "This is a Next.js 15 application using the App Router architecture with TypeScript for type safety, Tailwind CSS for styling, and Prisma as the ORM for PostgreSQL database operations.",
"architecture": "App Router with server components by default, client components only when needed for interactivity",
"patterns": [
"Server-first architecture",
"Component-based design",
"Feature-based organization",
"Type-safe API development"
]
},
"technologies": {
"frontend": {
"framework": "Next.js 15",
"language": "TypeScript 5.0+",
"styling": "Tailwind CSS",
"stateManagement": "Zustand",
"testing": "Jest + React Testing Library"
},
"backend": {
"runtime": "Node.js 18+",
"database": "PostgreSQL",
"orm": "Prisma",
"authentication": "NextAuth.js"
},
"tooling": {
"packageManager": "pnpm",
"linting": "ESLint + Prettier",
"typeChecking": "TypeScript strict mode",
"deployment": "Vercel"
}
},
"instructions": [
"Always use TypeScript with proper type definitions",
"Prefer server components over client components",
"Use Tailwind CSS utility classes for styling",
"Follow the established file naming conventions",
"Implement proper error handling and loading states",
"Use absolute imports with @/ prefix",
"Include proper JSDoc comments for complex functions",
"Follow the repository pattern for data access"
]
}
Guidelines File (.github/copilot/guidelines.json
)
{
"version": "2.0.1",
"name": "Coding Guidelines",
"description": "Project-specific coding standards and conventions",
"guidelines": {
"typescript": {
"strictMode": true,
"noImplicitAny": true,
"preferInterfaces": true,
"naming": {
"interfaces": "PascalCase",
"types": "PascalCase",
"functions": "camelCase",
"constants": "UPPER_CASE"
},
"examples": {
"interface": {
"description": "Define component props with proper TypeScript interfaces",
"code": "interface UserCardProps {\n user: {\n id: string;\n name: string;\n email: string;\n };\n onEdit?: (user: User) => void;\n}"
},
"component": {
"description": "React component with TypeScript",
"code": "export default function UserCard({ user, onEdit }: UserCardProps) {\n return (\n <div className=\"p-4 border rounded-lg\">\n <h3 className=\"text-lg font-semibold\">{user.name}</h3>\n <p className=\"text-gray-600\">{user.email}</p>\n </div>\n );\n}"
}
}
},
"react": {
"preferServerComponents": true,
"useClientDirective": "Only when necessary for interactivity",
"componentStructure": {
"interfaces": "Define props interface first",
"hooks": "Hooks at the top of component",
"handlers": "Event handlers after hooks",
"earlyReturns": "Handle loading/error states early",
"mainRender": "Main JSX at the bottom"
},
"examples": {
"serverComponent": {
"description": "Next.js server component with data fetching",
"code": "import { getUsers } from '@/lib/api/users';\n\nexport default async function UsersPage() {\n const users = await getUsers();\n \n return (\n <div>\n <h1>Users</h1>\n {users.map(user => (\n <UserCard key={user.id} user={user} />\n ))}\n </div>\n );\n}"
},
"clientComponent": {
"description": "Client component with state and interactivity",
"code": "'use client'\n\nimport { useState } from 'react';\n\ninterface CounterProps {\n initialCount?: number;\n}\n\nexport default function Counter({ initialCount = 0 }: CounterProps) {\n const [count, setCount] = useState(initialCount);\n \n return (\n <button\n onClick={() => setCount(c => c + 1)}\n className=\"px-4 py-2 bg-blue-500 text-white rounded\"\n >\n Count: {count}\n </button>\n );\n}"
}
}
},
"nextjs": {
"appRouter": true,
"fileConventions": {
"pages": "page.tsx",
"layouts": "layout.tsx",
"loading": "loading.tsx",
"error": "error.tsx",
"notFound": "not-found.tsx"
},
"routing": {
"dynamicRoutes": "[id]",
"routeGroups": "(auth)",
"catchAll": "[...slug]"
},
"examples": {
"apiRoute": {
"description": "API route with proper error handling",
"code": "import { NextRequest, NextResponse } from 'next/server';\nimport { z } from 'zod';\n\nconst schema = z.object({\n name: z.string().min(1),\n email: z.string().email()\n});\n\nexport async function POST(request: NextRequest) {\n try {\n const body = await request.json();\n const data = schema.parse(body);\n \n const user = await createUser(data);\n return NextResponse.json(user, { status: 201 });\n } catch (error) {\n if (error instanceof z.ZodError) {\n return NextResponse.json(\n { error: 'Validation failed' },\n { status: 400 }\n );\n }\n return NextResponse.json(\n { error: 'Internal server error' },\n { status: 500 }\n );\n }\n}"
}
}
},
"styling": {
"framework": "Tailwind CSS",
"approach": "Utility-first",
"responsive": "Mobile-first design",
"conventions": {
"spacing": "Use Tailwind spacing scale",
"colors": "Use design system colors",
"typography": "Use Tailwind typography utilities"
},
"examples": {
"card": {
"description": "Card component with Tailwind styling",
"code": "<div className=\"p-6 bg-white rounded-lg border border-gray-200 shadow-sm hover:shadow-md transition-shadow\">\n <h3 className=\"text-lg font-semibold text-gray-900 mb-2\">{title}</h3>\n <p className=\"text-gray-600\">{description}</p>\n</div>"
}
}
}
}
}
Patterns File (.github/copilot/patterns.json
)
{
"version": "2.0.1",
"name": "Code Patterns",
"description": "Common code patterns and architectural decisions",
"patterns": {
"dataFetching": {
"name": "Data Fetching Patterns",
"description": "How to fetch and handle data in different contexts",
"examples": [
{
"name": "Server Component Data Fetching",
"context": "Server components in app/ directory",
"pattern": "async function with direct database/API calls",
"code": "export default async function UserPage({ params }: { params: { id: string } }) {\n const user = await prisma.user.findUnique({\n where: { id: params.id }\n });\n \n if (!user) {\n notFound();\n }\n \n return <UserProfile user={user} />;\n}"
},
{
"name": "Client Component Data Fetching",
"context": "Client components needing reactive data",
"pattern": "React Query with custom hooks",
"code": "function useUser(id: string) {\n return useQuery({\n queryKey: ['user', id],\n queryFn: () => fetchUser(id),\n enabled: !!id\n });\n}\n\nexport default function UserProfile({ id }: { id: string }) {\n const { data: user, isLoading, error } = useUser(id);\n \n if (isLoading) return <LoadingSpinner />;\n if (error) return <ErrorMessage error={error} />;\n \n return <div>{user?.name}</div>;\n}"
}
]
},
"formHandling": {
"name": "Form Handling Patterns",
"description": "Server actions and client-side form handling",
"examples": [
{
"name": "Server Action Form",
"context": "Forms with server-side processing",
"pattern": "Server actions with revalidation",
"code": "// app/actions/user.ts\n'use server'\n\nimport { revalidatePath } from 'next/cache';\nimport { redirect } from 'next/navigation';\n\nexport async function createUser(formData: FormData) {\n const name = formData.get('name') as string;\n const email = formData.get('email') as string;\n \n const user = await prisma.user.create({\n data: { name, email }\n });\n \n revalidatePath('/users');\n redirect(`/users/${user.id}`);\n}\n\n// Component\nexport default function CreateUserForm() {\n return (\n <form action={createUser}>\n <input name=\"name\" placeholder=\"Name\" required />\n <input name=\"email\" type=\"email\" placeholder=\"Email\" required />\n <button type=\"submit\">Create User</button>\n </form>\n );\n}"
}
]
},
"errorHandling": {
"name": "Error Handling Patterns",
"description": "Consistent error handling across the application",
"examples": [
{
"name": "Error Boundary",
"context": "React error boundaries for component errors",
"pattern": "Error boundary with fallback UI",
"code": "'use client'\n\nimport { Component, ErrorInfo, ReactNode } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n}\n\nexport class ErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { hasError: false };\n }\n \n static getDerivedStateFromError(): State {\n return { hasError: true };\n }\n \n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.error('Error caught by boundary:', error, errorInfo);\n }\n \n render() {\n if (this.state.hasError) {\n return this.props.fallback || <div>Something went wrong.</div>;\n }\n \n return this.props.children;\n }\n}"
}
]
}
}
}
VS Code Workspace Configuration
Enhanced Settings (.vscode/settings.json
)
{
"github.copilot.enable": {
"*": true,
"plaintext": false,
"markdown": true,
"scminput": false
},
"github.copilot.advanced": {
"debug.overrideEngine": "copilot-codex",
"debug.testOverrideProxyUrl": "",
"debug.overrideProxyUrl": "",
"length": 500,
"temperature": "",
"top_p": "",
"inlineSuggestEnable": true,
"listCount": 10,
"indentationMode": {
"python": "tab",
"javascript": "space",
"typescript": "space"
}
},
"files.associations": {
"*.json": "jsonc"
},
"typescript.preferences.includePackageJsonAutoImports": "auto",
"typescript.suggest.autoImports": true,
"editor.inlineSuggest.enabled": true,
"editor.suggest.preview": true,
"workbench.editor.enablePreview": false
}
Tasks Configuration (.vscode/tasks.json
)
{
"version": "2.0.0",
"tasks": [
{
"label": "Update VDK Rules",
"type": "shell",
"command": "vdk",
"args": ["init", "--overwrite"],
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": []
},
{
"label": "Sync Copilot Configuration",
"type": "shell",
"command": "vdk",
"args": ["integrations", "--sync", "github-copilot"],
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
}
}
]
}
GitHub Copilot Features
Context-Aware Suggestions
With VDK integration, Copilot provides better suggestions:
Before VDK:
// User types: "create user component"
function UserComponent() {
return <div>User</div>;
}
After VDK:
// User types: "create user component"
interface UserComponentProps {
user: {
id: string;
name: string;
email: string;
};
onEdit?: (user: User) => void;
}
export default function UserComponent({ user, onEdit }: UserComponentProps) {
return (
<div className="p-4 border rounded-lg hover:shadow-md transition-shadow">
<h3 className="text-lg font-semibold text-gray-900">{user.name}</h3>
<p className="text-gray-600">{user.email}</p>
{onEdit && (
<button
onClick={() => onEdit(user)}
className="mt-2 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Edit
</button>
)}
</div>
);
}
Pattern Recognition
Copilot learns your project patterns:
// When creating API routes, Copilot suggests the established pattern:
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { prisma } from '@/lib/db';
const createUserSchema = z.object({
name: z.string().min(1),
email: z.string().email()
});
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const data = createUserSchema.parse(body);
const user = await prisma.user.create({ data });
return NextResponse.json(user, { status: 201 });
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{ error: 'Validation failed', details: error.errors },
{ status: 400 }
);
}
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
Configuration Options
Project-Level Configuration
{
"copilot": {
"enabled": true,
"contextFiles": [
".github/copilot/instructions.json",
".github/copilot/guidelines.json"
],
"fileTypes": {
"typescript": {
"enabled": true,
"strictMode": true
},
"javascript": {
"enabled": true,
"preferTypeScript": true
},
"json": {
"enabled": true,
"validateSchema": true
}
},
"suggestions": {
"length": 500,
"count": 10,
"temperature": 0.2
}
}
}
Global User Settings
{
"github.copilot.advanced": {
"inlineSuggestEnable": true,
"listCount": 10,
"length": 500
},
"vdk": {
"copilot": {
"autoUpdate": true,
"contextDepth": "comprehensive",
"patternLearning": true
}
}
}
Advanced Usage
Custom Instructions
Create project-specific instructions:
{
"customInstructions": {
"api": {
"pattern": "Always use Zod for validation, Prisma for database operations, and proper error handling",
"example": "// See patterns.json for API route examples"
},
"components": {
"pattern": "Use TypeScript interfaces, Tailwind CSS, and proper accessibility attributes",
"example": "// See guidelines.json for component examples"
},
"testing": {
"pattern": "Use Jest and React Testing Library with comprehensive test coverage",
"example": "// Write tests for all public APIs and components"
}
}
}
File-Specific Context
Provide context based on file location:
{
"fileContext": {
"app/**/page.tsx": {
"type": "Next.js Page Component",
"preferServerComponent": true,
"includeMetadata": true,
"pattern": "async function with data fetching"
},
"app/api/**/route.ts": {
"type": "Next.js API Route",
"includeValidation": true,
"includeErrorHandling": true,
"pattern": "RESTful endpoint with proper status codes"
},
"components/**/*.tsx": {
"type": "React Component",
"includeProps": true,
"includeAccessibility": true,
"pattern": "Reusable component with TypeScript"
}
}
}
Team Synchronization
Share Copilot configuration with team:
# Include Copilot configuration in git
git add .github/copilot/ .vscode/
# Deploy to VDK Hub for team sharing
vdk deploy --team frontend-team
# Team members sync with:
vdk update
vdk integrations --sync github-copilot
Troubleshooting
Common Issues
Copilot not using project context:
# Verify configuration files exist
ls -la .github/copilot/
# Check VS Code settings
code .vscode/settings.json
# Restart VS Code and Copilot extension
# Command Palette: "Developer: Reload Window"
Suggestions not matching project patterns:
# Update VDK rules
vdk init --overwrite
# Regenerate Copilot configuration
vdk integrations --setup github-copilot --force
# Check if files are being read
# VS Code: Check Copilot logs in Output panel
Configuration not loading:
# Validate JSON syntax
jq . .github/copilot/instructions.json
# Check file permissions
ls -la .github/copilot/
# Reset configuration
vdk integrations --reset github-copilot
Debug Mode
Enable detailed logging:
# Debug VDK Copilot integration
VDK_DEBUG_COPILOT=true vdk integrations --setup github-copilot
# VS Code: Enable Copilot logging
# Command Palette: "GitHub Copilot: Collect Diagnostics"
Best Practices
1. Organize Configuration by Domain
.github/copilot/
├── instructions.json # Main instructions
├── frontend.json # Frontend-specific rules
├── backend.json # Backend-specific rules
├── testing.json # Testing guidelines
└── deployment.json # Deployment patterns
2. Use Specific Examples
Include concrete code examples in guidelines:
{
"examples": {
"good": {
"description": "Proper TypeScript component",
"code": "interface Props { user: User; }\nexport default function UserCard({ user }: Props) { ... }"
},
"avoid": {
"description": "Avoid any types",
"code": "function UserCard(props: any) { ... }"
}
}
}
3. Keep Instructions Updated
# Regular update workflow
vdk init --overwrite # Update project analysis
vdk integrations --sync github-copilot # Sync Copilot config
git add .github/copilot/ # Version control changes
4. Use File-Specific Context
Tailor instructions to specific file types and locations:
{
"context": {
"app/api/": "Focus on server-side logic, validation, and error handling",
"components/ui/": "Focus on reusable, accessible UI components",
"app/": "Focus on Next.js App Router patterns and server components"
}
}
Next Steps
- Generic IDE Integration - Standard Markdown for any IDE
- Multi-IDE Setup - Using multiple IDEs together
- VS Code Extensions - Enhance VS Code integration
- Custom Patterns - Create custom Copilot patterns