Cline Rules: Autonomous Coding Agent Best Practices (2026)

Cline Rules: Autonomous Coding Agent Best Practices (2026)

Cline is an open-source autonomous coding agent that lives directly in VS Code. Unlike autocomplete tools, Cline can create files, run terminal commands, and complete entire coding tasks independently. The key to getting great results is providing clear instructions and guidelines.

This guide provides ready-to-use rules that help Cline work effectively on your projects.

Understanding Cline's Capabilities

Cline is unique because it:

  • Creates files: Can generate new files and folders autonomously
  • Edits code: Makes changes across multiple files in one task
  • Runs commands: Executes terminal commands (install packages, run tests, etc.)
  • Shows its work: Every action requires your approval before execution
  • Transparent pricing: Open-source with clear API usage costs
  • Multi-model support: Works with Claude, GPT-4, and other models

The transparency is key—you see and approve everything before it happens.

Setting Up Cline Instructions

Method 1: Custom Instructions in VS Code

Cline has a built-in custom instructions feature:

  1. Open Cline panel in VS Code
  2. Click settings (gear icon)
  3. Add your custom instructions

Method 2: Project Instructions File

Create .clinerules or .cline/instructions.md in your project root:

# Cline Instructions

[Your rules go here - Cline will reference this automatically]

Method 3: In-Task Instructions

Provide instructions directly when giving Cline a task:

"Following our TypeScript conventions (functional patterns, strict types), 
create a user authentication service..."

Ready-to-Use Cline Rules

General Task Execution Rules

## Task Execution Guidelines

- Break complex tasks into smaller, logical steps
- Ask for clarification if requirements are ambiguous
- Show a plan before implementing (outline the approach)
- Create tests alongside implementation code
- Run tests after implementation to verify functionality
- Format code before completing the task
- Provide a summary of changes made when done

## File Organization
- Create new files in appropriate directories based on project structure
- Follow existing naming conventions in the project
- Keep related files together (component + test + styles)
- Update imports in affected files after creating/moving files

Code Style Rules

## Code Style Standards

### General Principles
- Write self-documenting code with clear variable names
- Prefer readability over cleverness
- Keep functions small and focused (under 50 lines)
- Maximum 3 levels of nesting
- Use early returns to reduce nesting
- DRY (Don't Repeat Yourself) - extract common patterns

### Naming Conventions
- Variables and functions: camelCase
- Classes and components: PascalCase
- Constants: UPPER_SNAKE_CASE
- Boolean variables: prefix with is/has/should/can
- Private class members: prefix with underscore
- Event handlers: prefix with handle (handleClick, handleSubmit)

### Comments
- Use comments to explain "why", not "what"
- Complex algorithms need explanation
- TODO comments should include context and date
- Remove commented-out code (use git history instead)

TypeScript/JavaScript Rules

## TypeScript/JavaScript Standards

### Type Safety
```typescript
// ✅ Do this
interface User {
  id: string;
  email: string;
  name: string;
  role: 'admin' | 'user' | 'guest';
}

const fetchUser = async (id: string): Promise<User> => {
  const response = await api.get<User>(`/users/${id}`);
  return response.data;
};

// ❌ Avoid this
const fetchUser = async (id: any): Promise<any> => {
  const response = await api.get('/users/' + id);
  return response.data;
};


### Modern JavaScript
- Use `const` by default, `let` only when reassignment needed
- Never use `var`
- Prefer arrow functions for callbacks
- Use template literals instead of string concatenation
- Destructuring for object and array access
- Async/await over promise chains
- Optional chaining (`?.`) for safe property access
- Nullish coalescing (`??`) for default values

### Module System
- Named exports preferred over default exports
- Group imports: external → internal → relative → types
- Sort imports alphabetically within groups
- Use barrel exports (index.ts) for cleaner imports

React Rules

## React Development Standards

### Component Structure
```typescript
// Standard component template
interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: 'primary' | 'secondary';
  disabled?: boolean;
}

