This guide provides an overview of pyRevit’s architecture to help new contributors understand how the software works.
Whether you want to create tools, troubleshoot issues, or contribute code, understanding these components will help you navigate the project.
-
pyRevit Add-In (pyRevitLoader) —
dev/pyRevitLoader/- A small piece of C# code that starts pyRevit inside Revit.
- Calls the C# session manager directly to build the UI and button commands (no IronPython bootstrap).
-
pyRevit Python Libraries (pyrevitlib) —
pyrevitlib/pyrevit/- Python packages that simplify working with the .NET Revit API.
- Provide tools to create ribbon buttons, run scripts, and more.
-
Extensions — see Extensions for bundle structure,
bundle.yaml, script engines, and hooks.- These are the tools and features users see inside Revit.
- They are mostly written in python, but can also be C#/VB.NET scripts, dynamo projects, and so on
- Bundled extensions appear in the "pyRevit" tab, offering many tools.
- Users can add extensions by:
- Enabling listed extensions in
extensions/extensions.jsonvia the "Extensions" button in pyRevit. - Creating custom extensions and adding their paths to the configuration.
- Enabling listed extensions in
-
pyRevit Command-Line Interface (CLI) —
dev/pyRevitLabs/pyRevitCLI/- A tool for managing configurations, running scripts in bulk, and troubleshooting.
- Useful for corporate setups and advanced users.
- The
pyrevit envreport includes the configured CPython engine version (activeCpythonEngineVersionin JSON).
-
Telemetry Server
- A small server (written in Go) that tracks usage data of pyRevit tools.
- Stores data in MongoDB or PostgreSQL for business intelligence.
Command execution itself lives in a separate component, PyRevit.Runtime (dev/pyRevitLabs.PyRevit.Runtime/) — see How pyRevit Commands run.
!!! tip "TL;DR:"
- Revit reads the `.addin` manifest in the Addins folders
- The `.addin` manifest points to `pyRevitLoader.dll`
- `pyRevitLoader.dll` calls the C# session manager to build the UI and the button commands
- The C# session manager runs `session_preload.py` / `session_postload.py` to drive the Python services that have not yet been ported to C#
- The installer creates a file with
.addinextension, called manifest, in the Revit Addins folder, instructing Revit to load pyRevit when it starts. - The Addins folder can be located in one of these paths, depending on pyRevit installation:
C:\ProgramData\Autodesk\Revit\Addins(for all users)%APPDATA%\Autodesk\Revit\Addins(for the current user only)
- The manifest points to
pyRevitLoader.dll, which acts as the entry point for pyRevit.
The pyRevitLoader.dll file is a small C# program that:
- Ensures required .NET assemblies are loaded.
- Calls the C# session manager to load the session.
???+ info
the source code is in `PyRevitLoaderApplication.cs` and it is an implementation of the Revit API `IExternalApplication` _interface_ (the standard way to create a plugin for Revit).
There are multiple versions of pyRevitLoader.dll to support:
- different Revit versions:
- One for Revit 2025 and newer, built with .NET 8.
- Another for Revit 2021-2024, built with the .NET Framework.
- different IronPython versions; to this date:
- version 2.7.12, the default one
- version 3.4.2, more recent but not fully tested.
They share the same source code, but are compiled against the different .net runtimes and IronPython versions.
The legacy pure-Python loader (which supported pre-2021 Revit versions) has been removed; the C# loader requires Revit 2021+.
!!! note
Only one IronPython runtime engine can be attached at a time; switching it (Settings UI or `pyrevit attach`) rewrites the `.addin` manifest to the matching `pyRevitLoader.dll` build. CPython selection is separate and doesn't touch the manifest. Manifests can also go stale from clone switches or mixed attachments — `pyrevit attach`/`switch` fixes them by recreating the manifest.
PyRevitLoaderApplication.OnStartup calls SessionManagerService.LoadSession, which:
- Runs
session_preload.pyto set up environment variables, the logging/script console, update checks, telemetry, and API routes. - Loads extensions and creates UI elements like ribbons and buttons in C# (see below).
- Registers and activates hooks, which enable features like event-driven scripts.
- Runs
session_postload.pyto finalize the session (cleanup, doc colorizer, routes server, output teardown).
A reload re-enters the same LoadSession entry, so initial startup and reload share one code path.
???+ info
`session_preload.py` and `session_postload.py` are small scripts that call
[pyrevit.loader.sessionmgr.perform_preload][] and
[pyrevit.loader.sessionmgr.perform_postload][]. They drive the residual Python
session services that have not yet been ported to C#.
- pyRevit scans known paths and user defined folders to find extensions.
- For each extension, it builds a .net assembly to create buttons, tabs, and other UI elements.
???+ info
Extensions directories are detected by [pyrevit.userconfig.PyRevitConfig.get_ext_root_dirs][].
Extension components discovery is performed by [pyrevit.extensions.extensionmgr.get_installed_ui_extensions][].
Assemblies are generated by [pyrevit.loader.asmmaker][] with types from [pyrevit.runtime.create_type][].
!!! tip "TL;DR:"
Command execution is handled by the c# project `pyRevitLabs.Pyrevit.Runtime`
Each button generated by the Extension discovery is bound to a command derived by the ScriptCommand.cs source code.
This code deals with:
- detecting the modifier keys hold while clicking the button, and change the behavior accordingly
- calling
ScriptExcecutor.ExcecuteScriptpassing the python script (or any other supportesd script) for the command
???+ info
The `ScriptCommand` class implements Revit’s `IExternalCommand` interface.
The `Execute` method is the one called when you click the Ribbon button.
In turn, the code in ScriptExecutor.cs calls the appropriate script engine based on the type of (IronPython, CPython, .NET, and so on).
???+ info
You can find the code of the engines in the files that end with `Engine.cs`, in `dev/pyRevitLabs.PyRevit.Runtime/`:
- `IronPythonEngine.cs` — default Python engine.
- `CPythonEngine.cs` — modern Python (3.12).
- `CLREngine.cs` — C#/VB.NET execution.
- `DynamoBIMEngine.cs` — Dynamo graphs.
- `GrasshopperEngine.cs` — Grasshopper definitions.