This is the complete guide to RST — what it does, how to set it up, and how to build and share toolbar profiles. Written for Revit admins and users who want a clean, curated ribbon.
What Is RST
v0.5.0-beta — functional but still in active development. Use at your own risk.
RST is a pyRevit extension that lets administrators build custom toolbar profiles from any installed Revit tool or add-in. Instead of digging through default tabs and third-party panels, users load a single profile and get a purpose-built ribbon with only the tools they need.
Admins detect available tools, arrange them into colored panels, add company branding, and export profiles as shareable JSON files. Users load a profile and get a clean ribbon that rebuilds automatically every time Revit starts.
RST doesn't replace your tools — it reorganises them. Every button still executes the original command. RST just decides which ones show up and where.
Install
Requirements
- Windows 10/11
- Revit 2024+
- pyRevit 4.8+ — the extension framework RST runs on
- Python 3.12 — required for the UI windows (pywebview). Python 3.14+ is not yet compatible.
- Microsoft Edge WebView2 runtime — ships with Windows 11 and modern Windows 10. Older systems install from Microsoft.
1. Install pyRevit
Download and run the latest pyRevit installer (4.8+) from pyRevit releases. Open Revit once after install to confirm the pyRevit tab appears on the ribbon.
2. Install Python 3.12 + pywebview
Open PowerShell and run:
- x64 Windows (most machines):
winget install --id Python.Python.3.12 --scope user - ARM64 Windows (Surface Pro X, Copilot+ PCs, Parallels on Apple Silicon):
winget install --id Python.Python.3.12 --scope user --architecture x64— pywebview's native dependencies don't ship ARM64 builds, and Revit itself is x64.
Then install pywebview and verify:
py -3.12 -m pip install --user pywebviewpy -3.12 -c "import webview; print('ok')"— should printok
No winget? It ships with Windows 11 and modern Windows 10. If missing, install App Installer from the Microsoft Store first. Optional: install.bat in the repo root automates this step (winget check + Python 3.12 + pywebview, user-scope only, no admin required).
3. Add the RST Extension
- Open Revit
- pyRevit tab → Extensions → Add Extension
- Paste the repo URL:
https://github.com/jedbjorn/RST - Reload pyRevit (pyRevit tab → Reload, or restart Revit)
An RST tab appears in the Revit ribbon. Click Profiler to start building toolbar profiles, or Loader to open an existing one.
How It Works
Architecture
RST runs two processes: one inside Revit (IronPython) for ribbon building and button scripts, and one outside (CPython 3.12 + pywebview) for the admin and user UIs. They communicate through temporary JSON files. No persistent services, no background processes.
On Revit Launch
When Revit starts, startup.py reads active_profile.json and rebuilds the ribbon:
- Loads the profile referenced in
active_profile.json - Removes any existing
REST_*tabs from the ribbon - Builds the branding panel (logo, always leftmost)
- Creates colored panels with rounded-corner backgrounds
- Adds large tool buttons with PostCommand handlers
- Adds small tool groups (standard-sized text-only buttons)
- Deletes pyRevit's MinifyUI smartbutton folder (if present) to avoid conflicts
- On Idling event: styles RST admin panels grey, hides tabs configured in RSTify, sets RSTify icon to orange
The ribbon rebuilds from scratch every launch. Custom tabs don't persist natively in Revit — RST reconstructs them each time.
Profiler Flow (Admin)
- Click Profiler — IronPython scans the ribbon (1400+ commands) and loaded add-ins, writes
_revit_data.json, launches the CPython UI - Admin detects tools, creates panels, picks colors, adds tools/stacks/URLs, sets branding
- Export — saves profile JSON to
app/profiles/+ Desktop copy — animated overlay — window auto-closes (3s)
Loader Flow (User)
- Click Loader — IronPython collects Revit version + loaded add-ins, writes
_loader_data.json, launches the CPython UI - User browses profiles, sees tab preview, checks add-in compatibility (Native / Loaded / Not Loaded)
- User configures RSTify tab toggles — choose which tabs to hide (source tabs and core tabs are locked visible)
- Load Profile — writes
active_profile.jsonwith profile + hidden tabs — animated overlay — window auto-closes (3s) - ProfileLoader detects the change — shows "Reloading pyRevit..." with animated dots —
sessionmgr.reload()— ribbon rebuilds with hidden tabs applied
Add-in Detection
RST scans the live Revit session using AdWindows.dll and categorises every tool it finds:
| Status | Meaning |
|---|---|
| Native | Built-in Revit tab (Architecture, View, Manage, etc.) — always available |
| Loaded | Add-in tab detected in current session (DiRootsOne, pyRevit, Kinship, etc.) |
| Not Loaded | Required by profile but not found in this session |
The RST Tab
Tool panels with rounded grey backgrounds.
Profiler
Build and edit toolbar profiles. The admin-facing tool where profile creation happens.
- Detect scans every ribbon tab for installed tools
- Search and filter tools by name or source tab
- Create panels with custom colors (hex input + swatches) and opacity (10–100%)
- Add tools via checkbox, drag to reorder
- Create tool stacks — 2–3 small buttons stacked vertically
- A tool can only live in one place. Adding to a stack removes it from standalone; greyed tools show "Go to [location]" on click
- + Add URL for custom URL buttons and
mailto:email links (persistent across sessions) - Icon picker with 50 built-in icons and search bar
- Add Logo for company branding (48×48, resized automatically)
- Set Protection — admin panel for locking/protecting add-ins from disable operations
- Export — animated overlay with file paths — auto-closes. Active profiles can be re-exported with a reload warning.
Loader
Load and manage profiles. The user-facing tool for switching between profiles.
- Header: Revit version (live from session), Add Profile from Path
- Profile cards with tab preview and required add-in status
- RSTify tab toggles — two-column layout: hide tabs (left 1/3) + required add-ins (right 2/3)
- Disable unused add-ins toggle — preview which add-ins stay active vs get disabled before confirming
- Load Profile — auto-closes, triggers pyRevit reload
- Restore All Add-ins — one-click re-enable of all RST-disabled add-ins
- Unload or delete profiles (writes
BlankRSTmarker so the tab stays alive with branding only)
RSTify
Custom tab visibility manager that replaces pyRevit's MinifyUI. Click to toggle — orange icon when hiding, blue when showing. Tabs to hide are configured in the Profile Loader at load time. Auto-activates on every startup/reload when a profile has hidden tabs. No configuration from the button itself — reload the profile to change which tabs are hidden.
Update
Downloads the latest zip from GitHub, preserves user data (profiles, active profile, branding logo, config, custom tools, log), copies new files (skipping locked ones), and auto-reloads with an animated message.
Health
Point-in-time snapshot of the workstation and Revit session. Launched via the Snap pushbutton; also runs automatically when RST loads so data is fresh by the time the user opens the window.
What it shows — four collapsible sections, each with a severity dot (ok / soft-warn / warn / danger) driven by threshold rules:
- Hardware — CPU (name, cores, live %used), RAM (total, used %), GPU (model, driver, VRAM), Disk C: (SSD/HDD, total, free, used %). Dynamic values are color-coded; identity fields stay neutral.
- Display & Network — primary resolution, monitor count, active adapter + link speed.
- Revit — version + build, Revit username, hardware acceleration setting (from
Revit.ini), active model name + path + file size (size thresholds at 1 / 1.5 / 2 GB), warnings count with severity breakdown. - Operating System — Windows name, release, build.
How it gets the data
- RAM / CPU% — Win32 API via
ctypes(GlobalMemoryStatusEx,GetSystemTimes). CPU% is a 500ms-delta snapshot. - CPU name / cores / OS build — registry (
HKLM\HARDWARE\...\CentralProcessor) + Pythonplatformmodule. - GPU / Network adapter / Disk type / Monitors — single PowerShell call against WMI (
Win32_VideoController,Win32_NetworkAdapter,Get-PhysicalDisk,Win32_DesktopMonitor). - Revit session data — Revit API on the IronPython side (version, build, username, active model, warnings).
- Hardware acceleration flag — parsed from
%APPDATA%\Autodesk\Revit\Autodesk Revit <ver>\Revit.ini. - Model file size — .NET
FileInfoon the local file. For ACC / BIM 360 cloud models, falls back to walking%LOCALAPPDATA%\Autodesk\Revit\<ver>\CollaborationCache(matching by project/model GUID when available, otherwise newest.rvtmtime).
Triggers
- On RST load — fire-and-forget background scan (~1–3s), no model context since no document is open yet.
- On Snap click — synchronous scan with full Revit context, so the viewer opens on fresh data. Clean Junk Files and Close buttons live in the viewer footer.
Privacy: everything stays on the workstation. The viewer reads data/health_scan.json from the extension folder. No network calls, nothing sent anywhere.
Clean Junk Files
Bottom-right button in the Health viewer. Opens a modal with per-category toggles (all ON by default):
- Windows Temp Files — everything in
%LOCALAPPDATA%\Temp - Revit PacCache — Revit package cache
- Revit Journals — all journal files, every installed Revit version
- Collaboration Cache — central model cache, excluding today's activity
Confirm → delete → result message with per-category counts. Files locked by running applications are skipped automatically. Safe to run with Revit open — anything Revit holds open survives.
Reload
Triggers a pyRevit reload to apply changes.
Custom URL Tools
Add buttons that open URLs or email clients directly from the Revit ribbon — company wikis, SharePoint, Teams, or any web resource.
- In the Profiler, click + Add URL at the bottom of the tool list
- Enter a name (e.g. "Company Wiki") and a URL. Email addresses are auto-detected and converted to
mailto:links. - The tool appears tagged "Custom" with a link icon (🔗) or @ icon for email — add it to any panel like a regular tool
- In Revit, clicking opens the URL in the default browser (or default email client for
mailto:) - Revit ribbon automatically uses
pack:link_externalfor URLs andpack:atfor email tools
Custom tools persist in app/custom_tools.json. They can be edited, deleted, and survive Detect scans and profile export/import.
RSTify — Tab Visibility
RSTify replaces pyRevit's MinifyUI with profile-aware tab hiding. Instead of a global show/hide, it remembers which tabs to hide per profile and applies them automatically on every load.
How It Works
- Open the Profile Loader and select a profile
- The RSTify: Hide These Tabs column shows all ribbon tabs with toggles
- Core tabs (Modify, Manage, View, Annotate, Add-Ins) are locked — cannot be hidden
- Source tabs (tabs containing tools used by your profile) are locked — hiding them would break tools
- Everything else can be toggled off
- Click Load Profile — hidden tab selections are saved with the profile
- On every reload, configured tabs are hidden automatically
Hiding a tab prevents tools from that tab from executing via PostCommand. RST protects source tabs from being hidden — only tabs with no tools in your profile can be toggled off.
The RSTify Button
| Icon Color | State | Click Action |
|---|---|---|
| Orange | Tabs are hidden | Show all tabs |
| Blue | All tabs visible | Re-hide configured tabs |
Previous hidden tab selections are remembered when you reopen the Loader. Tabs you hid last time are pre-toggled.
MinifyUI
RST automatically deletes pyRevit's MinifyUI smartbutton folder when a profile is loaded, to avoid conflicts. To restore MinifyUI after removing RST: unload the RST profile (creates a blank tab), then reinstall pyRevit.
Branding
Every profile tab includes a branding panel as the leftmost element. By default it shows the RST logo. To use your company logo:
- In the Profiler, click Add Logo
- Upload your image (48×48 recommended — resized automatically)
- The logo persists across sessions and updates at
icons/branding.png
The branding panel is not stored in the profile JSON — it's injected at runtime so each install can have its own logo.
Panel Styling
Colors
Two rows of swatches: 8 built-in presets (Blue, Green, Purple, Amber, Red, Cyan, Orange, Lime) and 8 custom slots (initially blank, shown as dashed outlines).
Persistent color config — swatch colors are stored in app/panel_colors.json and persist across sessions. Click a swatch to select it, type a hex code (with or without #, spaces stripped), then click ✓ to write the color to that swatch. Click ✕ to reset — built-in swatches restore factory color, custom swatches clear back to blank. All 16 swatches update live across the panel list, tab preview, and panel slot cards.
Opacity
A per-profile slider controls panel background opacity from 10% to 100%. Applied to all panels in the profile.
Rounded Corners
Panel backgrounds use WPF DrawingBrush with RectangleGeometry for rounded corners. RST admin panels get a light grey background, applied after pyRevit finishes loading.
Tool Name Display
Long tool names are auto-split at the first space for compact two-line display on the ribbon.
Finding Colors
The Profiler includes a link to imagecolorpicker.com — upload a logo or brand guide and click any pixel to grab the hex code.
Profile JSON
Profiles are self-contained JSON files. They can be shared via email, OneDrive, Slack, or any file transfer. Each profile includes:
| Field | Purpose |
|---|---|
| profile | Profile name |
| tab | Ribbon tab name |
| min_version | Minimum Revit version |
| exportDate | When the profile was exported |
| panelOpacity | Background opacity (10–100) |
| requiredAddins | Add-ins the profile depends on |
| hideRules | Tabs to hide via RSTify |
| stacks | Tool stack definitions (2–3 tools each) |
| panels | Panel definitions with tools, colors, and layout |
The branding panel is not included in the JSON — it's injected at runtime from the local install.
Configuration
Add-in Lookup
The file lookup/addin_lookup.json maps ribbon tab names to .addin filenames. This is the single source of truth read by both UIs. Add entries for firm-specific add-ins — changes take effect on next Profiler or Loader open.
Protected Add-ins & Exempt Paths
The file lookup/config.json defines two lists:
- protected_addins — add-in files RST will never touch (e.g.
pyRevit.addin,Dynamo.addin) - exempt_paths — entire directories RST will never modify. Supports environment variables.
Both files are preserved across updates.
Uninstall
Remove the RST entry from pyRevit → Extensions → Manage (or delete the RST folder from any Custom Extension Directory you registered). Reload pyRevit. Python 3.12 and pywebview can stay — they're harmless and may be used by other tools.
Known Limitations
| Limitation | Detail |
|---|---|
| pyRevit script tools | Can be detected and placed but may not execute via PostCommand |
| Some OOTB tools | Dropdown/list button CommandIds are filtered out automatically |
| Locked files on update | Icons loaded by Revit are skipped during update, overwritten on next restart |
| Tab persistence | Custom tabs don't survive Revit restart — startup.py rebuilds every launch |
| Hidden tabs break tools | Tools from hidden tabs may not execute. RSTify protects source tabs, but manually hiding via MinifyUI can break things |
| MinifyUI deleted | RST removes MinifyUI smartbutton folder on profile load. Reinstall pyRevit to restore it |
| Add-in disabling | User-scope only. Machine-scope (ProgramData) add-ins are tracked but never disabled. Protected and Autodesk add-ins always exempt. |
| Memory growth on reload | Every pyRevit Reload / Update leaves memory behind in the Revit process (~100–150 MB per reload). This is a pyRevit architectural quirk — IronPython types created during extension load can't be unloaded by the CLR, so each reload stacks a new generation on top. RST tightens what it can (icon caching, event-handler teardown, brush de-dup) but the base cost belongs to pyRevit. If memory climbs during heavy profile switching, relaunch Revit. |
Tech Stack
| Component | Role |
|---|---|
| pyRevit | Extension framework, ribbon buttons, startup hooks |
| IronPython | Revit-side scripts — ribbon scanning, building, panel styling, reload UI |
| CPython 3.12 | UI windows via pywebview |
| AdWindows.dll | Ribbon manipulation — scan tools, build panels, detect add-ins, set colors |
| WPF | ImageBrush for branding, DrawingBrush for rounded corners, ToolWindow for reload messages |
| pywebview | HTML-based UI windows for Profiler and Loader |
Part of the Emergence Project. Built by the Design/OS shell team.
April 2026