export const Button = ({ 
  label, 
  onClick, 
  variant = 'primary',
  disabled = false 
}: ButtonProps) => {
  // 1. Hooks
  const [isLoading, setIsLoading] = useState(false);
  
  // 2. Derived state
  const buttonClass = useMemo(() => {
    return `btn btn-${variant} ${disabled ? 'disabled' : ''}`;
  }, [variant, disabled]);
  
  // 3. Event handlers
  const handleClick = useCallback(async () => {
    if (disabled) return;
    
    setIsLoading(true);
    try {
      await onClick();
    } finally {
      setIsLoading(false);
    }
  }, [disabled, onClick]);
  
  // 4. Render
  return (
    <button 
      className={buttonClass}
      onClick={handleClick}
      disabled={disabled || isLoading}
    >
      {isLoading ? 'Loading...' : label}
    </button>
  );
};

React Best Practices

  • Functional components only (no class components)
  • One component per file (except tiny related components)
  • Props interfaces defined separately above component
  • Named exports for all components
  • Custom hooks for reusable stateful logic
  • Keep component logic separate from presentation when complex

React Hooks Rules

  • All hooks at the top level (not in conditions or loops)
  • Consistent hook order across renders
  • Include all dependencies in useEffect/useCallback/useMemo
  • Extract complex effects into custom hooks

Performance

  • React.memo for components with expensive renders
  • useMemo for expensive calculations
  • useCallback for functions passed to memoized child components
  • Lazy load large components and routes
  • Virtual scrolling for lists with 100+ items

Python Rules

## Python Development Standards

### Code Style (PEP 8)
```python
# ✅ Good Python code
from typing import List, Optional
from dataclasses import dataclass
from datetime import datetime

@dataclass
class User:
    """Represents a user in the system."""
    id: str
    email: str
    name: str
    created_at: datetime
    is_active: bool = True

def get_active_users(
    users: List[User],
    min_created_date: Optional[datetime] = None
) -> List[User]:
    """
    Filter users by active status and optional creation date.
    
    Args:
        users: List of User objects to filter
        min_created_date: Optional minimum creation date filter
        
    Returns:
        Filtered list of active users
        
    Raises:
        ValueError: If users list is empty
    """
    if not users:
        raise ValueError("Users list cannot be empty")
    
    active_users = [u for u in users if u.is_active]
    
    if min_created_date:
        active_users = [
            u for u in active_users 
            if u.created_at >= min_created_date
        ]
    
    return active_users

Python Best Practices

  • Type hints for all function signatures
  • Docstrings (Google style) for public functions
  • Use f-strings for string formatting
  • List comprehensions when readable
  • Context managers (with statement) for resources
  • Dataclasses for data structures
  • Never use bare except: - always specify exception type

Testing Rules

## Testing Standards

### Test Coverage Requirements
- Minimum 80% code coverage overall
- 100% coverage for critical business logic
- Test happy path, edge cases, and error conditions
- Integration tests for feature workflows
- E2E tests for critical user journeys

### Test Structure (Arrange-Act-Assert)
```typescript
describe('UserService', () => {
  describe('createUser', () => {
    it('should successfully create a new user with valid data', async () => {
      // Arrange
      const userData = {
        email: 'test@example.com',
        name: 'Test User',
        password: 'SecurePass123!'
      };
      const mockDb = createMockDatabase();
      const service = new UserService(mockDb);
      
      // Act
      const result = await service.createUser(userData);
      
      // Assert
      expect(result.success).toBe(true);
      expect(result.data).toMatchObject({
        email: userData.email,
        name: userData.name
      });
      expect(result.data.id).toBeDefined();
      expect(mockDb.insert).toHaveBeenCalledTimes(1);
    });
    
    it('should reject user creation with invalid email', async () => {
      // Arrange
      const invalidUserData = {
        email: 'not-an-email',
        name: 'Test User',
        password: 'SecurePass123!'
      };
      const service = new UserService(createMockDatabase());
      
      // Act
      const result = await service.createUser(invalidUserData);
      
      // Assert
      expect(result.success).toBe(false);
      expect(result.error).toContain('Invalid email format');
    });
    
    it('should handle database errors gracefully', async () => {
      // Arrange
      const userData = { email: 'test@example.com', name: 'Test', password: 'Pass123!' };
      const mockDb = createMockDatabase();
      mockDb.insert.mockRejectedValue(new Error('Database connection failed'));
      const service = new UserService(mockDb);
      
      // Act
      const result = await service.createUser(userData);
      
      // Assert
      expect(result.success).toBe(false);
      expect(result.error).toContain('Failed to create user');
    });
  });
});

