frigate/.github/copilot-instructions.md
Josh Hawkins 50ac5a1483
Some checks failed
CI / AMD64 Build (push) Has been cancelled
CI / ARM Build (push) Has been cancelled
CI / Jetson Jetpack 6 (push) Has been cancelled
CI / AMD64 Extra Build (push) Has been cancelled
CI / ARM Extra Build (push) Has been cancelled
CI / Synaptics Build (push) Has been cancelled
CI / Assemble and push default build (push) Has been cancelled
Miscellaneous fixes (0.17 beta) (#21764)
* Add 640x640 Intel NPU stats

* use css instead of js for reviewed button hover state in filmstrip

* update copilot instructions to copy HA's format

* Set json schema for genai

---------

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
2026-01-25 18:59:25 -07:00

10 KiB

GitHub Copilot Instructions for Frigate NVR

This document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection.

Project Overview

Frigate NVR is a realtime object detection system for IP cameras that uses:

  • Backend: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX
  • Frontend: React with TypeScript, Vite, TailwindCSS
  • Architecture: Multiprocessing design with ZMQ and MQTT communication
  • Focus: Minimal resource usage with maximum performance

Code Review Guidelines

When reviewing code, do NOT comment on:

  • Missing imports - Static analysis tooling catches these
  • Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting
  • Minor style inconsistencies already enforced by linters

Python Backend Standards

Python Requirements

  • Compatibility: Python 3.13+
  • Language Features: Use modern Python features:
    • Pattern matching
    • Type hints (comprehensive typing preferred)
    • f-strings (preferred over % or .format())
    • Dataclasses
    • Async/await patterns

Code Quality Standards

  • Formatting: Ruff (configured in pyproject.toml)
  • Linting: Ruff with rules defined in project config
  • Type Checking: Use type hints consistently
  • Testing: unittest framework - use python3 -u -m unittest to run tests
  • Language: American English for all code, comments, and documentation

Logging Standards

  • Logger Pattern: Use module-level logger

    import logging
    
    logger = logging.getLogger(__name__)
    
  • Format Guidelines:

    • No periods at end of log messages
    • No sensitive data (keys, tokens, passwords)
    • Use lazy logging: logger.debug("Message with %s", variable)
  • Log Levels:

    • debug: Development and troubleshooting information
    • info: Important runtime events (startup, shutdown, state changes)
    • warning: Recoverable issues that should be addressed
    • error: Errors that affect functionality but don't crash the app
    • exception: Use in except blocks to include traceback

Error Handling

  • Exception Types: Choose most specific exception available

  • Try/Catch Best Practices:

    • Only wrap code that can throw exceptions
    • Keep try blocks minimal - process data after the try/except
    • Avoid bare exceptions except in background tasks

    Bad pattern:

    try:
        data = await device.get_data()  # Can throw
        # ❌ Don't process data inside try block
        processed = data.get("value", 0) * 100
        result = processed
    except DeviceError:
        logger.error("Failed to get data")
    

    Good pattern:

    try:
        data = await device.get_data()  # Can throw
    except DeviceError:
        logger.error("Failed to get data")
        return
    
    # ✅ Process data outside try block
    processed = data.get("value", 0) * 100
    result = processed
    

Async Programming

  • External I/O: All external I/O operations must be async
  • Best Practices:
    • Avoid sleeping in loops - use asyncio.sleep() not time.sleep()
    • Avoid awaiting in loops - use asyncio.gather() instead
    • No blocking calls in async functions
    • Use asyncio.create_task() for background operations
  • Thread Safety: Use proper synchronization for shared state

Documentation Standards

  • Module Docstrings: Concise descriptions at top of files

    """Utilities for motion detection and analysis."""
    
  • Function Docstrings: Required for public functions and methods

    async def process_frame(frame: ndarray, config: Config) -> Detection:
        """Process a video frame for object detection.
    
        Args:
            frame: The video frame as numpy array
            config: Detection configuration
    
        Returns:
            Detection results with bounding boxes
        """
    
  • Comment Style:

    • Explain the "why" not just the "what"
    • Keep lines under 88 characters when possible
    • Use clear, descriptive comments

File Organization

  • API Endpoints: frigate/api/ - FastAPI route handlers
  • Configuration: frigate/config/ - Configuration parsing and validation
  • Detectors: frigate/detectors/ - Object detection backends
  • Events: frigate/events/ - Event management and storage
  • Utilities: frigate/util/ - Shared utility functions

Frontend (React/TypeScript) Standards

Internationalization (i18n)

  • CRITICAL: Never write user-facing strings directly in components

  • Always use react-i18next: Import and use the t() function

    import { useTranslation } from "react-i18next";
    
    function MyComponent() {
      const { t } = useTranslation(["views/live"]);
      return <div>{t("camera_not_found")}</div>;
    }
    
  • Translation Files: Add English strings to the appropriate json files in web/public/locales/en

  • Namespaces: Organize translations by feature/view (e.g., views/live, common, views/system)

Code Quality

  • Linting: ESLint (see web/.eslintrc.cjs)
  • Formatting: Prettier with Tailwind CSS plugin
  • Type Safety: TypeScript strict mode enabled
  • Testing: Vitest for unit tests

Component Patterns

  • UI Components: Use Radix UI primitives (in web/src/components/ui/)
  • Styling: TailwindCSS with cn() utility for class merging
  • State Management: React hooks (useState, useEffect, useCallback, useMemo)
  • Data Fetching: Custom hooks with proper loading and error states

ESLint Rules

Key rules enforced:

  • react-hooks/rules-of-hooks: error
  • react-hooks/exhaustive-deps: error
  • no-console: error (use proper logging or remove)
  • @typescript-eslint/no-explicit-any: warn (always use proper types instead of any)
  • Unused variables must be prefixed with _
  • Comma dangles required for multiline objects/arrays

File Organization

  • Pages: web/src/pages/ - Route components
  • Views: web/src/views/ - Complex view components
  • Components: web/src/components/ - Reusable components
  • Hooks: web/src/hooks/ - Custom React hooks
  • API: web/src/api/ - API client functions
  • Types: web/src/types/ - TypeScript type definitions

Testing Requirements

Backend Testing

  • Framework: Python unittest
  • Run Command: python3 -u -m unittest
  • Location: frigate/test/
  • Coverage: Aim for comprehensive test coverage of core functionality
  • Pattern: Use TestCase classes with descriptive test method names
    class TestMotionDetection(unittest.TestCase):
        def test_detects_motion_above_threshold(self):
            # Test implementation
    

Test Best Practices

  • Always have a way to test your work and confirm your changes
  • Write tests for bug fixes to prevent regressions
  • Test edge cases and error conditions
  • Mock external dependencies (cameras, APIs, hardware)
  • Use fixtures for test data

Development Commands

Python Backend

# Run all tests
python3 -u -m unittest

# Run specific test file
python3 -u -m unittest frigate.test.test_ffmpeg_presets

# Check formatting (Ruff)
ruff format --check frigate/

# Apply formatting
ruff format frigate/

# Run linter
ruff check frigate/

Frontend (from web/ directory)

# Start dev server (AI agents should never run this directly unless asked)
npm run dev

# Build for production
npm run build

# Run linter
npm run lint

# Fix linting issues
npm run lint:fix

# Format code
npm run prettier:write

Docker Development

AI agents should never run these commands directly unless instructed.

# Build local image
make local

# Build debug image
make debug

Common Patterns

API Endpoint Pattern

from fastapi import APIRouter, Request
from frigate.api.defs.tags import Tags

router = APIRouter(tags=[Tags.Events])

@router.get("/events")
async def get_events(request: Request, limit: int = 100):
    """Retrieve events from the database."""
    # Implementation

Configuration Access

# Access Frigate configuration
config: FrigateConfig = request.app.frigate_config
camera_config = config.cameras["front_door"]

Database Queries

from frigate.models import Event

# Use Peewee ORM for database access
events = (
    Event.select()
    .where(Event.camera == camera_name)
    .order_by(Event.start_time.desc())
    .limit(limit)
)

Common Anti-Patterns to Avoid

Avoid These

# Blocking operations in async functions
data = requests.get(url)  # ❌ Use async HTTP client
time.sleep(5)  # ❌ Use asyncio.sleep()

# Hardcoded strings in React components
<div>Camera not found</div>  # ❌ Use t("camera_not_found")

# Missing error handling
data = await api.get_data()  # ❌ No exception handling

# Bare exceptions in regular code
try:
    value = await sensor.read()
except Exception:  # ❌ Too broad
    logger.error("Failed")

Use These Instead

# Async operations
import aiohttp
async with aiohttp.ClientSession() as session:
    async with session.get(url) as response:
        data = await response.json()

await asyncio.sleep(5)  # ✅ Non-blocking

# Translatable strings in React
const { t } = useTranslation();
<div>{t("camera_not_found")}</div>  # ✅ Translatable

# Proper error handling
try:
    data = await api.get_data()
except ApiException as err:
    logger.error("API error: %s", err)
    raise

# Specific exceptions
try:
    value = await sensor.read()
except SensorException as err:  # ✅ Specific
    logger.exception("Failed to read sensor")

Project-Specific Conventions

Configuration Files

  • Main config: config/config.yml

Directory Structure

  • Backend code: frigate/
  • Frontend code: web/
  • Docker files: docker/
  • Documentation: docs/
  • Database migrations: migrations/

Code Style Conformance

Always conform new and refactored code to the existing coding style in the project:

  • Follow established patterns in similar files
  • Match indentation and formatting of surrounding code
  • Use consistent naming conventions (snake_case for Python, camelCase for TypeScript)
  • Maintain the same level of verbosity in comments and docstrings

Additional Resources