Created: 2025-01-27
Last Modified: 2025-01-27
Last Modified Summary: Initial comprehensive best practices document covering web development, design, UX/UI, content, and AI slop prevention
- AI Slop Prevention
⚠️ CRITICAL - Web Development
- Web Design
- Mobile & Responsive Design
- User Experience (UX)
- User Interface (UI)
- Content Management
- Code Quality Principles
- File & Project Organization
- Security Best Practices
- Performance Optimization
- Testing Standards
- Documentation Standards
- Inspection Checklist
AI slop includes:
- Duplicate files with similar functionality
- Conflicting implementations of the same feature
- Unused or orphaned files created but never integrated
- Redundant code that violates DRY principles
- Inconsistent patterns across similar components
- Dead code that serves no purpose
- Over-engineered solutions when simpler ones exist
BEFORE creating ANY new file, component, function, or feature:
-
✅ Search the codebase thoroughly
- Use semantic search to find existing implementations
- Check for similar functionality in related directories
- Look for naming variations (e.g.,
ButtonvsBtnvsButtonComponent)
-
✅ Verify file doesn't already exist
- Check exact file path and name
- Check for similar files in different locations
- Review imports to see what's actually being used
-
✅ Check for conflicting patterns
- Ensure new code follows existing patterns
- Don't mix different architectural approaches
- Maintain consistency with project conventions
-
✅ Verify single source of truth
- Don't duplicate constants, types, or utilities
- Use shared components instead of creating new ones
- Import from existing modules rather than copying code
-
✅ Confirm integration points
- Ensure new code integrates with existing systems
- Don't create isolated code that won't be used
- Verify dependencies and imports are correct
-
Never create duplicate functionality
- If a component exists, extend it rather than creating a new one
- If a utility function exists, import and use it
- If a type/interface exists, reuse it
-
Never create conflicting implementations
- Don't create
Button.tsxifcomponents/ui/Button.tsxexists - Don't create
utils/helpers.tsiflib/utils.tsexists - Don't create multiple ways to do the same thing
- Don't create
-
Always check before creating
# Search for existing implementations grep -r "functionName" src/ find . -name "*similar-name*" # Use semantic search tools
-
Consolidate, don't duplicate
- Merge similar files instead of keeping both
- Refactor to use shared utilities
- Create abstractions for common patterns
-
Remove unused code immediately
- Delete files that aren't imported anywhere
- Remove functions that are never called
- Clean up commented-out code
🚩 Multiple files with similar names:
Button.tsx,ButtonComponent.tsx,Btn.tsxutils.ts,helpers.ts,utilities.tstypes.ts,interfaces.ts,models.ts
🚩 Conflicting implementations:
- Same function in multiple files
- Different patterns for the same feature
- Inconsistent naming conventions
🚩 Orphaned files:
- Files with no imports
- Unused components
- Dead code paths
🚩 Over-engineering:
- Complex solutions for simple problems
- Unnecessary abstractions
- Premature optimization
# Find duplicate function names
grep -r "function.*name" src/ | sort | uniq -d
# Find files with similar names
find src/ -type f -name "*.tsx" | sort
# Find unused imports (requires tools like ts-prune)
npx ts-prune
# Find duplicate code blocks
npx jscpd src/
# Check for conflicting exports
grep -r "export.*from" src/ | sort✅ DO:
- Create small, focused, single-responsibility components
- Use composition over inheritance
- Extract reusable logic into custom hooks
- Keep components under 200 lines when possible
- Use TypeScript for all components
❌ DON'T:
- Create monolithic components that do everything
- Duplicate component logic
- Mix business logic with presentation
- Use
anytypes - Create components without proper typing
✅ DO:
- Use React hooks (useState, useEffect, useContext) for local state
- Use server state management (React Query, SWR) for API data
- Keep state as close to where it's used as possible
- Use context for truly global state only
- Implement proper loading and error states
❌ DON'T:
- Prop drill through many levels
- Store everything in global state
- Mix server and client state incorrectly
- Forget to handle loading/error states
// ✅ GOOD: Clear structure
src/
components/
ui/
Button.tsx
Input.tsx
features/
auth/
LoginForm.tsx
lib/
utils.ts
api.ts
types/
index.ts
// ❌ BAD: Unorganized
src/
Button.tsx
button.tsx
Btn.tsx
utils.ts
helpers.ts✅ DO:
- Define interfaces for all props and data structures
- Use type inference where appropriate
- Create shared types in
types/directory - Use discriminated unions for complex states
- Export types alongside components
❌ DON'T:
- Use
anytype - Create duplicate type definitions
- Use
@ts-ignorewithout explanation - Mix
interfaceandtypeinconsistently
✅ DO:
- Use RESTful conventions
- Version APIs (
/api/v1/...) - Return consistent response formats
- Implement proper error handling
- Use HTTP status codes correctly
- Document all endpoints
❌ DON'T:
- Create inconsistent endpoint patterns
- Return different response structures
- Ignore error cases
- Mix concerns in single endpoints
// ✅ GOOD: Consistent error handling
export async function handler(req: Request) {
try {
const data = await processRequest(req);
return Response.json({ success: true, data }, { status: 200 });
} catch (error) {
if (error instanceof ValidationError) {
return Response.json(
{ success: false, error: error.message },
{ status: 400 }
);
}
return Response.json(
{ success: false, error: 'Internal server error' },
{ status: 500 }
);
}
}✅ DO:
- Validate all input data
- Sanitize user inputs
- Use parameterized queries (prevent SQL injection)
- Implement rate limiting
- Use HTTPS only
- Store secrets in environment variables
- Implement proper authentication/authorization
❌ DON'T:
- Trust client-side validation alone
- Expose sensitive data in responses
- Hardcode credentials
- Skip input validation
- Allow SQL injection vulnerabilities
✅ DO:
- Normalize data appropriately (3NF minimum)
- Use appropriate data types
- Create indexes on frequently queried columns
- Use foreign keys for relationships
- Add constraints for data integrity
- Document schema decisions
❌ DON'T:
- Create redundant columns
- Use generic types (VARCHAR(255) for everything)
- Forget indexes on foreign keys
- Skip constraints
- Create circular dependencies
✅ DO:
- Use indexes effectively
- Avoid N+1 queries
- Use joins appropriately
- Limit result sets
- Use prepared statements
- Monitor slow queries
❌ DON'T:
- Select all columns when not needed
- Use subqueries when joins would work
- Forget to paginate large results
- Ignore query performance
✅ DO:
- Use proper HTTP methods (GET, POST, PUT, PATCH, DELETE)
- Use resource-based URLs (
/api/users/:id) - Return appropriate status codes
- Implement pagination for lists
- Use query parameters for filtering
- Version your API
❌ DON'T:
- Use GET for mutations
- Create inconsistent URL patterns
- Return 200 for errors
- Forget pagination on large datasets
- Mix versions in same endpoint
// ✅ GOOD: Consistent response structure
{
success: true,
data: { ... },
meta?: { pagination, ... }
}
// Error response
{
success: false,
error: {
code: "VALIDATION_ERROR",
message: "Invalid input",
details?: { ... }
}
}✅ DO:
- Maintain visual hierarchy
- Use consistent spacing system
- Follow brand guidelines
- Ensure sufficient contrast (WCAG AA minimum)
- Use whitespace effectively
- Create clear visual flow
❌ DON'T:
- Use too many fonts
- Ignore accessibility
- Create cluttered layouts
- Use low contrast text
- Break brand consistency
✅ DO:
- Use design system colors
- Maintain color consistency
- Test color combinations for accessibility
- Use semantic color names
- Document color usage
❌ DON'T:
- Use arbitrary color values
- Create new colors without system approval
- Ignore contrast ratios
- Use colors inconsistently
✅ DO:
- Use consistent font families
- Establish clear type scale
- Maintain readable line heights
- Use appropriate font weights
- Ensure responsive typography
❌ DON'T:
- Mix too many font families
- Use inconsistent sizes
- Create unreadable text
- Ignore mobile typography
✅ DO:
- Design for mobile screens first
- Use mobile-first CSS (min-width media queries)
- Test on real devices
- Consider touch targets (minimum 44x44px)
- Optimize for mobile performance
❌ DON'T:
- Design desktop first and shrink
- Use fixed pixel widths
- Create tiny touch targets
- Ignore mobile performance
// ✅ GOOD: Consistent breakpoints
const breakpoints = {
sm: '640px', // Mobile landscape
md: '768px', // Tablet
lg: '1024px', // Desktop
xl: '1280px', // Large desktop
'2xl': '1536px' // Extra large
}✅ DO:
- Use flexible grids (CSS Grid, Flexbox)
- Use relative units (rem, em, %)
- Implement responsive images
- Test at all breakpoints
- Use container queries where appropriate
❌ DON'T:
- Use fixed widths
- Ignore different screen sizes
- Load large images on mobile
- Create horizontal scroll
✅ DO:
- Make interactive elements at least 44x44px
- Add adequate spacing between touch targets
- Provide visual feedback for touches
- Support swipe gestures where appropriate
- Test on actual touch devices
❌ DON'T:
- Create tiny buttons
- Place links too close together
- Ignore touch feedback
- Assume mouse-only interactions
✅ DO:
- Understand user needs and goals
- Create user personas
- Map user journeys
- Test with real users
- Iterate based on feedback
- Prioritize user goals over technical elegance
❌ DON'T:
- Design for yourself
- Ignore user feedback
- Create complex flows
- Assume users understand technical terms
✅ DO:
- Create clear, intuitive navigation
- Use consistent navigation patterns
- Provide breadcrumbs for deep pages
- Include search functionality
- Make navigation accessible
❌ DON'T:
- Hide important navigation
- Create confusing menu structures
- Use inconsistent navigation patterns
- Forget mobile navigation
✅ DO:
- Optimize for fast load times
- Show loading states
- Implement progressive loading
- Minimize perceived wait time
- Optimize images and assets
❌ DON'T:
- Make users wait without feedback
- Load everything at once
- Ignore performance metrics
- Create slow interactions
✅ DO:
- Provide immediate feedback for actions
- Show success/error messages clearly
- Use loading indicators
- Confirm destructive actions
- Explain errors in user-friendly language
❌ DON'T:
- Leave users guessing
- Use technical error messages
- Skip confirmation dialogs
- Hide important feedback
✅ DO:
- Use design system components
- Maintain consistent styling
- Follow established patterns
- Reuse components
- Document component usage
❌ DON'T:
- Create one-off components
- Use inconsistent styling
- Reinvent existing components
- Ignore design system
✅ DO:
- Use semantic HTML
- Add ARIA labels where needed
- Ensure keyboard navigation
- Maintain focus management
- Test with screen readers
- Meet WCAG 2.1 AA standards
❌ DON'T:
- Use divs for buttons
- Ignore keyboard users
- Create inaccessible forms
- Skip ARIA attributes
- Forget focus states
✅ DO:
- Use size, color, and spacing to create hierarchy
- Make important elements prominent
- Group related content
- Use whitespace effectively
- Guide user attention
❌ DON'T:
- Make everything the same size
- Create visual noise
- Ignore content hierarchy
- Overuse emphasis
✅ DO:
- Provide clear affordances
- Use consistent interaction patterns
- Add hover/focus states
- Implement smooth transitions
- Make interactions predictable
❌ DON'T:
- Create confusing interactions
- Use inconsistent patterns
- Skip hover states
- Make jarring transitions
✅ DO:
- Write clear, concise content
- Use plain language
- Structure content with headings
- Write for your audience
- Keep content up-to-date
- Use consistent tone and voice
❌ DON'T:
- Use jargon unnecessarily
- Write walls of text
- Create outdated content
- Ignore user needs
- Mix tones inconsistently
✅ DO:
- Use descriptive page titles
- Write meaningful meta descriptions
- Use proper heading hierarchy (h1 → h2 → h3)
- Optimize images with alt text
- Create semantic HTML structure
- Use descriptive URLs
❌ DON'T:
- Keyword stuff
- Use generic titles
- Ignore meta descriptions
- Skip alt text
- Create confusing URLs
✅ DO:
- Use short paragraphs
- Break up text with headings
- Use lists for multiple items
- Include relevant images
- Make content scannable
- Use consistent formatting
❌ DON'T:
- Create long paragraphs
- Use walls of text
- Ignore visual breaks
- Skip formatting
✅ DO:
- Extract common logic into functions
- Create reusable components
- Use shared utilities
- Abstract repeated patterns
- Create configuration files
❌ DON'T:
- Copy-paste code
- Duplicate logic
- Create similar functions
- Repeat configuration
- Single Responsibility: Each function/component does one thing
- Open/Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes must be substitutable
- Interface Segregation: Many specific interfaces > one general
- Dependency Inversion: Depend on abstractions, not concretions
✅ DO:
- Separate business logic from presentation
- Keep API logic separate from UI
- Isolate data fetching
- Separate styling from structure
- Keep utilities independent
❌ DON'T:
- Mix concerns in single files
- Couple unrelated logic
- Embed business logic in components
- Mix data and presentation
✅ DO:
- Store constants in one place
- Use shared type definitions
- Centralize configuration
- Maintain one design system
- Use version control properly
❌ DON'T:
- Duplicate constants
- Create multiple type definitions
- Scatter configuration
- Maintain multiple design systems
✅ DO:
- Create small, focused modules
- Use clear module boundaries
- Minimize dependencies
- Export clean APIs
- Document module purpose
❌ DON'T:
- Create monolithic modules
- Create tight coupling
- Export everything
- Mix unrelated functionality
✅ DO:
- Follow established project structure
- Group related files together
- Use clear naming conventions
- Organize by feature when appropriate
- Keep structure flat when possible
❌ DON'T:
- Create random file locations
- Nest too deeply
- Use inconsistent naming
- Mix organizational patterns
✅ DO:
- Use descriptive names
- Follow language conventions (camelCase, PascalCase)
- Use consistent file extensions
- Name files to match exports
- Use kebab-case for file names
❌ DON'T:
- Use abbreviations
- Create confusing names
- Mix naming conventions
- Use generic names (utils.ts, helpers.ts)
✅ DO:
- Place scripts in
/scripts/{category}/ - Place tests in
__tests__/directories - Place docs in
/docs/ - Place config in root or
/config/ - Group related files
❌ DON'T:
- Create files in root (except config)
- Scatter related files
- Mix file types
- Create duplicate directories
✅ DO:
- Use secure authentication methods
- Implement proper session management
- Use HTTPS everywhere
- Validate permissions on server
- Use secure password hashing
- Implement rate limiting
❌ DON'T:
- Store passwords in plain text
- Trust client-side auth only
- Skip authorization checks
- Expose sensitive endpoints
✅ DO:
- Encrypt sensitive data
- Sanitize all inputs
- Use parameterized queries
- Implement CSRF protection
- Set secure cookies
- Validate data types
❌ DON'T:
- Trust user input
- Expose sensitive data
- Skip input validation
- Use SQL string concatenation
✅ DO:
- Store secrets in environment variables
- Use
.envfiles for local development - Never commit secrets
- Rotate credentials regularly
- Use different keys for dev/prod
❌ DON'T:
- Hardcode secrets
- Commit
.envfiles - Share credentials
- Use production keys in dev
✅ DO:
- Code split routes and components
- Lazy load images and components
- Minimize bundle size
- Use efficient rendering (React.memo, useMemo)
- Optimize images (WebP, proper sizing)
- Minimize re-renders
❌ DON'T:
- Load everything upfront
- Use unoptimized images
- Create unnecessary re-renders
- Ignore bundle size
✅ DO:
- Use database indexes
- Implement caching strategies
- Optimize queries
- Use connection pooling
- Implement pagination
- Monitor performance
❌ DON'T:
- Create N+1 queries
- Skip indexes
- Load all data at once
- Ignore slow queries
✅ DO:
- Compress images
- Use modern image formats (WebP, AVIF)
- Minify CSS/JS
- Use CDN for static assets
- Implement caching headers
- Optimize fonts
❌ DON'T:
- Use unoptimized images
- Skip minification
- Ignore caching
- Load unnecessary assets
✅ DO:
- Write unit tests for utilities
- Test components in isolation
- Write integration tests for flows
- Test error cases
- Maintain >80% coverage for critical code
- Test accessibility
❌ DON'T:
- Skip testing
- Only test happy paths
- Test implementation details
- Ignore edge cases
✅ DO:
- Keep tests close to code
- Use descriptive test names
- Follow AAA pattern (Arrange, Act, Assert)
- Mock external dependencies
- Clean up after tests
❌ DON'T:
- Create tests far from code
- Use vague test names
- Test multiple things in one test
- Leave test data around
✅ DO:
- Document public APIs
- Use JSDoc for functions
- Explain complex logic
- Keep comments up-to-date
- Document decisions (ADRs)
❌ DON'T:
- Document obvious code
- Leave outdated comments
- Skip public API docs
- Ignore complex logic
✅ DO:
- Keep README current
- Document architecture
- Explain setup process
- Include examples
- Update when code changes
❌ DON'T:
- Leave stale documentation
- Skip setup instructions
- Ignore architecture changes
- Create duplicate docs
✅ DO:
- Include created_date (YYYY-MM-DD)
- Include last_modified_date
- Include last_modified_summary
- Keep documentation organized
- Update docs with code changes
❌ DON'T:
- Skip date tracking
- Leave docs outdated
- Create scattered documentation
- Ignore documentation updates
Use this checklist when inspecting the codebase for adherence to best practices:
- No duplicate files with similar functionality
- No conflicting implementations
- All files are imported/used
- No orphaned code
- Single source of truth maintained
- Consistent patterns throughout
- DRY principle followed
- Single responsibility maintained
- Separation of concerns clear
- Modular architecture
- TypeScript types properly used
- No
anytypes (unless justified)
- Files in correct directories
- Consistent naming conventions
- No files in root (except config)
- Clear directory structure
- Related files grouped together
- Consistent design system usage
- Responsive design implemented
- Accessibility standards met (WCAG AA)
- Mobile-first approach
- Clear visual hierarchy
- Consistent UI patterns
- Images optimized
- Code splitting implemented
- Lazy loading used appropriately
- Bundle size reasonable
- Database queries optimized
- Caching implemented
- No hardcoded secrets
- Input validation implemented
- Authentication/authorization proper
- HTTPS enforced
- Environment variables used
- SQL injection prevented
- Code documented appropriately
- README current
- Architecture documented
- API documented
- Examples provided
- Dates tracked in docs
- Critical paths tested
- Error cases covered
- Accessibility tested
- Performance tested
- Integration tests exist
If you see these, investigate immediately:
🚩 Multiple similar files (Button.tsx, ButtonComponent.tsx, Btn.tsx)
🚩 Duplicate functions in different files
🚩 Unused imports or files
🚩 Conflicting patterns for same feature
🚩 Hardcoded values that should be config
🚩 Missing error handling
🚩 No TypeScript types
🚩 Inconsistent naming
🚩 Files in wrong locations
🚩 Dead code or commented-out blocks
🚩 Circular dependencies
🚩 Tight coupling between modules
🚩 Missing documentation for public APIs
🚩 Accessibility violations
🚩 Performance issues (N+1 queries, large bundles)
- Review relevant sections before starting work
- Use the inspection checklist before committing
- Reference specific sections when making decisions
- Update this document when patterns change
- ALWAYS check AI Slop Prevention section first
- Search codebase before creating anything
- Follow the "DO/DON'T" patterns strictly
- Use the inspection checklist after changes
- Reference this document when making recommendations
- Use the inspection checklist
- Check for red flags
- Verify adherence to relevant sections
- Ensure no AI slop introduced
This document should be:
- Reviewed quarterly
- Updated when patterns change
- Referenced in all development work
- Used as basis for code reviews
- Enforced in CI/CD where possible
Remember: The goal is maintainable, high-quality code that avoids AI slop and follows best practices. When in doubt, prioritize clarity, consistency, and maintainability.