DEV Community

Yigit Konur
Yigit Konur

Posted on

Complete Guide: How to Set AI Coding Rules for GitHub Copilot

Understanding Copilot's configuration evolution is a great start to understand how Github innovates in this field:

Historical Timeline

2021-2023: No Project-Level Configuration

  • Only user-level and workspace settings
  • No way to share coding standards via files
  • Each developer manually configured preferences

August 2024: Experimental Instructions

  • Introduced github.copilot.chat.experimental.codeGeneration.instructions
  • JSON-based configuration in VS Code settings
  • Limited to code generation, not all Copilot features

October 2024: Official File-Based Instructions

  • .github/copilot-instructions.md enabled by default
  • Markdown format for natural language instructions
  • Repository-wide context for all Copilot features

March 2025: Personal Instructions (GA)

  • User-level instructions in GitHub profile
  • Global preferences across all projects

July 2025: Path-Specific Instructions

  • .github/instructions/*.instructions.md files
  • Scope rules to specific directories or file patterns
  • YAML frontmatter for path matching

Why Copilot Lagged Behind Competitors

GitHub Copilot initially focused on:

  • Inline autocomplete (fast, lightweight)
  • Individual developer productivity (not team standards)
  • Cross-IDE compatibility (minimal per-IDE configuration)
  • GitHub ecosystem integration (rather than IDE-specific features)

Advanced customization was reserved for Copilot Enterprise ($39/month) through "coding guidelines" in private preview. Only in late 2024 did GitHub democratize project-level instructions across all tiers.

Current Architecture (2025)

GitHub Copilot now uses a four-tier instruction system:

Priority Order (Highest to Lowest):
1. Personal Instructions (user profile)
2. Repository Instructions (.github/copilot-instructions.md)
3. Path-Specific Instructions (.github/instructions/*.instructions.md)
4. Organization Instructions (Copilot Business/Enterprise)
Enter fullscreen mode Exit fullscreen mode

Official Configuration Methods

Supported Files and Locations

File Location Format Tier Auto-Load Since
copilot-instructions.md .github/ Markdown Free+ ✅ Yes Oct 2024
*.instructions.md .github/instructions/ Markdown + YAML Free+ ✅ Yes Jul 2025
Personal Instructions GitHub Settings Web UI Free+ ✅ Yes Mar 2025
Organization Guidelines Admin Console Web UI Business/Enterprise ✅ Yes 2024

What Gets Loaded

VS Code:

  • All four instruction tiers
  • Workspace settings (.vscode/settings.json)
  • Model configuration from VS Code settings

JetBrains IDEs:

  • All four instruction tiers
  • IDE settings (per-project and global)
  • Plugin configuration

GitHub.com:

  • Repository instructions
  • Organization guidelines
  • Personal instructions
  • Used in Pull Request reviews, Copilot Chat

GitHub Desktop:

  • ❌ No instruction file support
  • Only organization guidelines (if Enterprise)

GitHub CLI:

  • Repository instructions (if in git repo)
  • Personal instructions
  • Organization guidelines

Repository-Level Instructions

File: .github/copilot-instructions.md

Purpose: Project-wide coding standards, architecture context, and team conventions.

Visibility: All team members, automatically loaded in all Copilot surfaces.

When to Use:

  • Project-specific coding standards
  • Tech stack and architecture documentation
  • Team conventions and patterns
  • Testing requirements
  • Deployment procedures

Creating Your First Instructions File

Step 1: Create the File

# Navigate to repository root
cd my-project

# Create .github directory if it doesn't exist
mkdir -p .github

# Create instructions file
touch .github/copilot-instructions.md
Enter fullscreen mode Exit fullscreen mode

Step 2: Basic Structure

# GitHub Copilot Instructions

**Project**: [Your Project Name]  
**Last Updated**: 2025-11-29  

---

## Project Overview

[One-paragraph description of what this project does]

---

## Technology Stack

- **Language**: TypeScript 5.4
- **Framework**: Next.js 15 (App Router)
- **Database**: PostgreSQL 16
- **ORM**: Drizzle ORM

---

## Coding Standards

### TypeScript
- Use strict mode
- Explicit return types on all functions
- No `any` types

### React
- Functional components only
- Server Components by default
- Add `'use client'` only when needed

---

## Testing Requirements

- Unit tests: Vitest
- E2E tests: Playwright
- Minimum 80% coverage

---

## Important Notes

- Use `pnpm` (NOT npm or yarn)
- All commits follow Conventional Commits format
- Environment variables in `.env.local` (never commit secrets)
Enter fullscreen mode Exit fullscreen mode

Step 3: Commit and Push

git add .github/copilot-instructions.md
git commit -m "docs: add GitHub Copilot instructions"
git push origin main
Enter fullscreen mode Exit fullscreen mode

Step 4: Verify Loading

Open any file in your project and ask Copilot Chat:

What are the coding standards for this project?
Enter fullscreen mode Exit fullscreen mode

Copilot should reference your instructions.

Comprehensive Template

# GitHub Copilot Instructions

**Project**: E-Commerce Platform  
**Version**: 2.0.0  
**Last Updated**: 2025-11-29  
**Maintainers**: @frontend-team, @backend-team  

---

## Project Context

### Overview
Full-stack e-commerce platform built with Next.js and PostgreSQL.  
Supports multi-tenant SaaS model with row-level security.

### Goals
- Handle 10,000 concurrent users
- Sub-100ms API response times
- 99.9% uptime SLA

### Non-Goals
- Mobile app (separate repo)
- Legacy PHP admin panel (deprecated)

---

## Technology Stack

### Frontend
- **Framework**: Next.js 15.1 (App Router, NOT Pages Router)
- **Language**: TypeScript 5.4 (strict mode)
- **Styling**: Tailwind CSS 4.0
- **Components**: shadcn/ui + Radix UI
- **State Management**:
  - Server State: TanStack Query v5
  - Client State: Zustand 4.5
  - Forms: React Hook Form + Zod

### Backend
- **Runtime**: Node.js 20.11 LTS
- **API**: tRPC 11 (type-safe)
- **Database**: PostgreSQL 16
- **ORM**: Drizzle ORM 0.35
- **Auth**: NextAuth.js v5

### DevOps
- **Monorepo**: Turborepo 2.0
- **Package Manager**: pnpm 9.0 (**CRITICAL**: Never use npm/yarn)
- **Testing**: Vitest 2.0, Playwright 1.45
- **CI/CD**: GitHub Actions
- **Hosting**: Vercel (production), Railway (staging)

---

## Project Structure

Enter fullscreen mode Exit fullscreen mode

apps/
web/ # Next.js frontend
app/ # App Router pages
components/ # React components
lib/ # Client utilities
packages/
ui/ # Shared component library
database/ # Drizzle schema
types/ # Shared TypeScript types
config/ # ESLint, TS configs


**Key Directories**:
- `apps/web/app/`: Routes using App Router (NOT Pages Router)
- `apps/web/components/ui/`: shadcn/ui primitives
- `packages/database/`: Drizzle schema definitions

---

## Coding Standards

### Universal Principles

1. **Type Safety First**: TypeScript strict mode, no `any`
2. **Error Handling**: Never swallow errors silently
3. **Testing**: 80% coverage minimum
4. **Documentation**: JSDoc for all public APIs

### TypeScript Rules

#### Explicit Return Types
Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ CORRECT
export function calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}

// ❌ WRONG
export function calculateTotal(items: Item[]) {
return items.reduce((sum, item) => sum + item.price, 0);
}


#### Error Handling Pattern
Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ REQUIRED: Result type
type Result =
| { success: true; data: T }
| { success: false; error: string };

async function fetchUser(id: string): Promise> {
try {
const user = await db.query.users.findFirst({
where: eq(users.id, id)
});

if (!user) {
  return { success: false, error: 'User not found' };
}

return { success: true, data: user };
Enter fullscreen mode Exit fullscreen mode

} catch (error) {
logger.error('fetchUser failed', { id, error });
return { success: false, error: 'Database error' };
}
}


#### Avoid `any`
Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ Use unknown + type guards
function processData(data: unknown) {
if (typeof data === 'object' && data !== null && 'id' in data) {
return data.id; // Type-safe
}
throw new Error('Invalid data');
}

// ❌ Never use any
function processData(data: any) {
return data.id; // No type safety
}


### React Patterns

#### Server vs Client Components
Enter fullscreen mode Exit fullscreen mode


tsx
// ✅ Server Component (default - no directive)
async function UserProfilePage({ params }: { params: { id: string } }) {
const user = await db.query.users.findFirst({
where: eq(users.id, params.id)
});

return ;
}

// ✅ Client Component (only when needed)
'use client';

import { useState } from 'react';

export function InteractiveCounter() {
const [count, setCount] = useState(0);
return setCount(count + 1)}>{count};
}


**Add `'use client'` only when**:
- Using hooks (useState, useEffect, useContext)
- Event handlers (onClick, onChange)
- Browser APIs (window, localStorage)

#### Component Size Limits
- Maximum 200 lines per component
- Extract sub-components if exceeded
- Use composition over props drilling

### Import Organization
Enter fullscreen mode Exit fullscreen mode


typescript
// 1. External dependencies
import { useState, useEffect } from 'react';
import { z } from 'zod';

// 2. Internal packages
import { Button } from '@repo/ui';
import { User } from '@repo/types';

// 3. Application modules
import { trpc } from '@/lib/trpc/client';
import { cn } from '@/lib/utils';

// 4. Relative imports
import { UserCard } from './UserCard';

// 5. Styles
import './styles.css';


---

## Testing Standards

### Coverage Requirements
- **Unit Tests**: 80% minimum (business logic)
- **Integration Tests**: 70% minimum (API endpoints)
- **E2E Tests**: Critical user flows only

### Test Structure (AAA Pattern)
Enter fullscreen mode Exit fullscreen mode


typescript
describe('UserService', () => {
it('should create user with valid data', async () => {
// ARRANGE
const userData = { email: 'test@example.com', name: 'Test' };

// ACT
const result = await service.createUser(userData);

// ASSERT
expect(result.success).toBe(true);
expect(result.data).toMatchObject(userData);
Enter fullscreen mode Exit fullscreen mode

});
});


### Commands
Enter fullscreen mode Exit fullscreen mode


bash
pnpm test # Run unit tests
pnpm test:watch # Watch mode
pnpm test:coverage # Coverage report
pnpm test:e2e # E2E tests


---

## API Patterns

### tRPC Procedure Template
Enter fullscreen mode Exit fullscreen mode


typescript
export const userRouter = createTRPCRouter({
getById: publicProcedure
.input(z.object({ id: z.string().uuid() }))
.query(async ({ input, ctx }) => {
const user = await ctx.db.query.users.findFirst({
where: eq(users.id, input.id)
});

  if (!user) {
    throw new TRPCError({
      code: 'NOT_FOUND',
      message: 'User not found',
    });
  }

  return user;
}),
Enter fullscreen mode Exit fullscreen mode

});


### Response Format
All endpoints return:
Enter fullscreen mode Exit fullscreen mode


typescript
{
success: boolean;
data: T | null;
error: string | null;
}


---

## Common Pitfalls

### Hot Reload with tRPC
**Symptom**: Router changes don't reflect  
**Solution**: Restart dev server when adding/removing procedures

### Server Component Hydration
**Symptom**: "Text content did not match" errors  
**Solution**: Ensure all async operations are awaited

### Environment Variables
**Symptom**: `process.env.NEXT_PUBLIC_VAR` undefined  
**Solution**: All client vars MUST have `NEXT_PUBLIC_` prefix

Enter fullscreen mode Exit fullscreen mode


bash

.env.local

NEXT_PUBLIC_API_URL=https://api.example.com # ✅ Client-accessible
DATABASE_URL=postgresql://... # ❌ Server-only


---

## Security Requirements

### Never Commit
- API keys, tokens, secrets
- Database credentials
- Private keys or certificates

### Input Validation
Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ ALWAYS validate with Zod
const UserSchema = z.object({
email: z.string().email(),
password: z.string().min(12),
});

const user = UserSchema.parse(untrustedData);


### SQL Injection Prevention
Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ Parameterized queries (Drizzle ORM)
const users = await db.query.users.findMany({
where: eq(users.email, email) // Safe
});

// ❌ String concatenation
const query = SELECT * FROM users WHERE email = '${email}'; // Vulnerable!


---

## Git Workflow

### Branch Naming
- `feat/feature-name` - New features
- `fix/bug-description` - Bug fixes
- `docs/what-changed` - Documentation
- `refactor/what-improved` - Code improvements

### Commit Format
Follow Conventional Commits:
Enter fullscreen mode Exit fullscreen mode

feat(auth): add password reset flow
fix(api): handle null user in profile endpoint
docs(readme): update installation steps


Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`

### Pull Requests
- Require 1 approval
- All CI checks must pass
- Squash merge to main

---

## Deployment Checklist

Before deploying:
- [ ] All tests pass (`pnpm test`)
- [ ] TypeScript check passes (`pnpm type-check`)
- [ ] Linter passes (`pnpm lint --max-warnings 0`)
- [ ] Build succeeds (`pnpm build`)
- [ ] Environment variables configured
- [ ] Database migrations applied
- [ ] Secrets rotated if compromised

---

## Common Commands

### Development
Enter fullscreen mode Exit fullscreen mode


bash
pnpm dev # Start dev server
pnpm build # Production build
pnpm lint # Run ESLint
pnpm type-check # TypeScript validation
pnpm format # Prettier formatting


### Database
Enter fullscreen mode Exit fullscreen mode


bash
pnpm db:push # Push schema to database
pnpm db:studio # Open Drizzle Studio
pnpm db:generate # Generate migrations
pnpm db:migrate # Apply migrations


---

## Additional Resources

- **Architecture**: `docs/architecture.md`
- **API Reference**: `docs/api-reference.md`
- **Database Schema**: `packages/database/schema.ts`
- **Deployment**: `docs/deployment.md`

---

## Working with GitHub Copilot

### In VS Code
- Use **Copilot Chat** (Ctrl+I) for questions
- Use **Inline Suggestions** (Tab) for autocomplete
- Use **Slash Commands**: `/explain`, `/fix`, `/test`

### In JetBrains
- Open **Copilot Chat** (Alt+\)
- Use inline completions (Tab)
- Right-click for context actions

### On GitHub.com
- Use **Copilot Chat** in Pull Requests
- Ask for code review feedback
- Generate commit messages

---

## Maintenance

Update this file when:
- Tech stack changes (framework upgrades, new libraries)
- Coding patterns evolve (new best practices discovered)
- Team conventions change (new git workflow, testing strategy)

**Process**: Create PR, require 1 approval, update date.

---

*This file configures GitHub Copilot for all team members. Treat it as living documentation.*
Enter fullscreen mode Exit fullscreen mode

Character Limits and Optimization

No Hard Limits: GitHub Copilot doesn't enforce character limits like Windsurf (6,000 chars) or enforce specific lengths.

Practical Limits:

  • Recommended: 2,000-5,000 words (8-20 KB)
  • Maximum effective: ~50 KB (beyond this, context dilution occurs)
  • Minimum useful: 500 words (basic standards)

Token Usage:

  • Instructions compete for context window space
  • More concise = more room for actual code context
  • Use bullet points and tables over prose

Path-Specific Instructions

File: .github/instructions/*.instructions.md

Purpose: Apply rules only to specific directories or file patterns.

Use Cases:

  • Different standards for frontend vs backend
  • Language-specific conventions
  • Test-specific patterns
  • Directory-level overrides

YAML Frontmatter Syntax

---
applyTo: "pattern"
---

# Instructions content
Enter fullscreen mode Exit fullscreen mode

Supported Patterns:

  • File extensions: **/*.ts, **/*.tsx
  • Directories: src/**, tests/**
  • Specific files: src/index.ts
  • Multiple patterns: **/*.{ts,tsx,js,jsx}