Test Best Practices

  • Descriptive test names explaining what is tested
  • One assertion concept per test
  • Mock external dependencies (APIs, databases, file system)
  • Tests should be independent and idempotent
  • Fast execution (unit tests < 100ms)
  • Use test fixtures for complex setup
  • Test file colocation (UserService.ts → UserService.test.ts)

API Design Rules

## API Development Standards

### RESTful API Conventions

Resource: users

GET    /api/v1/users              - List users (paginated)
GET    /api/v1/users/:id          - Get specific user
POST   /api/v1/users              - Create new user
PUT    /api/v1/users/:id          - Update entire user
PATCH  /api/v1/users/:id          - Partial update user
DELETE /api/v1/users/:id          - Delete user

Nested resources:
GET    /api/v1/users/:id/posts    - Get user's posts
POST   /api/v1/users/:id/posts    - Create post for user

Response Format

// Success response
{
  success: true,
  data: {
    id: "123",
    email: "user@example.com",
    name: "John Doe"
  },
  meta?: {
    pagination?: {
      page: 1,
      pageSize: 20,
      totalPages: 5,
      totalItems: 100
    }
  }
}

// Error response
{
  success: false,
  error: {
    message: "User not found",
    code: "USER_NOT_FOUND",
    details?: {
      userId: "123"
    }
  }
}

HTTP Status Codes

  • 200 OK - Successful GET, PUT, PATCH
  • 201 Created - Successful POST
  • 204 No Content - Successful DELETE
  • 400 Bad Request - Validation error
  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Not authorized
  • 404 Not Found - Resource doesn't exist
  • 409 Conflict - Resource already exists
  • 422 Unprocessable Entity - Semantic error
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

API Best Practices

  • Version all APIs (v1, v2, etc.)
  • Use plural nouns for resources
  • Validate all input data
  • Implement pagination for list endpoints
  • Rate limiting on all public endpoints
  • Proper error messages with context
  • CORS configuration for web clients

Database Rules

## Database Standards

### Schema Design
```sql
-- Standard table structure
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) NOT NULL UNIQUE,
  name VARCHAR(255) NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  is_active BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  deleted_at TIMESTAMP NULL  -- Soft delete
);

-- Add indexes for frequently queried columns
CREATE INDEX idx_users_email ON users(email) WHERE deleted_at IS NULL;
CREATE INDEX idx_users_created_at ON users(created_at) WHERE deleted_at IS NULL;

ORM Best Practices

// ✅ Use ORM with proper typing
const users = await prisma.user.findMany({
  where: {
    deletedAt: null,
    isActive: true
  },
  select: {
    id: true,
    email: true,
    name: true
  },
  orderBy: {
    createdAt: 'desc'
  },
  take: 50
});

// ❌ Avoid raw SQL (SQL injection risk)
const users = await prisma.$queryRaw`
  SELECT * FROM users WHERE email = ${email}
`;

// ✅ If raw SQL needed, use parameterized queries
const users = await prisma.$queryRaw`
  SELECT * FROM users WHERE email = ${email}
`;

Database Best Practices

  • Use UUIDs for primary keys
  • Add created_at, updated_at to all tables
  • Implement soft deletes with deleted_at
  • Foreign keys with ON DELETE CASCADE or SET NULL
  • Indexes on columns used in WHERE, JOIN, ORDER BY
  • Use transactions for multi-table operations
  • Connection pooling for performance
  • Database migrations for all schema changes

Security Rules

## Security Standards

### Environment & Secrets
```bash
# .env file structure
DATABASE_URL=postgresql://user:pass@localhost:5432/db
API_KEY=your-api-key-here
JWT_SECRET=your-jwt-secret-here
NODE_ENV=development

Security Rules:

  • Never commit .env files to git
  • Add .env to .gitignore immediately
  • Use different secrets for dev/staging/prod
  • Rotate secrets regularly
  • Never log sensitive data

