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
freecad/MyAddon/__init__.py: package initializer; runs when the namespace is first imported.freecad/MyAddon/init_gui.py: registers the Workbench, toolbars, and commands with FreeCADβs GUI.
Additional Python modules for the addonβs tools and commands also live inside freecad/MyAddon/.
Metadata & packaging
package.xml: the addon manifest read by the Addon Manager.pyproject.toml: standard Python project metadata; consumed bypip,uv, or any PEP 517-compatible tool, typically to install development dependencies such asfreecad-stubsandpyside6.CHANGELOG.md,README.md, and license files. It is conventional to split licenses by what they cover, e.g.LICENSE-CodeandLICENSE-Assets(see Licensing).
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.pyfile, and, optionally anInitGui.pyfile. TheInit.pyfile is executed when FreeCAD starts, and theInitGui.pyfile 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.
Init.py: executed even when FreeCAD is running in console mode; typically used for file importers, exporters, and other non-GUI setup.InitGui.py: executed only when FreeCAD starts in GUI mode; registers the Workbench class with FreeCADβs UI.
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.
Related
- Addon Manifest: the
package.xmlfile read by the Addon Manager.