FoundryKit

Best Practices

Best practices for using FoundryKit CLI effectively

Best Practices

Learn the best practices for using FoundryKit CLI to create maintainable, efficient, and scalable projects.

Project Organization

Consistent Directory Structure

Maintain a consistent project structure across all your FoundryKit projects.

my-project/
├── src/
   ├── components/
   ├── ui/
   ├── forms/
   └── layout/
   ├── hooks/
   ├── utils/
   ├── types/
   ├── styles/
   └── pages/
├── public/
├── tests/
├── docs/
├── scripts/
├── foundrykit.config.js
├── package.json
└── README.md

Component Organization

Organize components by feature or type for better maintainability.

src/components/
├── ui/           # Reusable UI components
   ├── Button/
   ├── Input/
   └── Modal/
├── forms/        # Form-specific components
   ├── FormField/
   └── FormValidation/
└── layout/       # Layout components
    ├── Header/
    ├── Sidebar/
    └── Footer/

Configuration Management

Environment-Specific Configurations

Use environment-specific configurations for different deployment stages.

// foundrykit.config.js
module.exports = {
  // Base configuration
  build: {
    outDir: 'dist',
    sourcemap: true
  },

  // Environment-specific overrides
  environments: {
    development: {
      dev: {
        port: 3000,
        open: true
      },
      build: {
        sourcemap: true,
        minify: false
      }
    },
    staging: {
      dev: {
        port: 4000
      },
      build: {
        sourcemap: true,
        minify: true
      }
    },
    production: {
      dev: {
        port: 8080,
        open: false
      },
      build: {
        sourcemap: false,
        minify: true
      }
    }
  }
}

Configuration Validation

Validate your configuration to catch errors early.

// foundrykit.config.js
module.exports = {
  // Configuration validation
  validate: {
    project: {
      name: { required: true, type: 'string' },
      version: { required: true, pattern: /^\d+\.\d+\.\d+$/ }
    },
    build: {
      outDir: { required: true, type: 'string' },
      port: { type: 'number', min: 1, max: 65535 }
    }
  },

  // Actual configuration
  project: {
    name: 'my-project',
    version: '1.0.0'
  },
  build: {
    outDir: 'dist',
    port: 3000
  }
}

Development Workflow

Consistent Command Usage

Use consistent command patterns across your team.

# Development
foundrykit dev                    # Start development server
foundrykit dev --port 3001       # Custom port
foundrykit dev --host 0.0.0.0    # External access

# Building
foundrykit build                 # Production build
foundrykit build --watch         # Watch mode
foundrykit build --analyze       # Bundle analysis

# Testing
foundrykit test                  # Run all tests
foundrykit test --watch          # Watch mode
foundrykit test --coverage       # With coverage
foundrykit test --pattern "Button" # Specific tests

# Linting
foundrykit lint                  # Run linting
foundrykit lint --fix            # Auto-fix issues
foundrykit format                # Format code

Git Integration

Set up proper Git hooks for code quality.

// foundrykit.config.js
module.exports = {
  git: {
    hooks: {
      'pre-commit': [
        'foundrykit lint --fix',
        'foundrykit format --write',
        'foundrykit test --watch=false'
      ],
      'pre-push': [
        'foundrykit test --coverage',
        'foundrykit build'
      ]
    }
  }
}

Component Development

Consistent Component Structure

Use consistent patterns for component creation.

# Create components with all necessary files
foundrykit add component Button --typescript --test --docs

# Use consistent naming conventions
foundrykit add component UserProfile
foundrykit add component ProductCard
foundrykit add component NavigationMenu

Component Templates

Create reusable component templates for consistency.

// templates/components/component.tsx
import React from 'react'
import { cn } from '@/lib/utils'

interface {{name}}Props {
  className?: string
  children?: React.ReactNode
  variant?: 'default' | 'primary' | 'secondary'
  size?: 'sm' | 'md' | 'lg'
}

export function {{name}}({ 
  className, 
  children, 
  variant = 'default',
  size = 'md',
  ...props 
}: {{name}}Props) {
  return (
    <div 
      className={cn(
        '{{name}}-component',
        `{{name}}-${variant}`,
        `{{name}}-${size}`,
        className
      )} 
      {...props}
    >
      {children}
    </div>
  )
}

Testing Best Practices

Comprehensive Test Coverage

Set up comprehensive testing for all components and utilities.