Input Validation

import { z } from 'zod';

// Define validation schema
const UserCreateSchema = z.object({
  email: z.string().email('Invalid email format'),
  password: z.string()
    .min(8, 'Password must be at least 8 characters')
    .regex(/[A-Z]/, 'Password must contain uppercase letter')
    .regex(/[0-9]/, 'Password must contain number'),
  name: z.string()
    .min(2, 'Name must be at least 2 characters')
    .max(100, 'Name must be less than 100 characters')
});

// Validate input
const validateUserInput = (input: unknown) => {
  try {
    return UserCreateSchema.parse(input);
  } catch (error) {
    if (error instanceof z.ZodError) {
      throw new ValidationError(error.errors);
    }
    throw error;
  }
};

Authentication & Authorization

  • Hash passwords with bcrypt (minimum cost factor 12)
  • Use JWT for stateless auth or sessions for stateful
  • Implement rate limiting (express-rate-limit)
  • Require re-authentication for sensitive operations
  • Use HTTPS in production always
  • Set secure cookie flags (httpOnly, secure, sameSite)

SQL Injection Prevention

  • Always use parameterized queries
  • Never concatenate user input into SQL
  • Use ORM/query builder properly
  • Validate input before database operations

XSS Prevention

  • Sanitize user input before rendering
  • Use Content Security Policy headers
  • Escape HTML in user-generated content
  • Use React's JSX (auto-escapes by default)

Error Handling Rules

## Error Handling Standards

### Async Error Handling
```typescript
// ✅ Proper async error handling
async function fetchUserData(id: string): Promise<Result<User>> {
  try {
    const response = await api.get(`/users/${id}`);
    return { 
      success: true, 
      data: response.data 
    };
  } catch (error) {
    // Log with context
    console.error('Failed to fetch user:', {
      userId: id,
      error: error instanceof Error ? error.message : 'Unknown error'
    });
    
    // Return user-friendly error
    if (axios.isAxiosError(error)) {
      if (error.response?.status === 404) {
        return { 
          success: false, 
          error: 'User not found' 
        };
      }
      if (error.response?.status === 403) {
        return { 
          success: false, 
          error: 'Access denied' 
        };
      }
    }
    
    return { 
      success: false, 
      error: 'Failed to fetch user data. Please try again later.' 
    };
  }
}

Custom Error Classes

export class AppError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number = 500,
    public isOperational: boolean = true
  ) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

export class ValidationError extends AppError {
  constructor(message: string, public fields?: Record<string, string>) {
    super(message, 'VALIDATION_ERROR', 400);
  }
}

export class NotFoundError extends AppError {
  constructor(resource: string, id: string) {
    super(`${resource} with id ${id} not found`, 'NOT_FOUND', 404);
  }
}

export class UnauthorizedError extends AppError {
  constructor(message: string = 'Unauthorized') {
    super(message, 'UNAUTHORIZED', 401);
  }
}

Error Logging

  • Log all errors with full context
  • Include stack traces in development
  • Sanitize sensitive data before logging
  • Use structured logging (JSON format)
  • Different log levels: error, warn, info, debug
  • Centralized error handling middleware

Git & Version Control Rules

## Git Conventions

### Commit Message Format (Conventional Commits)

<type>(<scope>): <subject>

<body>

<footer>

Commit Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation only
  • style: Code style (formatting, missing semicolons, etc)
  • refactor: Code refactoring (no functional changes)
  • perf: Performance improvement
  • test: Adding or updating tests
  • chore: Maintenance (dependencies, build, etc)

Examples

feat(auth): implement password reset flow

Add email-based password reset with secure token generation.
Tokens expire after 1 hour for security.

Closes #234

---

fix(api): handle null response from payment service

Payment service occasionally returns null instead of error object.
Added null check and appropriate error handling.

Fixes #456

---

refactor(components): extract common button styles

Created shared Button component to reduce code duplication
across Login, Register, and Profile components.

Git Best Practices

  • Commit early and often
  • Keep commits atomic and focused
  • Write clear, descriptive commit messages
  • Always pull before pushing
  • Review your changes before committing
  • Use branches for features (feature/feature-name)
  • Squash commits before merging to main

### Documentation Rules

```markdown
## Documentation Standards