Creating Path-Specific Instructions

Step 1: Create Directory Structure

mkdir -p .github/instructions

# Create instruction files
touch .github/instructions/typescript.instructions.md
touch .github/instructions/tests.instructions.md
touch .github/instructions/frontend.instructions.md
Enter fullscreen mode Exit fullscreen mode

Step 2: TypeScript-Specific Rules

---
applyTo: "**/*.{ts,tsx}"
---

# TypeScript Standards

## Type Safety

### Explicit Return Types
All functions must have explicit return types:
Enter fullscreen mode Exit fullscreen mode


typescript
function calculate(x: number): number {
return x * 2;
}


### No Any Types
Use `unknown` instead:
Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ Correct
function process(data: unknown) {
if (typeof data === 'string') {
return data.toUpperCase();
}
}

// ❌ Wrong
function process(data: any) {
return data.toUpperCase();
}


## Async Patterns

Always use async/await:
Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ Correct
async function fetchData() {
const response = await fetch(url);
return response.json();
}

// ❌ Wrong
function fetchData() {
return fetch(url).then(r => r.json());
}

Enter fullscreen mode Exit fullscreen mode

Step 3: Test-Specific Rules

---
applyTo: "**/*.{test,spec}.{ts,tsx,js,jsx}"
---

# Testing Standards