// foundrykit.config.js
module.exports = {
  testing: {
    framework: 'jest',
    coverage: {
      enabled: true,
      threshold: {
        global: {
          branches: 80,
          functions: 80,
          lines: 80,
          statements: 80
        }
      }
    },
    patterns: {
      test: '**/*.{test,spec}.{js,jsx,ts,tsx}',
      ignore: ['**/node_modules/**', '**/dist/**']
    }
  }
}

Test Organization

Organize tests to match your component structure.

src/components/
├── Button/
   ├── Button.tsx
   ├── Button.test.tsx
   └── Button.stories.tsx
├── Input/
   ├── Input.tsx
   ├── Input.test.tsx
   └── Input.stories.tsx

Performance Optimization

Build Optimization

Configure build optimizations for better performance.

// foundrykit.config.js
module.exports = {
  build: {
    optimization: {
      splitChunks: {
        chunks: 'all',
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            chunks: 'all'
          }
        }
      },
      treeShaking: true,
      minify: true
    },
    analyze: {
      enabled: true,
      threshold: {
        size: 500000 // 500KB
      }
    }
  }
}

Bundle Size Monitoring

Monitor bundle sizes to prevent performance regressions.

// scripts/check-bundle-size.js
const fs = require('fs')
const path = require('path')

function checkBundleSize() {
  const statsPath = path.join(process.cwd(), 'dist', 'stats.json')
  
  if (!fs.existsSync(statsPath)) {
    console.error('Bundle stats not found. Run build first.')
    process.exit(1)
  }
  
  const stats = JSON.parse(fs.readFileSync(statsPath, 'utf8'))
  const bundleSize = stats.assets.reduce((total, asset) => {
    return total + asset.size
  }, 0)
  
  const maxSize = 500000 // 500KB
  
  if (bundleSize > maxSize) {
    console.error(`❌ Bundle size ${bundleSize} exceeds limit ${maxSize}`)
    process.exit(1)
  }
  
  console.log(`✅ Bundle size: ${bundleSize} bytes`)
}

checkBundleSize()

Security Best Practices

Dependency Management

Regularly update dependencies and audit for security issues.

# Regular security audits
npm audit
foundrykit audit

# Update dependencies
npm update
foundrykit update

# Check for outdated packages
npm outdated

Environment Variables

Properly manage environment variables and secrets.

// foundrykit.config.js
module.exports = {
  env: {
    files: ['.env', '.env.local', '.env.development', '.env.production'],
    required: ['API_KEY', 'DATABASE_URL'],
    defaults: {
      NODE_ENV: 'development',
      PORT: '3000'
    }
  }
}

Documentation

Comprehensive Documentation

Maintain comprehensive documentation for your project.

// foundrykit.config.js
module.exports = {
  documentation: {
    enabled: true,
    output: {
      directory: 'docs',
      format: 'mdx'
    },
    components: {
      include: ['src/components/**/*.{tsx,jsx}'],
      templates: {
        component: './templates/component-doc.mdx'
      }
    }
  }
}

README Maintenance

Keep your README up to date with project information.

# My FoundryKit Project

## Quick Start

```bash
# Install dependencies
npm install

# Start development server
foundrykit dev

# Build for production
foundrykit build

# Run tests
foundrykit test

Project Structure

  • src/components/ - React components
  • src/hooks/ - Custom React hooks
  • src/utils/ - Utility functions
  • tests/ - Test files
  • docs/ - Documentation

Available Scripts

  • foundrykit dev - Start development server
  • foundrykit build - Build for production
  • foundrykit test - Run tests
  • foundrykit lint - Run linting
  • foundrykit format - Format code

## CI/CD Best Practices

### Automated Testing

Set up automated testing in your CI/CD pipeline.

```yaml
# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run linting
        run: foundrykit lint
      
      - name: Run tests
        run: foundrykit test --coverage
      
      - name: Build application
        run: foundrykit build

Deployment Automation

Automate deployment processes for consistency.

// scripts/deploy.js
const { execSync } = require('child_process')

function deploy(environment) {
  console.log(`Deploying to ${environment}...`)
  
  // Build for environment
  execSync(`foundrykit build --env ${environment}`, { stdio: 'inherit' })
  
  // Run tests
  execSync('foundrykit test --ci', { stdio: 'inherit' })
  
  // Deploy
  execSync(`foundrykit deploy ${environment}`, { stdio: 'inherit' })
  
  console.log(`Deployment to ${environment} completed!`)
}

const environment = process.argv[2] || 'staging'
deploy(environment)

Error Handling

