Skip to main content
KiCad follows specific code style guidelines to maintain consistency across the codebase. All contributions should adhere to these standards.

Overview

KiCad uses automated formatting tools to enforce many (but not all) style requirements:
  • clang-format - Primary formatting tool (minimum version 10)
  • uncrustify - Legacy formatting configuration (for reference)
The official style guide is available at: https://dev-docs.kicad.org/en/rules-guidelines/code-style/

Automated Formatting

Using clang-format

The clang-format configuration is stored in _clang-format at the repository root.

Format a Single File

clang-format -i path/to/file.cpp

Check Formatting (Dry Run)

clang-format --dry-run --Werror path/to/file.cpp

Format All Modified Files

git diff --name-only | grep '\.(cpp|h)$' | xargs clang-format -i

CI Format Checks

When you create a merge request, the CI pipeline includes a formatting check. This automatic check is not always 100% correct, so keep in mind:
  1. Exceptions exist: Some formatting guidelines have exceptions or only apply to certain situations. clang-format doesn’t know about these nuances.
  2. Sweeping changes: clang-format may suggest changes to areas of a file near your code, even if you didn’t modify that code. Rule 7 of the style guide: When there is flexibility or doubt, follow the existing formatting of the file you are editing.
  3. Limitations: clang-format doesn’t handle:
    • Column alignment formatting (Rule 4.1.2)
    • Preferred lambda format (Rule 4.10)
    • Alphabetizing #include directives (don’t do this for existing files unless making sweeping changes)

Code Style Configuration

clang-format Settings

Key settings from _clang-format:
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 120

# Bracing
BreakBeforeBraces: Allman

# Spacing
SpacesInParentheses: true
SpaceBeforeParens: Never
PointerAlignment: Left

# Line breaks
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBinaryOperators: NonAssignment
BreakConstructorInitializers: AfterColon

# Functions
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: None

Basic Style Rules

Indentation and Spacing

  • Indentation: 4 spaces (no tabs)
  • Line length: Maximum 120 characters
  • Spaces in parentheses: Yes - foo( a, b ) not foo(a, b)
  • No space before parentheses: function() not function ()

Naming Conventions

Classes and Types:
class MY_CLASS_NAME
{
};

struct MY_STRUCT;
typedef int MY_TYPE;
Functions:
void MyFunction( int aParameter )
{
}
Variables:
int localVariable;          // Local variables: camelCase
int m_memberVariable;       // Member variables: m_ prefix
int g_globalVariable;       // Global variables: g_ prefix
const int MY_CONSTANT = 42; // Constants: ALL_CAPS
Parameters:
void Function( int aParameter )  // Function parameters: a prefix
{
}

Bracing Style (Allman)

if( condition )
{
    // Code here
}
else
{
    // Code here
}

for( int i = 0; i < 10; i++ )
{
    // Code here
}

class MyClass
{
public:
    void MyMethod()
    {
        // Code here
    }
};

Pointer and Reference Alignment

int* pointer;      // Pointer to left
int& reference;    // Reference to left

// Not:
int *pointer;
int &reference;

Header Guards

Use #ifndef include guards:
#ifndef MY_HEADER_H
#define MY_HEADER_H

// Header content

#endif // MY_HEADER_H

Include Order

While clang-format suggests alphabetizing includes, do not alphabetize includes in existing files unless you are making sweeping changes to the include list. Typical include order:
// 1. Corresponding header (for .cpp files)
#include "my_class.h"

// 2. Project headers
#include "project_header.h"

// 3. Library headers
#include <wx/string.h>

// 4. System headers
#include <vector>
#include <string>

C++ Specific Guidelines

Modern C++ (C++20)

KiCad uses C++20. Prefer modern C++ features:
// Use auto when type is obvious
auto result = CalculateSomething();

// Use range-based for loops
for( const auto& item : container )
{
    // ...
}

// Use nullptr instead of NULL
int* ptr = nullptr;

// Use smart pointers when appropriate
std::unique_ptr<MyClass> obj = std::make_unique<MyClass>();

Lambda Functions

clang-format doesn’t support KiCad’s preferred lambda format. Format lambdas manually:
auto lambda = []( int a, int b )
              {
                  return a + b;
              };

Templates

template<typename T>
class MyTemplate
{
    // ...
};

Constructor Initializer Lists

MyClass::MyClass( int aParam1, int aParam2 ) :
        m_member1( aParam1 ),
        m_member2( aParam2 )
{
}

Comments and Documentation

File Headers

All source files should include a license header:
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

Doxygen Comments

Use Doxygen-style comments for classes, functions, and important members:
/**
 * Brief description of the class.
 *
 * Detailed description if needed.
 */
class MY_CLASS
{
public:
    /**
     * Brief description of the function.
     *
     * @param aParameter description of parameter
     * @return description of return value
     */
    int MyFunction( int aParameter );

private:
    int m_value;  ///< Brief member description
};

Inline Comments

// Use double-slash for single-line comments

/*
 * Use block comments for
 * multi-line explanations
 */

wxWidgets Specific

wxString Usage

wxString str = wxT( "String literal" );
wxString formatted = wxString::Format( wxT( "Value: %d" ), value );

Event Handlers

void OnButtonClick( wxCommandEvent& aEvent )
{
    // Handler code
}

Best Practices

Column Alignment (Rule 4.1.2)

When appropriate, align similar code for readability:
int         shortVar       = 1;
int         mediumVariable = 2;
const char* longerVariableName = "value";
Note: clang-format doesn’t support this, so format manually.

Error Handling

if( !DoSomething() )
{
    // Handle error
    return false;
}

Boolean Comparisons

if( condition )     // Good
if( condition == true )  // Avoid

if( !condition )    // Good
if( condition == false ) // Avoid

Magic Numbers

Avoid magic numbers, use named constants:
const int MAX_LAYERS = 32;

if( layerCount > MAX_LAYERS )
{
    // ...
}

User Interface Guidelines

For UI-related code, also follow the User Interface Guidelines:
  • Consistent dialog layouts
  • Proper use of wxWidgets sizers
  • Keyboard shortcuts and mnemonics
  • Accessibility considerations

Pre-Commit Checks

Before committing your changes:
  1. Format your code:
    clang-format -i modified_file.cpp
    
  2. Build without warnings:
    make -j$(nproc)
    
  3. Run tests:
    ctest --output-on-failure
    
  4. Check for style violations:
    clang-format --dry-run --Werror modified_file.cpp
    

When to Deviate

Rule 7: When there is flexibility or doubt, follow the existing formatting of the file you are editing rather than rigidly following clang-format. If you’re modifying an existing file:
  • Match the existing style in that file
  • Don’t reformat code you didn’t change
  • Focus on making your changes consistent with the surroundings

Additional Resources

Next Steps

Now that you understand the code style guidelines:
  1. Practice formatting your code with clang-format
  2. Review existing code to see style in practice
  3. Start contributing with a merge request

Build docs developers (and LLMs) love