## Test Structure

Use AAA pattern (Arrange, Act, Assert):
Enter fullscreen mode Exit fullscreen mode


typescript
describe('calculateTotal', () => {
it('should sum item prices', () => {
// Arrange
const items = [{ price: 10 }, { price: 20 }];

// Act
const total = calculateTotal(items);

// Assert
expect(total).toBe(30);
Enter fullscreen mode Exit fullscreen mode

});
});


## Coverage Requirements

- Every public function needs tests
- Test happy path + error cases + edge cases
- Mock external dependencies

## Naming Convention

Enter fullscreen mode Exit fullscreen mode

describe('[Component/Function Name]', () => {
it('should [expected behavior] when [condition]', () => {
// Test
});
});

Enter fullscreen mode Exit fullscreen mode

Step 4: Frontend-Specific Rules

---
applyTo: "src/components/**/*.{tsx,jsx}"
---

# React Component Standards

## Component Structure

Use functional components with TypeScript:
Enter fullscreen mode Exit fullscreen mode


tsx
interface Props {
user: User;
onEdit: (id: string) => void;
}

export function UserCard({ user, onEdit }: Props) {
return (


{user.name}


onEdit(user.id)}>Edit

);
}

## Size Limits

- Maximum 200 lines per component
- Extract sub-components if exceeded

