---
title: LLMs Best Practices - Common
url: https://colingoudie.me/llms.txt
description: Universal coding conventions for AI-assisted development
related:
- https://colingoudie.me/llms-rails.txt
- https://colingoudie.me/llms-nextjs.txt
- https://colingoudie.me/llms-node.txt
---
# LLMs Best Practices - Common
Include this in your CLAUDE.md or similar AI assistant configuration file.
## File Size Limits
- Maximum 150-250 lines per file
- Split larger files into logical modules
- Each file should have a single responsibility
## UI Components
### shadcn/ui Wrapper Pattern
Always wrap shadcn/ui components in your own components:
```tsx
// components/ui/button.tsx - Your wrapper
import { Button as ShadcnButton } from "@/components/shadcn/button";
export function Button({ children, ...props }) {
return {children};
}
```
This allows project-wide customisation without modifying vendor code.
### Cursor Styles
Always apply appropriate cursor styles:
- cursor-pointer: All clickable elements (buttons, links, interactive cards)
- cursor-not-allowed: Disabled states
- cursor-wait: Loading states
- cursor-grab / cursor-grabbing: Draggable elements
### No Native Browser Dialogs
Never use:
- alert()
- confirm()
- prompt()
Use proper UI components (modals, toasts, dialogs) instead.
## Code Principles
### SOLID Principles
- Single Responsibility: One reason to change per module
- Open/Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes must be substitutable
- Interface Segregation: Many specific interfaces over one general
- Dependency Inversion: Depend on abstractions, not concretions
### DRY (Don't Repeat Yourself)
- Extract repeated logic into reusable functions
- Use composition over inheritance
- Create shared utilities for common patterns
## TypeScript Conventions
```typescript
// Prefer interfaces for object shapes
interface User {
id: string;
name: string;
email: string;
}
// Use type for unions, intersections, and mapped types
type Status = "pending" | "active" | "archived";
// Always type function parameters and returns
function getUser(id: string): Promise {
// ...
}
// Avoid any - use unknown if type is truly unknown
function parseData(input: unknown): User {
// Validate and narrow the type
}
```
## React Conventions
```tsx
// Functional components only
function UserCard({ user }: { user: User }) {
return {user.name}
;
}
// Prefer named exports
export function UserCard() {}
// Co-locate related code
// components/
// UserCard/
// UserCard.tsx
// UserCard.test.tsx
// useUserCard.ts
```
## Package Manager
Always use pnpm:
```bash
pnpm install
pnpm add
pnpm remove
```
Never use npm or yarn unless the project explicitly requires it.
## Error Handling
```typescript
// Use Result types for expected errors
type Result =
| { ok: true; value: T }
| { ok: false; error: E };
// Throw for unexpected errors only
// Use try/catch at boundaries (API routes, event handlers)
```
## Testing
- Write tests for business logic
- Use descriptive test names: it("should return null when user not found")
- Prefer integration tests over excessive unit tests
- Mock external services, not internal modules