### Code Documentation
```typescript
/**
 * Processes a payment transaction with the payment provider.
 * 
 * This function handles the complete payment flow including validation,
 * provider communication, and transaction recording. If the payment fails,
 * it will be automatically retried up to 3 times with exponential backoff.
 * 
 * @param paymentData - Payment information including amount, currency, and method
 * @param userId - ID of the user making the payment
 * @returns Promise resolving to transaction result with transaction ID
 * 
 * @throws {ValidationError} If payment data is invalid
 * @throws {PaymentError} If payment provider rejects the transaction
 * @throws {NetworkError} If unable to reach payment provider after retries
 * 
 * @example
 * ```typescript
 * const result = await processPayment({
 *   amount: 99.99,
 *   currency: 'USD',
 *   method: 'credit_card',
 *   token: 'tok_...'
 * }, 'user_123');
 * 
 * if (result.success) {
 *   console.log('Transaction ID:', result.transactionId);
 * }
 * ```
 */
async function processPayment(
  paymentData: PaymentData,
  userId: string
): Promise<TransactionResult> {
  // Implementation
}

README Template

# Project Name

Brief description of what this project does.

## Features

- Feature 1
- Feature 2
- Feature 3

## Tech Stack

- Frontend: React, TypeScript, Tailwind CSS
- Backend: Node.js, Express, PostgreSQL
- Testing: Jest, React Testing Library

## Getting Started

### Prerequisites

- Node.js 18+
- PostgreSQL 14+
- npm or yarn

### Installation

\```bash
# Clone the repository
git clone https://github.com/username/project.git

# Install dependencies
cd project
npm install

# Set up environment variables
cp .env.example .env
# Edit .env with your configuration

# Run database migrations
npm run db:migrate

# Start development server
npm run dev
\```

### Running Tests

\```bash
npm test                 # Run all tests
npm run test:watch      # Watch mode
npm run test:coverage   # With coverage report
\```

## Project Structure

\```
src/
  ├── components/      # React components
  ├── pages/          # Page components
  ├── lib/            # Utility functions
  ├── services/       # API services
  ├── hooks/          # Custom React hooks
  └── types/          # TypeScript types
\```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md)

## License

MIT

How to Use These Rules with Cline

Method 1: Custom Instructions in VS Code

  1. Open Cline in VS Code
  2. Click Settings ⚙️
  3. Add instructions:
Follow the coding standards in .clinerules file.
When creating new features:
1. Show implementation plan first
2. Create tests alongside code
3. Run tests to verify
4. Format code before completion
5. Provide summary of changes

Method 2: Project Rules File

Create .clinerules in project root:

# Cline Project Rules

## Tech Stack
- React 18 with TypeScript
- Next.js 14 (App Router)
- Tailwind CSS
- PostgreSQL with Prisma
- Jest + React Testing Library

## Standards
[Copy relevant rules from this guide]

## Current Focus
- Building user authentication system
- Follow security best practices strictly

Method 3: In-Task Instructions

When giving Cline a task:

"Create a user profile component following our React standards:
- TypeScript with proper interfaces
- Functional component with hooks
- Include loading and error states
- Write tests (happy path + error cases)
- Use Tailwind for styling

The component should display user info and allow editing."

Cline-Specific Best Practices

Always Review Before Approving

Cline shows every change before executing:

  • ✅ Read file changes carefully
  • ✅ Check command line operations
  • ✅ Verify file paths are correct
  • ❌ Don't blindly approve everything

Break Large Tasks into Steps

Instead of: "Build complete authentication system"

Do this:

Step 1: "Create database schema for users table with email, password_hash"
Step 2: "Implement user registration API endpoint with validation"
Step 3: "Add password hashing with bcrypt"
Step 4: "Create login endpoint with JWT generation"
Step 5: "Add authentication middleware"

Let Cline Run Tests

After implementation:

"Now run the tests you created to verify everything works"

Cline will execute tests and fix issues if they fail.

Use Cline for Refactoring

"Refactor the UserService class to:
- Extract validation logic into separate validator
- Improve error handling with custom error classes
- Add JSDoc documentation
- Ensure all existing tests still pass"

Leverage Multi-File Capabilities

"Create a new 'products' feature with:
- Product model in src/models/Product.ts
- Product service in src/services/ProductService.ts
- Product API routes in src/pages/api/products/
- React components in src/components/products/
- Tests for all of the above

Follow existing project patterns."

Framework-Specific Rules

Next.js App Router

## Next.js Standards

- Use App Router (not Pages Router)
- Server Components by default
- Mark client components with 'use client' directive
- Use Server Actions for form submissions
- Implement proper loading.tsx and error.tsx
- Metadata API for SEO

File Structure

app/
  ├── (marketing)/
  │   ├── page.tsx           # Homepage (Server Component)
  │   └── about/
  │       └── page.tsx
  ├── (app)/
  │   ├── layout.tsx
  │   ├── dashboard/
  │   │   ├── page.tsx
  │   │   ├── loading.tsx
  │   │   └── error.tsx
  │   └── settings/
  │       └── page.tsx
  └── api/
      └── v1/
          └── users/
              └── route.ts   # API Route Handler

Express.js Backend

## Express.js Standards

- Use TypeScript for type safety
- Async route handlers with express-async-errors
- Centralized error handling middleware
- Request validation middleware (express-validator or Zod)
- Helmet for security headers
- Rate limiting on all routes
- CORS configuration

Project Structure

src/
  ├── routes/
  │   ├── index.ts
  │   └── users.ts
  ├── controllers/
  │   └── userController.ts
  ├── services/
  │   └── userService.ts
  ├── models/
  │   └── User.ts
  ├── middleware/
  │   ├── auth.ts
  │   ├── errorHandler.ts
  │   └── validation.ts
  └── app.ts

Troubleshooting Common Issues

Cline Not Following Your Style

Problem: Code doesn't match your conventions

Solution:

  • Be more explicit in custom instructions
  • Provide examples of preferred patterns
  • Reference existing files: "Follow the pattern in UserController.ts"

Too Many Changes at Once

Problem: Cline makes extensive changes you can't review properly

Solution:

  • Break task into smaller pieces
  • Ask Cline to "show the plan first before implementing"
  • Approve changes incrementally

Tests Failing After Implementation

Problem: Cline creates code but tests don't pass

Solution:

"The tests are failing. Please:
1. Review the test output
2. Fix the implementation
3. Run tests again to verify
4. Explain what was wrong"

Wrong File Locations

Problem: Cline creates files in incorrect directories

Solution: Be explicit about file paths

"Create UserService.ts in src/services/ directory (not src/lib/)"

Complete Example: Task with Full Context

Here's a complete task example with all context:

Task: Create user profile feature

Context:
- Project uses Next.js 14 App Router with TypeScript
- Database: PostgreSQL with Prisma ORM
- Styling: Tailwind CSS
- Testing: Jest + React Testing Library

Requirements:
1. Create Prisma schema for user profiles (add to existing schema)
   - Fields: bio (text), avatar_url (string), location (string)
   
2. Create API endpoint: PATCH /api/v1/users/[id]/profile
   - Validate input with Zod
   - Update user profile in database
   - Return updated profile data
   
3. Create ProfileEdit component (app/dashboard/profile/edit)
   - Form with bio, avatar, location fields
   - Client component with form state
   - Handle submit with Server Action
   - Show loading and error states
   - Success message after save
   
4. Write tests:
   - API endpoint tests (happy path + validation)
   - Component tests (render, submit, error handling)

Follow our coding standards:
- TypeScript strict mode
- Functional components with hooks
- Proper error handling
- 80% test coverage

Please show me the plan first, then implement step by step.

Related Resources


Last Updated: January 2026

Cline's autonomous capabilities are powerful when guided with clear instructions. Start with small tasks to build trust, then gradually delegate more complex work as you refine your rules and communication style!

Enjoyed this article?

Share it with your network

Listings related to Cline Rules: Autonomous Coding Agent Best Practices (2026)