## State Management

| Use Case | Solution |
|----------|----------|
| Server data | TanStack Query |
| Form state | React Hook Form |
| Local UI state | useState |
| Global state | Zustand |
Enter fullscreen mode Exit fullscreen mode

Complete Example Structure

my-project/
├── .github/
│   ├── copilot-instructions.md           # Repository-wide rules
│   └── instructions/
│       ├── typescript.instructions.md     # applyTo: **/*.{ts,tsx}
│       ├── javascript.instructions.md     # applyTo: **/*.{js,jsx}
│       ├── tests.instructions.md          # applyTo: **/*.test.*
│       ├── frontend.instructions.md       # applyTo: src/components/**
│       ├── backend.instructions.md        # applyTo: src/api/**
│       └── database.instructions.md       # applyTo: **/schema.ts
└── src/
Enter fullscreen mode Exit fullscreen mode

Advanced Pattern Matching

Exclude Patterns (Negative Lookahead):

---
applyTo: "src/**/*.ts,!src/**/*.test.ts"
---

# Production TypeScript (excluding tests)
Enter fullscreen mode Exit fullscreen mode

Multiple Directories:

---
applyTo: "{src,lib,packages}/**/*.tsx"
---

# React Components Across Multiple Directories
Enter fullscreen mode Exit fullscreen mode

Specific File Names:

---
applyTo: "**/schema.ts"
---

# Database Schema Files
Enter fullscreen mode Exit fullscreen mode

Organization-Level Instructions

Copilot Business/Enterprise Feature

Access: Admin Console → Copilot → Policies → Coding Guidelines

Character Limit: 609 characters (very restrictive)

Purpose:

  • Company-wide security policies
  • Compliance requirements (SOC2, HIPAA, GDPR)
  • Universal coding standards
  • Technology restrictions

What to Include (Given 609 Char Limit)

Option 1: Security-Focused

Security Requirements:
- No hardcoded secrets/API keys
- Validate all user inputs (use Zod)
- Parameterized SQL queries only
- HTTPS for all external calls
- Log security events to SIEM

Compliance:
- GDPR: Personal data must be encrypted at rest
- SOC2: Audit logging required for data access
Enter fullscreen mode Exit fullscreen mode

Option 2: Standards-Focused

Company Standards:
- TypeScript for all new code
- Test coverage >80%
- Conventional Commits format
- Branch protection: require reviews
- No GPL-licensed dependencies

Contact: security@company.com for exceptions
Enter fullscreen mode Exit fullscreen mode

Option 3: Technology Restrictions

Approved Technologies:
- Languages: TypeScript, Python, Go
- Databases: PostgreSQL, MongoDB
- Cloud: AWS only (no GCP/Azure)
- Auth: Okta integration required

Prohibited:
- Eval functions
- Deprecated libraries (see wiki)
Enter fullscreen mode Exit fullscreen mode

Setting Organization Instructions

Step 1: Navigate to Admin Console

https://github.com/organizations/YOUR_ORG/settings/copilot/policies/coding_guidelines
Enter fullscreen mode Exit fullscreen mode

Step 2: Enable Coding Guidelines

  • Toggle "Enable coding guidelines" to ON

Step 3: Enter Guidelines (609 char limit)

Company-Wide Standards:
1. TypeScript strict mode
2. No secrets in code
3. Test coverage >80%
4. Conventional Commits
5. Zod for validation
6. PostgreSQL only

Security:
- Validate inputs
- Parameterized queries
- HTTPS only
- Audit logging

Contact: dev-standards@company.com
Enter fullscreen mode Exit fullscreen mode

Step 4: Save and Deploy

  • Changes propagate to all organization members within 15 minutes

Best Practices for 609 Character Limit

Do:

  • ✅ Focus on security and compliance (non-negotiable items)
  • ✅ Use abbreviations and bullet points
  • ✅ Reference external documentation URL
  • ✅ Prioritize the most critical 5-7 rules

Don't:

  • ❌ Try to fit complete coding standards (use repository instructions)
  • ❌ Include examples (no space)
  • ❌ Duplicate what's in repository instructions
  • ❌ Use prose (wastes characters)

Combining Organization + Repository Instructions

Organization Instructions (609 chars):

Security (REQUIRED):
- No secrets in code
- Input validation (Zod)
- SQL: parameterized only
- Audit logging

Standards:
- TypeScript strict mode
- >80% test coverage
- Conventional Commits

Tech Stack:
- PostgreSQL only
- AWS only

See: wiki.company.com/standards
Enter fullscreen mode Exit fullscreen mode

Repository Instructions (in .github/copilot-instructions.md):

# Project-Specific Instructions

## Organization Standards

This project follows company-wide standards:
- See: wiki.company.com/standards
- Contact: dev-standards@company.com

## Project-Specific Rules

[Detailed project rules here...]
Enter fullscreen mode Exit fullscreen mode

Personal Instructions

User-Level Global Configuration

Location: GitHub Account Settings → Copilot → Preferences

Purpose: Your personal coding preferences that apply across ALL projects.

