View on GitHub
FreeCAD Addon Academy

Structuring

There are two common ways to lay out a FreeCAD addon: a Modern, namespaced structure used by the current addon templates, and a Legacy structure that keeps Python files at the top level with Init.py and InitGui.py.

New addons should prefer the Modern layout. It is what both the Addon-Template and the workbench starter kit produce by default, it places the addon’s code in its own namespace rather than in FreeCAD’s global namespace, and it opens up the possibility of using standard Python packaging tools (such as pip and uv) for installing the addon and managing its development dependencies.

The two layouts at a glance:

Modern (recommended)          Legacy
MyAddon/                      MyAddon/
β”œβ”€ package.xml                β”œβ”€ package.xml
└─ freecad/                   β”œβ”€ Init.py
   └─ MyAddon/                └─ InitGui.py
      β”œβ”€ __init__.py
      └─ init_gui.py

The remaining sections detail each side.

Modern

In the Modern layout, all of the addon’s Python code lives under a freecad/<ModName>/ subdirectory, a namespace package under the shared freecad import namespace. The top of the repository contains only metadata, documentation, resources, and packaging files; no Python source sits at the top level.

A typical Modern addon looks like this:

MyAddon/
β”œβ”€ freecad/
β”‚  └─ MyAddon/
β”‚     β”œβ”€ __init__.py
β”‚     └─ init_gui.py
β”œβ”€ Documentation/
β”œβ”€ Resources/
β”‚  β”œβ”€ Icons/
β”‚  β”‚  └─ Logo.svg
β”‚  └─ Media/
β”œβ”€ LICENSE-Code
β”œβ”€ LICENSE-Assets
β”œβ”€ README.md
β”œβ”€ package.xml
└─ pyproject.toml

Code

Additional Python modules for the addon’s tools and commands also live inside freecad/MyAddon/.

Metadata & packaging

Legacy

The legacy layout predates namespaced packaging and is still supported. From the wiki’s Workbench creation page:

You need a folder, with any name you like, placed in the user Mod directory, with an Init.py file, and, optionally an InitGui.py file. The Init.py file is executed when FreeCAD starts, and the InitGui.py file is executed immediately after, but only when FreeCAD starts in GUI mode. That’s all it needs for FreeCAD to find your workbench at startup and add it to its interface.

The workbench’s directory should look like this (at a minimum):

MyWorkbench/
β”œβ”€ Init.py
β”œβ”€ InitGui.py
└─ package.xml

Of course any real workbench will likely have many more files, subdirectories, resources, etc., but none of that is dictated by FreeCAD. Any additional Python files sit alongside Init.py and InitGui.py at the top level of the addon folder.

The wiki describes this as β€œthe classic way of creating a new workbench.” Unless you are maintaining an existing legacy addon, prefer the Modern layout above.