pyRevit tutorial: install it and make your first button
From installation to your own button on the ribbon that counts your model. With the folder structure, a working script and the problems everyone runs into.
Short answer: download pyRevit from the official releases page and install it; a pyRevit tab appears in Revit. Create a folder MyTools.extension containing MyTools.tab/Pipes.panel/Count pipes.pushbutton/script.py, add that folder in the pyRevit settings and choose Reload. Your button is now on the ribbon.
What is pyRevit?
pyRevit is a free, open-source add-in for Revit. It turns Python scripts into ribbon buttons: you write a script.py file, pyRevit makes a button for it, and a click runs your script with access to the whole Revit API. No Visual Studio, no compiling.
By default pyRevit runs your scripts in IronPython 2.7. That is Python as it was around 2010: f-strings do not exist there yet. You can choose Python 3 (CPython) per script with #! python3 on the first line, but not all pyRevit helper modules work then. So in buttons, prefer "{}".format(value): it works in both.
Installing pyRevit
- Close Revit.
- Download the installer from the official pyRevit releases page. At the time of writing (October 2026) the latest version is 6.4.0, supporting Revit up to and including 2027.
- Install and start Revit. You will see a new pyRevit tab on the ribbon.
At work you often need your IT department for the installation. pyRevit is open source and does not send anything out on its own, which helps with that conversation. Meanwhile you can already practise without Revit, for example in PyPath.
The folder structure of an extension
A set of your own buttons is called an extension in pyRevit. It is simply a folder with subfolders; the suffixes of the folder names decide what ends up where on the ribbon:
MyTools.extension/
MyTools.tab/
Pipes.panel/
Count pipes.pushbutton/
script.py
bundle.yaml
icon.png.extension: the whole set. Keep it in its own folder, for exampleDocuments/pyRevit..tab: your own ribbon tab, named after the part before the dot..panel: a group of buttons within that tab..pushbutton: one button. The folder name is the label under the button.
Later you add a lib folder next to the tab with your own functions; pyRevit makes it available to all your buttons automatically. Step 5 of Learning Python for Revit shows how.
Your first script.py
Start with a button that only reads: counting how many pipes are in the model. Reading can never break anything.
# -*- coding: utf-8 -*-
from pyrevit import revit, DB, forms
count = (DB.FilteredElementCollector(revit.doc)
.OfCategory(DB.BuiltInCategory.OST_PipeCurves)
.WhereElementIsNotElementType()
.GetElementCount())
forms.alert("This model contains {} pipes.".format(count),
title="Count pipes")Count pipes: This model contains 45 pipes.- The first line tells IronPython the file is UTF-8. You need it as soon as you use characters such as é or ².
revit.docis the active model;DBisAutodesk.Revit.DB.- The FilteredElementCollector finds the pipes;
WhereElementIsNotElementType()leaves out the pipe types. forms.alertshows a message in Revit. Prefer a list? Useprint(): pyRevit then opens an output window.
Loading the button
- In Revit, open the pyRevit tab and open the settings.
- Under Custom Extension Directories, add the folder that contains
MyTools.extension. So the folder above it, not the extension itself. - Save the settings and choose Reload. The MyTools tab appears with your button.
If you then only change script.py, you will see the change on the next click. New buttons, new folder names or a different icon need a Reload.
Title, tooltip and icon
With a bundle.yaml file next to the script you give the button a proper title and a tooltip that appears when you hover over it:
title: Count pipes
tooltip: Counts all pipes in the active model.
author: My nameAn icon.png in the same folder becomes the icon. If you use Revit's dark theme, you can add an icon.dark.png next to it.
When it does not work
- The button does not appear. Are the suffixes right (
.extension,.tab,.panel,.pushbutton)? Did you add the folder above the extension? And did you press Reload? SyntaxErroron a line withf"...". The default engine is IronPython 2.7, which has no f-strings. Write"{}".format(...), or put#! python3on the first line.- Strange characters or an encoding error. Put
# -*- coding: utf-8 -*-at the top of the script. forms.alertdoes not work. Under the Python 3 enginepyrevit.formsis not available; useprint()there.Attempt to modify the model outside of transaction.Your script changes something outside a transaction. See this guide on that error.
More about pyRevit itself is in the pyRevit documentation.