Use Cases:

  • Response style preferences
  • Language preferences (e.g., British vs American English)
  • Explanation verbosity
  • Code comment style
  • Personal shortcuts or patterns

Setting Personal Instructions

Step 1: Navigate to Settings

https://github.com/settings/copilot
Enter fullscreen mode Exit fullscreen mode

Step 2: Scroll to "Preferences"

Step 3: Enter Your Instructions

Response Style:
- Be concise and direct
- Provide code examples with explanations
- Highlight breaking changes or gotchas

Code Preferences:
- Prefer modern ES2022+ syntax
- Use descriptive variable names
- Favor explicit over clever

Comments:
- JSDoc for all public functions
- Inline comments for complex logic
- No obvious comments

Testing:
- I prefer integration tests over unit tests
- Always show test examples
Enter fullscreen mode Exit fullscreen mode

Step 4: Save

Personal vs Repository Instructions

Personal Instructions (highest priority):

  • Response format and style
  • Your preferred patterns (across all projects)
  • Communication preferences

Repository Instructions (team standards):

  • Project-specific tech stack
  • Team coding conventions
  • Architecture patterns

Example Interaction:

// Repository says: "Use Zustand for state"
// Personal says: "Always explain why a pattern was chosen"

// Copilot response:
// "I'm using Zustand for global state management (as specified in 
// project standards) because it provides a simple, hook-based API
// with minimal boilerplate compared to Redux."
Enter fullscreen mode Exit fullscreen mode

Effective Personal Instructions

# My Copilot Preferences

## Communication Style
- Concise explanations (no fluff)
- Code-first (show, don't tell)
- Warn about performance implications

## Code Style
- Modern syntax (async/await, optional chaining, nullish coalescing)
- Destructuring where readable
- Explicit types in TypeScript

## Testing Philosophy
- Integration tests preferred
- Mock external services
- Real database in test env (not mocks)

## Git
- Conventional Commits format
- Prefix: feat|fix|docs|refactor|test

## When I Say "Improve"
Check for:
1. Type safety
2. Error handling
3. Performance (O(n) complexity)
4. Security (input validation)
Enter fullscreen mode Exit fullscreen mode

Workspace Settings Configuration

.vscode/settings.json

Purpose: Project-specific VS Code configuration (not strictly Copilot instructions, but affects behavior).

Location: .vscode/settings.json in project root

What to Configure:

  • Model selection
  • Context token budget
  • Enable/disable features per language

Basic Configuration

{
  // Copilot enable/disable per language
  "github.copilot.enable": {
    "*": true,
    "plaintext": false,
    "markdown": false
  },

  // Context tokens for chat
  "github.copilot.chat.experimental.contextTokensBudget": 40000,

  // Inline suggestions
  "github.copilot.inlineSuggest.enable": true,

  // Editor integration
  "editor.inlineSuggest.enabled": true,
  "editor.quickSuggestions": {
    "comments": false,
    "strings": false,
    "other": true
  }
}
Enter fullscreen mode Exit fullscreen mode

Advanced Configuration

{
  // Language-specific Copilot settings
  "github.copilot.enable": {
    "*": true,
    "yaml": false,
    "markdown": false,
    "plaintext": false
  },

  // Chat context configuration
  "github.copilot.chat.experimental.contextTokensBudget": 40000,
  "github.copilot.chat.experimental.maxReferences": 30,

  // Code generation preferences
  "github.copilot.chat.experimental.codeGeneration.instructions": [
    {
      "text": "Always use TypeScript strict mode"
    },
    {
      "text": "Prefer functional programming patterns"
    }
  ],

  // Inline suggestions
  "github.copilot.inlineSuggest.enable": true,
  "github.copilot.advanced": {
    "inlineSuggestCount": 3,
    "top_p": 1,
    "temperature": 0.1,
    "listCount": 10
  },

  // Editor behavior
  "editor.inlineSuggest.enabled": true,
  "editor.inlineSuggest.showToolbar": "onHover",
  "editor.quickSuggestions": {
    "other": true,
    "comments": false,
    "strings": false
  },

  // Language-specific overrides
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },

  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  }
}
Enter fullscreen mode Exit fullscreen mode

Deprecated Settings (Pre-October 2024)

Don't Use (replaced by .github/copilot-instructions.md):

