Skip to main content
CVAT follows strict coding standards to maintain code quality and consistency across the project. This guide covers the style guidelines for different programming languages used in CVAT.

General Principles

  • Write readable code: Code is read more often than written
  • Be consistent: Follow existing patterns in the codebase
  • Document your code: Add comments for complex logic
  • Keep it simple: Avoid unnecessary complexity
  • Test your changes: Ensure code works as expected

Python Code Style

CVAT’s Python code follows PEP 8 with some modifications enforced by Black and isort.

Formatters and Linters

Black

Black is used for automatic code formatting with these settings:
[tool.black]
line-length = 100
target-version = ['py310']
Format your Python code:
black cvat/

isort

Isort organizes imports with Black-compatible settings:
[tool.isort]
profile = "black"
line_length = 100
forced_separate = ["tests"]
Sort imports:
isort cvat/

pylint

Pylint is used for static code analysis. Run it to check for issues:
pylint cvat/

Python Style Guidelines

  • Line length: Maximum 100 characters
  • Indentation: 4 spaces (no tabs)
  • Imports: Group imports (standard library, third-party, local) and sort alphabetically
  • Naming conventions:
    • Classes: PascalCase
    • Functions and variables: snake_case
    • Constants: UPPER_SNAKE_CASE
    • Private members: _leading_underscore

Example

from typing import List, Optional

import django
from rest_framework import serializers

from cvat.apps.engine.models import Task


class TaskSerializer(serializers.ModelSerializer):
    """Serializer for Task model with custom validation."""

    def validate_name(self, value: str) -> str:
        """Validate that task name is not empty."""
        if not value.strip():
            raise serializers.ValidationError("Task name cannot be empty")
        return value

    class Meta:
        model = Task
        fields = "__all__"

JavaScript/TypeScript Code Style

The frontend uses ESLint and Prettier for code quality and formatting.

ESLint Configuration

CVAT uses a strict ESLint configuration based on Airbnb style guide:
// Key rules
{
  "indent": ["error", 4],
  "max-len": ["error", { "code": 120 }],
  "quotes": ["error", "single"],
  "semi": ["error", "always"]
}

Prettier Configuration

Prettier enforces consistent formatting:
{
  "printWidth": 120,
  "tabWidth": 4,
  "singleQuote": true,
  "semi": true,
  "trailingComma": "all",
  "arrowParens": "always",
  "jsxSingleQuote": true
}

Running Linters

Check code style:
# ESLint
yarn run lint

# Prettier
yarn run prettier --check .
Auto-fix issues:
# ESLint
yarn run lint --fix

# Prettier
yarn run prettier --write .

TypeScript/JavaScript Style Guidelines

  • Line length: Maximum 120 characters
  • Indentation: 4 spaces
  • Quotes: Single quotes for strings, JSX props use single quotes
  • Semicolons: Always required
  • Naming conventions:
    • Interfaces/Types: PascalCase
    • Functions/Variables: camelCase
    • Constants: UPPER_SNAKE_CASE
    • React components: PascalCase
    • Private members: _leadingUnderscore

TypeScript Example

import React from 'react';
import { Task } from 'cvat-core-wrapper';

interface TaskItemProps {
    task: Task;
    onSelect: (taskId: number) => void;
}

export default function TaskItem({ task, onSelect }: TaskItemProps): JSX.Element {
    const handleClick = (): void => {
        onSelect(task.id);
    };

    return (
        <div className='task-item' onClick={handleClick}>
            <h3>{task.name}</h3>
            <p>{task.status}</p>
        </div>
    );
}

File Organization

Python Files

# Copyright header
# SPDX-License-Identifier: MIT

"""Module docstring describing the file purpose."""

# Standard library imports
import os
import sys

# Third-party imports
import django
from rest_framework import viewsets

# Local imports
from cvat.apps.engine.models import Task

# Constants
MAX_RETRY_COUNT = 3

# Module code

TypeScript/JavaScript Files

// Copyright (C) CVAT.ai Corporation
// SPDX-License-Identifier: MIT

// External imports
import React from 'react';
import { useSelector } from 'react-redux';

// CVAT imports
import { Task } from 'cvat-core-wrapper';

// Local imports
import './styles.scss';

// Constants
const MAX_ITEMS_PER_PAGE = 10;

// Component code

Comments and Documentation

Python Docstrings

Use Google-style docstrings:
def create_task(name: str, owner_id: int, labels: List[str]) -> Task:
    """Create a new annotation task.

    Args:
        name: The task name
        owner_id: ID of the task owner
        labels: List of label names

    Returns:
        The created Task instance

    Raises:
        ValidationError: If task name is invalid
    """
    pass

TypeScript/JSDoc Comments

/**
 * Calculate the annotation completion percentage
 * @param completed - Number of completed frames
 * @param total - Total number of frames
 * @returns Percentage value between 0 and 100
 */
function calculateProgress(completed: number, total: number): number {
    return (completed / total) * 100;
}

Git Commit Messages

Write clear, descriptive commit messages:
Short summary (50 chars or less)

Detailed explanation of the changes if needed. Wrap at 72 characters.
Explain the problem this commit solves and why this approach was chosen.

- Use bullet points for multiple changes
- Reference issues: Fixes #123, Resolves #456
- Break lines at 72 characters
Good commit message examples:
  • Fix annotation export for rotated bounding boxes
  • Add support for video chapters in frame navigation
  • Refactor task creation to improve performance
  • Update dependencies to fix security vulnerabilities

Pre-commit Hooks

CVAT uses linters in CI/CD. Before committing, run:
# Python
black cvat/
isort cvat/
pylint cvat/

# JavaScript/TypeScript
yarn run lint --fix
yarn run prettier --write .

Code Review Guidelines

When reviewing code:
  • Check for adherence to style guidelines
  • Verify tests are included and passing
  • Look for potential bugs or edge cases
  • Ensure code is readable and maintainable
  • Provide constructive feedback
  • Approve when requirements are met

Security Considerations

ESLint includes security plugins:
plugins: ['security', 'no-unsanitized']
Always:
  • Sanitize user input
  • Avoid eval() and similar dangerous functions
  • Use parameterized queries for database access
  • Validate and escape data before rendering

Editor Configuration

VS Code

Recommended extensions:
  • Python (Microsoft)
  • Pylance
  • ESLint
  • Prettier
  • EditorConfig
Settings:
{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "python.formatting.provider": "black",
  "python.linting.pylintEnabled": true
}

PyCharm/WebStorm

Configure:
  • Black as the Python formatter
  • ESLint for JavaScript/TypeScript
  • Prettier for auto-formatting
  • Line length to 100 (Python) or 120 (JS/TS)

Continuous Integration

CVAT’s CI runs these checks on every pull request:
  • Linters: ESLint, Pylint, Black, isort
  • Type checking: TypeScript compiler, mypy
  • Security: CodeQL analysis
  • Tests: Unit, integration, and E2E tests
Ensure your code passes all checks before submitting a PR.

Next Steps

Build docs developers (and LLMs) love