Graceful Error Handling

Implement graceful error handling in your CLI scripts.

// scripts/error-handler.js
function handleError(error, context = '') {
  console.error(`❌ Error in ${context}:`, error.message)
  
  if (process.env.NODE_ENV === 'development') {
    console.error('Stack trace:', error.stack)
  }
  
  process.exit(1)
}

process.on('uncaughtException', (error) => {
  handleError(error, 'uncaught exception')
})

process.on('unhandledRejection', (reason, promise) => {
  handleError(reason, 'unhandled rejection')
})

module.exports = { handleError }

Validation Scripts

Create validation scripts to catch issues early.

// scripts/validate.js
const fs = require('fs')
const path = require('path')

function validateProject() {
  const errors = []
  
  // Check required files
  const requiredFiles = [
    'package.json',
    'foundrykit.config.js',
    'src/components',
    'tests'
  ]
  
  requiredFiles.forEach(file => {
    if (!fs.existsSync(file)) {
      errors.push(`Missing required file/directory: ${file}`)
    }
  })
  
  // Check configuration
  try {
    const config = require('../foundrykit.config.js')
    if (!config.project?.name) {
      errors.push('Project name is required in configuration')
    }
  } catch (error) {
    errors.push('Invalid configuration file')
  }
  
  if (errors.length > 0) {
    console.error('❌ Validation failed:')
    errors.forEach(error => console.error(`  - ${error}`))
    process.exit(1)
  }
  
  console.log('✅ Project validation passed')
}

validateProject()

Performance Monitoring

Performance Tracking

Track performance metrics in your development workflow.

// scripts/performance-tracker.js
const fs = require('fs')
const path = require('path')

function trackPerformance() {
  const startTime = process.hrtime.bigint()
  
  return {
    end: () => {
      const endTime = process.hrtime.bigint()
      const duration = Number(endTime - startTime) / 1000000 // Convert to milliseconds
      
      console.log(`⏱️  Operation completed in ${duration.toFixed(2)}ms`)
      
      // Log to performance file
      const performanceLog = {
        timestamp: new Date().toISOString(),
        duration,
        operation: 'build'
      }
      
      fs.appendFileSync(
        'performance.log',
        JSON.stringify(performanceLog) + '\n'
      )
      
      return duration
    }
  }
}

module.exports = { trackPerformance }

Code Quality

Consistent Code Style

Maintain consistent code style across your project.

// foundrykit.config.js
module.exports = {
  linting: {
    eslint: {
      config: {
        extends: [
          'eslint:recommended',
          '@typescript-eslint/recommended',
          'plugin:react/recommended'
        ],
        rules: {
          'prefer-const': 'error',
          'no-unused-vars': 'error',
          'no-console': 'warn'
        }
      }
    },
    prettier: {
      config: {
        semi: false,
        singleQuote: true,
        tabWidth: 2,
        trailingComma: 'es5'
      }
    }
  }
}

Type Safety

Maintain strict type safety throughout your project.

// foundrykit.config.js
module.exports = {
  typescript: {
    config: {
      compilerOptions: {
        strict: true,
        noUnusedLocals: true,
        noUnusedParameters: true,
        noImplicitReturns: true,
        noFallthroughCasesInSwitch: true
      }
    }
  }
}

Common Anti-Patterns

Avoid These Practices

// ❌ Don't ignore configuration validation
module.exports = {
  // Missing required fields
  build: {
    // Missing outDir
  }
}

// ❌ Don't use hardcoded values
module.exports = {
  dev: {
    port: 3000, // Should be configurable
    host: 'localhost' // Should be configurable
  }
}

// ❌ Don't skip error handling
function build() {
  // Missing try-catch
  execSync('build-command')
}

// ❌ Don't ignore performance
module.exports = {
  build: {
    // Missing optimization settings
  }
}

Best Practices Checklist

Before Starting Development

  • Set up consistent project structure
  • Configure environment-specific settings
  • Set up Git hooks for code quality
  • Configure testing framework
  • Set up linting and formatting

During Development

  • Use consistent command patterns
  • Write comprehensive tests
  • Maintain documentation
  • Monitor bundle sizes
  • Follow security best practices

Before Deployment

  • Run full test suite
  • Check bundle size limits
  • Validate configuration
  • Review security audit
  • Update documentation

Maintenance

  • Regularly update dependencies
  • Monitor performance metrics
  • Review and refactor code
  • Update documentation
  • Conduct security audits

Next Steps