{
  //  DEPRECATED - Use .github/copilot-instructions.md instead
  "github.copilot.chat.experimental.codeGeneration.instructions": [
    { "text": "Use TypeScript" },
    { "file": "docs/standards.md" }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Workspace vs User Settings

User Settings (~/.config/Code/User/settings.json):

  • Personal Copilot preferences
  • Applies to all projects
  • Not version controlled

Workspace Settings (.vscode/settings.json):

  • Project-specific configuration
  • Version controlled (commit to git)
  • Shared with team

Best Practice: Use workspace settings for team-wide configurations, user settings for personal preferences.


Instruction Hierarchy and Precedence

Priority Order (Highest to Lowest)

1. Personal Instructions (GitHub Settings)
   ↓ (overrides)
2. Repository Instructions (.github/copilot-instructions.md)
   ↓ (overrides)
3. Path-Specific Instructions (.github/instructions/*.instructions.md)
   ↓ (overrides)
4. Organization Instructions (Admin Console)
   ↓ (overrides)
5. Default Copilot Behavior
Enter fullscreen mode Exit fullscreen mode

How Conflicts are Resolved

Scenario 1: Conflicting State Management

Personal Instructions: "I prefer Redux for state management"
Repository Instructions: "Use Zustand for global state"

Result: Copilot uses Zustand (repository wins for team standards) but may explain both options and why Zustand was chosen for this project.


Scenario 2: Comment Style

Personal Instructions: "Minimal comments, self-documenting code"
Repository Instructions: "JSDoc required for all public functions"

Result: Copilot adds JSDoc (repository wins) but keeps comments concise per your preference.


Scenario 3: Security Policy

Organization Instructions: "No console.log in production code"
Repository Instructions: [No mention of logging]
Personal Instructions: [No mention of logging]

Result: Copilot avoids console.log (organization policy enforced).


Testing Priority

Create a test file:

# Create test
mkdir -p src/test
cat > src/test/priority-test.ts << 'EOF'
// Test GitHub Copilot instruction priority
// Ask Copilot to generate a state management solution
EOF
Enter fullscreen mode Exit fullscreen mode

Ask Copilot:

Generate a global state store for user authentication.
Enter fullscreen mode Exit fullscreen mode

Observe:

  • Which state management library does it choose?
  • Does it follow personal or repository conventions?
  • Are organization security policies applied?

VS Code Integration

Installation and Setup

Step 1: Install Extension

  1. Open VS Code
  2. Navigate to Extensions (Ctrl+Shift+X)
  3. Search "GitHub Copilot"
  4. Click "Install"
  5. Restart VS Code

Step 2: Sign In

  1. Click Copilot icon in bottom status bar
  2. Sign in with GitHub account
  3. Authorize VS Code

Step 3: Verify Instructions Loaded

  1. Open any file in your project
  2. Open Copilot Chat (Ctrl+I)
  3. Ask: "What coding standards apply to this project?"
  4. Copilot should reference .github/copilot-instructions.md

Using Copilot with Instructions

Inline Suggestions:

// Start typing, Copilot suggests following project rules
async function fetchUser
// Copilot suggests: (id: string): Promise<Result<User>> {
Enter fullscreen mode Exit fullscreen mode

Copilot Chat:

You: Generate error handling for API call
Copilot: I'll use the Result<T> pattern from project standards:
[Generates code following .github/copilot-instructions.md]
Enter fullscreen mode Exit fullscreen mode

Slash Commands:

  • /explain - Explain code (uses context)
  • /fix - Fix problems (follows standards)
  • /test - Generate tests (follows test patterns)
  • /doc - Add documentation (follows doc style)

Keyboard Shortcuts

Action Windows/Linux macOS
Accept suggestion Tab Tab
Reject suggestion Esc Esc
Next suggestion Alt+] Option+]
Previous suggestion Alt+[ Option+[
Open Chat Ctrl+I Cmd+I
Inline Chat Ctrl+I (in editor) Cmd+I

Workspace Commands

Open Command Palette (Ctrl+Shift+P):

  • GitHub Copilot: Open Completions Panel
  • GitHub Copilot: Toggle Copilot Completions
  • GitHub Copilot: Send Feedback

Troubleshooting in VS Code

Instructions Not Loading:

# Check file exists
ls -la .github/copilot-instructions.md

# Verify format (valid Markdown)
cat .github/copilot-instructions.md

# Restart VS Code
# Cmd+Shift+P → "Developer: Reload Window"
Enter fullscreen mode Exit fullscreen mode

Check Copilot Status:

  • Click Copilot icon in status bar
  • Should show "✓ Ready"
  • If error, click to see details

JetBrains IDEs Integration

Supported IDEs

  • IntelliJ IDEA (Ultimate, Community)
  • PyCharm (Professional, Community)
  • WebStorm
  • PhpStorm
  • Rider
  • GoLand
  • RubyMine
  • CLion
  • DataGrip

Installation

Step 1: Install Plugin

  1. Open IDE → Settings/Preferences
  2. Navigate to Plugins
  3. Search "GitHub Copilot"
  4. Click "Install"
  5. Restart IDE

Step 2: Sign In

  1. Settings → Tools → GitHub Copilot
  2. Click "Sign In"
  3. Authorize in browser
  4. Return to IDE

Step 3: Verify

  1. Open any file
  2. Start typing
  3. Copilot suggestions should appear

Using Instructions in JetBrains

Automatic Loading:

  • .github/copilot-instructions.md loaded automatically
  • Path-specific instructions apply based on file location
  • Organization guidelines enforced

Copilot Chat:

  1. Right-click in editor → "Copilot Chat"
  2. Or use shortcut: *Alt+* (Windows/Linux), *⌥* (Mac)
  3. Ask questions referencing project context

Inline Suggestions:

// Start typing
fun fetchUser
// Copilot suggests based on project Kotlin standards
Enter fullscreen mode Exit fullscreen mode

Configuration in JetBrains

Settings → Tools → GitHub Copilot:

☑ Enable GitHub Copilot
☐ Show completions automatically
☑ Enable Copilot Chat
☑ Include project context in chat

Context:
☑ Repository instructions (.github/copilot-instructions.md)
☑ Organization guidelines
☑ Personal instructions

Languages:
☑ Kotlin
☑ Java
☑ Python
☐ XML
☐ Properties files
Enter fullscreen mode Exit fullscreen mode

JetBrains-Specific Features

Intention Actions:

  1. Press Alt+Enter on any code
  2. Select "Ask Copilot"
  3. Choose action (Explain, Fix, Generate Test, etc.)

Code Generation Templates:

  • Copilot respects JetBrains Live Templates
  • Combines project instructions + IDE templates

Language-Specific Integration:

  • Java: Understands Spring Boot, Maven, Gradle from instructions
  • Kotlin: Applies Kotlin idioms + project standards
  • Python: Respects virtual env, follows PEP 8 + custom rules

Troubleshooting in JetBrains

Instructions Not Working:

  1. Invalidate Caches: File → Invalidate Caches → Invalidate and Restart
  2. Verify plugin updated: Settings → Plugins → GitHub Copilot → Check for Updates
  3. Re-index project: File → Invalidate Caches → Clear File System Cache

Chat Context Issues:

  1. Settings → Tools → GitHub Copilot
  2. Ensure "Include project context" enabled
  3. Restart IDE

GitHub.com Web Integration

Pull Request Reviews

Using Copilot in PRs:

  1. Open any Pull Request
  2. Click "Copilot" icon in comment toolbar
  3. Ask for code review:
   Review this code for:
   - Standards compliance (check .github/copilot-instructions.md)
   - Security issues
   - Performance problems
Enter fullscreen mode Exit fullscreen mode

Copilot will:

  • Reference repository instructions
  • Check organization policies
  • Provide inline suggestions

Copilot Chat on GitHub.com

Access:

  1. Navigate to repository
  2. Click "Copilot Chat" button (top-right, next to search)
  3. Chat opens in sidebar

Example Usage:

You: What are the coding standards for this project?

Copilot: Based on .github/copilot-instructions.md, this project uses:
- TypeScript 5.4 (strict mode)
- Next.js 15 (App Router)
- Drizzle ORM for database
- Result<T> pattern for error handling
Enter fullscreen mode Exit fullscreen mode

Commit Message Generation

In Commit UI:

  1. Stage changes
  2. Click Copilot icon in commit message box
  3. Copilot generates message following Conventional Commits (if specified in instructions)

Example:

feat(auth): add password reset flow

- Implements email-based password reset
- Uses NextAuth.js v5
- Follows Result<T> error pattern from project standards
Enter fullscreen mode Exit fullscreen mode

Repository Q&A

Ask Copilot about your repo:

You: How is authentication implemented?

Copilot: [Scans codebase + reads .github/copilot-instructions.md]
Authentication uses NextAuth.js v5 as specified in the project standards...
Enter fullscreen mode Exit fullscreen mode

Limitations on GitHub.com

  • ❌ No inline code completions (web editor limitation)
  • ✅ Full chat functionality
  • ✅ Pull request reviews
  • ✅ Commit message generation
  • ✅ Repository Q&A

GitHub Desktop and CLI

GitHub Desktop

Current Status (as of November 2025):

  • No support for .github/copilot-instructions.md
  • ❌ No Copilot integration at all
  • ⚠️ Organization guidelines MAY apply if Enterprise (unconfirmed)

Recommendation: Use VS Code, JetBrains, or GitHub.com for Copilot features.


GitHub CLI (gh command)

Copilot in CLI:

# Install GitHub CLI
brew install gh  # macOS
# or download from: https://cli.github.com

# Install Copilot extension
gh extension install github/gh-copilot

# Use Copilot
gh copilot suggest "how to undo last commit"
gh copilot explain "git rebase -i HEAD~3"
Enter fullscreen mode Exit fullscreen mode

Instructions Support:

  • ✅ Reads .github/copilot-instructions.md (if in git repo)
  • ✅ Applies organization guidelines
  • ✅ Uses personal instructions

Example with Project Context:

# Navigate to project
cd my-project

# Ask project-specific question
gh copilot suggest "generate user authentication endpoint"

# Copilot response:
# [Uses context from .github/copilot-instructions.md]
# "Based on your project standards (tRPC + NextAuth.js):"
# [Generates code following project patterns]
Enter fullscreen mode Exit fullscreen mode

Production-Ready Examples

Example 1: React + TypeScript SaaS

# GitHub Copilot Instructions - SaaS Platform

**Project**: Multi-tenant SaaS Platform  
**Stack**: Next.js 15, TypeScript, PostgreSQL  
**Last Updated**: 2025-11-29  

---

## Core Standards

- TypeScript strict mode (no `any`)
- Server Components by default
- Result<T> for error handling
- 85% test coverage minimum

---

## Tech Stack

- Next.js 15 (App Router)
- TypeScript 5.4
- Tailwind CSS 4.0
- Drizzle ORM + PostgreSQL 16
- NextAuth.js v5
- tRPC 11

---

## Multi-Tenancy

### Critical Rule
Every database query MUST filter by `orgId`:

Enter fullscreen mode Exit fullscreen mode


typescript
// ✅ CORRECT
const projects = await db.query.projects.findMany({
where: eq(projects.orgId, user.orgId)
});

// ❌ SECURITY RISK - Leaks data across organizations
const projects = await db.query.projects.findMany();


### Row-Level Security
All tables have RLS enabled. Double-check in code anyway.

---

## Authentication

- JWTs in HttpOnly cookies (NEVER localStorage)
- Access tokens: 15min expiry
- Refresh tokens: 7 days, rotated on use

---

## API Design

### tRPC Pattern
Enter fullscreen mode Exit fullscreen mode


typescript
export const router = createTRPCRouter({
list: protectedProcedure
.query(async ({ ctx }) => {
return await ctx.db.query.items.findMany({
where: eq(items.orgId, ctx.user.orgId)
});
}),
});


### Response Format
Enter fullscreen mode Exit fullscreen mode


typescript
{
success: boolean;
data: T | null;
error: string | null;
}


---

## Testing

- Unit: Vitest
- E2E: Playwright
- Mock Strategy: MSW for external APIs, real DB for data layer

---

## Security Checklist

- [ ] OrgId filter on all queries
- [ ] Input validation (Zod)
- [ ] No secrets in code
- [ ] Rate limiting on public endpoints
Enter fullscreen mode Exit fullscreen mode

Example 2: Python FastAPI Microservice

# GitHub Copilot Instructions - API Service

**Project**: User Management Microservice  
**Stack**: Python, FastAPI, PostgreSQL  

---

## Standards

- Python 3.12+
- Type hints on ALL function arguments and return values
- PEP 8 style guide
- Async/await for all I/O operations

---

## Architecture

### Hexagonal Architecture
Enter fullscreen mode Exit fullscreen mode

app/
api/ # Primary adapters (routers)
core/ # Core logic (config, exceptions)
domain/ # Domain models and services
infrastructure/ # Secondary adapters (DB, external APIs)


### Dependency Injection
Use FastAPI dependencies for all services:
Enter fullscreen mode Exit fullscreen mode


python
@router.get("/users/{id}")
async def get_user(
id: str,
service: UserService = Depends(get_user_service)
):
return await service.get_user(id)


---

## Database Patterns

### SQLAlchemy + AsyncPG
Enter fullscreen mode Exit fullscreen mode


python

✅ CORRECT - Async session

async with AsyncSession(engine) as session:
result = await session.execute(select(User))
return result.scalars().all()

❌ WRONG - Sync session

with Session(engine) as session:
# Will block event loop!


### Pydantic Models
- Use Pydantic V2 (`model_validate`, not `parse_obj`)
- Strict types where possible
- Config: `from_attributes = True` (was `orm_mode`)

---

## Testing

- Pytest with `pytest-asyncio`
- Coverage > 90%
- Fixtures in `conftest.py`
Enter fullscreen mode Exit fullscreen mode

Best Practices

1. Keep Instructions Concise

Copilot has a limited context window (64k tokens). Verbose instructions push relevant code out of context.

Bad:

We believe that type safety is very important because it helps prevent runtime errors and makes the code easier to maintain. Therefore, we would like you to please try to use TypeScript's strict mode whenever possible and avoid using the 'any' type unless absolutely necessary.
Enter fullscreen mode Exit fullscreen mode

Good:

- TypeScript strict mode REQUIRED
- NO `any` types (use `unknown` + type guards)
Enter fullscreen mode Exit fullscreen mode

2. Use Examples

Examples are more effective than descriptions.

Bad:

Use the repository pattern for data access.
Enter fullscreen mode Exit fullscreen mode

Good:

## Repository Pattern

Enter fullscreen mode Exit fullscreen mode


typescript
class UserRepository {
constructor(private db: Database) {}

async findById(id: string): Promise {
return this.db.users.findFirst({ where: { id } });
}
}

Enter fullscreen mode Exit fullscreen mode

3. Regular Updates

Update instructions when:

  • Tech stack changes (e.g., upgrading Next.js 14 → 15)
  • New patterns are adopted
  • Common mistakes are identified
  • Team conventions evolve

Schedule: Review monthly or quarterly.

4. Avoid Conflicts

Ensure your instruction layers don't contradict:

  • Repo: "Use tabs"
  • Personal: "Use spaces"
  • Org: "Use EditorConfig"

Result: Confusion and inconsistent suggestions.

5. Test Your Rules

  1. Create a test file
  2. Ask Copilot to generate code
  3. Verify it follows your rules
  4. Adjust instructions if needed

Limitations and Workarounds

Context Window (64k Tokens)

Problem: Copilot can't "read" your entire codebase at once. It sees:

  • Current file (cursor position)
  • Open tabs (recent context)
  • copilot-instructions.md
  • Snippets from other files (via retrieval)

Impact: Complex refactoring across 50+ files is unreliable.

Workaround:

  • Keep files small (<300 lines)
  • Open relevant files in tabs before asking complex questions
  • Use explicit imports so Copilot can trace dependencies

Multi-File Awareness

Problem: Copilot struggles to understand deep relationships between distant files.

Impact: "Refactor this API and update all consumers" often misses some usages.

Workaround:

  • Do it in steps: "Refactor the API", then "Update consumer A", then "Update consumer B"
  • Use "Copilot Workspace" (if available) for multi-file tasks

Instruction Adherence

Problem: Copilot sometimes ignores instructions, especially negative ones ("Don't do X").

Impact: Generated code might contain forbidden patterns.

Workaround:

  • Use strong language: "REQUIRED", "MANDATORY", "NEVER"
  • Provide correct examples (positive reinforcement works better than negative)
  • Use path-specific instructions for strict enforcement in critical areas

Migration from Other Tools

From Cursor (.cursorrules)

Process:

  1. Copy .cursorrules content to .github/copilot-instructions.md
  2. Remove Cursor-specific syntax (e.g., @file references if used in rules)
  3. Convert YAML frontmatter (if using .mdc format) to standard Markdown headers
  4. Simplify glob patterns (Copilot uses .github/instructions/ for path-specifics)

Example Conversion:

Cursor (.cursor/rules/typescript.mdc):

---
description: TypeScript rules
globs: ["**/*.ts"]
---
Use strict mode.
Enter fullscreen mode Exit fullscreen mode

Copilot (.github/instructions/typescript.instructions.md):

---
applyTo: "**/*.ts"
---
Use strict mode.
Enter fullscreen mode Exit fullscreen mode

From Windsurf (.windsurfrules)

Process:

  1. Extract rules from .windsurfrules or .windsurf/rules/*.md
  2. Combine universal rules into .github/copilot-instructions.md
  3. Move file-specific rules to .github/instructions/*.instructions.md
  4. Remove Windsurf-specific activation modes (Copilot manages context automatically)

From Aider (CONVENTIONS.md)

Process:

  1. Copy CONVENTIONS.md content to .github/copilot-instructions.md
  2. Copilot will automatically read it (no config file needed)

Troubleshooting

Instructions Not Loading

Symptom: Copilot ignores your rules.

Checks:

  1. File location: Must be exactly .github/copilot-instructions.md (case-sensitive)
  2. Root directory: .github/ must be in the project root (where .git/ is)
  3. VS Code reload: Restart VS Code to refresh context
  4. Format: Ensure valid Markdown syntax
  5. Token limit: Is the file too large? (>50KB)

"I don't see that file"

Symptom: Copilot Chat says it can't access the instructions file.

Explanation: Copilot treats instructions as system prompt context, not necessarily as a file in the file explorer.

Test: Instead of "read the instructions file", ask "what are the project coding standards?". If it answers correctly, the instructions are loaded.

Conflicting Behavior

Symptom: Copilot alternates between two styles.

Cause: Conflict between:

  • Repository instructions vs Personal instructions
  • Instructions vs Existing Code patterns (Copilot mimics existing code)

Fix:

  • Align instructions
  • Refactor existing code to match new standards (Copilot learns from context)
  • Use stronger language ("ALWAYS use X, never Y")

Conclusion

GitHub Copilot's instruction system has matured into a powerful, tiered configuration engine. By leveraging Repository Instructions for team standards, Path-Specific Instructions for granular control, and Personal Instructions for developer preferences, teams can achieve high consistency and productivity.

Key Takeaway: Treat your .github/copilot-instructions.md as a first-class artifact of your codebase—version it, review it, and keep it updated as your project evolves.

Top comments (0)