How to make your own SketchUp extension (.rbz)
A SketchUp extension is a zip file renamed to .rbz that holds exactly two things: a small loader file (my_tool.rb) that registers the extension, and a folder with the same name (my_tool/) that holds your code. Install it with Extensions › Extension Manager › Install Extension.
The structure of a SketchUp extension
Start with a script that already works in the Ruby Console (see how to run a Ruby script in SketchUp). Turning it into an extension, whether a one-click cleanup or a cut-list exporter, is mostly packaging. Trimble's extension requirements ask for this layout:
jd_hide_edges.rb <- loader: registers the extension, nothing else
jd_hide_edges/ <- support folder, same name without .rb
main.rb <- your code and the menu itemThe rules that matter most:
- The loader only registers. It creates a
SketchupExtensionand passes it toSketchup.register_extension. No tool logic, no loading other files. - Everything sits inside one uniquely named module. All extensions share one Ruby environment, so a method called
runat the top level will collide with someone else's. Use your name or company plus the tool name, such asJaneDoe::HideEdges. - Leave the file extension off paths. Write
"jd_hide_edges/main", not"jd_hide_edges/main.rb". If the extension is later encrypted, the files become.rbeand a hard-coded.rbbreaks loading. - Load your own extra files with Sketchup.require, not
requireorrequire_relative, for the same reason.
A prefix on the file names (jd_ here) keeps your folder from clashing with another extension's folder in the Plugins directory.
A minimal working extension: loader and main.rb
This one adds Extensions › Hide Selected Edges. The loader, saved as jd_hide_edges.rb:
require "sketchup.rb"
require "extensions.rb"
module JaneDoe
module HideEdges
unless file_loaded?(__FILE__)
ext = SketchupExtension.new("Hide Selected Edges", "jd_hide_edges/main")
ext.creator = "Jane Doe"
ext.version = "1.0.0"
ext.copyright = "2026 Jane Doe"
ext.description = "Hides the edges in the current selection."
Sketchup.register_extension(ext, true)
file_loaded(__FILE__)
end
end
endThe code, saved as jd_hide_edges/main.rb:
require "sketchup.rb"
module JaneDoe
module HideEdges
def self.run
model = Sketchup.active_model
edges = model.selection.grep(Sketchup::Edge)
return UI.messagebox("Select some edges first.") if edges.empty?
model.start_operation("Hide Selected Edges", true)
begin
edges.each { |edge| edge.hidden = true }
model.commit_operation
rescue StandardError => e
model.abort_operation
UI.messagebox("Hide Selected Edges failed: #{e.message}")
end
end
unless file_loaded?(__FILE__)
UI.menu("Extensions").add_item("Hide Selected Edges") { run }
file_loaded(__FILE__)
end
end
endWhat each part does:
Sketchup.register_extension(ext, true)lists the extension in the Extension Manager. Thetrueloads it now and at every start, which Trimble recommends.UI.menu("Extensions")returns the Extensions menu (called Plugins before SketchUp 2015).add_itemadds your command and runs the block when it's clicked.- The
file_loaded?guard stops the menu item from being added twice if the file is loaded again. start_operationandcommit_operationmake each click one undo step, named in Edit › Undo. If anything fails,abort_operationrolls it all back. Trimble's requirements ask for this on any command that changes the model.
Testing your extension without reinstalling
Reinstalling an .rbz after every edit gets old fast. While you work, put the loader and folder straight into your Plugins folder. To find it, run Sketchup.find_support_file("Plugins") in the Ruby Console. Restart SketchUp once so the loader registers the menu item.
After that, edit main.rb, save, and reload just that file from the console:
load File.join(Sketchup.find_support_file("Plugins"), "jd_hide_edges/main.rb")The new version of run replaces the old one at once, and the guard keeps the menu from doubling up. Changes to the loader or to the menu text still need a restart.
Test on a copy of a real model, not an empty one. Try it with nothing selected, with a group selected, and while editing inside a component. Press Cmd+Z (Mac) or Ctrl+Z (Windows) after each run and check that one undo removes the whole change.
How to create an .rbz file
An .rbz is an ordinary zip. The catch is that the loader and the folder must sit at the top of the zip, not inside an extra wrapping folder.
On macOS
- In Finder, select both
jd_hide_edges.rband thejd_hide_edgesfolder (not the folder that contains them). - Right-click and choose Compress 2 Items. You get
Archive.zip. - Rename it to
jd_hide_edges.rbzand confirm the change of extension.
Finder may also pack hidden macOS files such as .DS_Store. For a clean archive, run this in Terminal from the folder that holds both items instead:
zip -r jd_hide_edges.rbz jd_hide_edges.rb jd_hide_edges -x "*.DS_Store"On Windows
- In File Explorer, select both the
.rbfile and the folder. - Right-click and choose Compress to › ZIP File on Windows 11 (some builds say Compress to ZIP file) or Send to › Compressed (zipped) folder on Windows 10.
- Rename the result from
.zipto.rbz. If you can't see the.zipending, turn on File name extensions under File Explorer's View menu first.
Turn a working prompt into an extension with MakeIt4Me
Writing the tool is usually the hard part, not the zip. MakeIt4Me (our product) connects an AI agent on your computer to your open SketchUp model, so you can describe a tool, watch the agent build and test it on your real model, and correct it until it behaves.
When it works, say "make this a plugin". The bundled sketchup-export-plugin skill asks what to call it, then packages the Ruby in the layout above: a loader, a support folder, its own namespace, a menu command and one undo step per run. It installs the extension into your Plugins folder and loads it live, so the menu command works with no restart. It also saves a shareable .rbz on your Desktop.
The result is plain Ruby that runs on its own, with no agent needed. Signing and Extension Warehouse submission are still up to you. For how this compares with writing it yourself or hiring a developer, see making your own plugin.
Questions
Do I need to know Ruby to make a SketchUp extension?
To write one by hand, yes, plus some of the SketchUp Ruby API. A good start is to get a script working in the console, then wrap it as shown above. Using ChatGPT to write SketchUp Ruby scripts covers getting help with the code itself.
What is the difference between a .rb and an .rbz file?
A .rb file is one Ruby script. An .rbz is a zip of a loader .rb and its folder, which the Extension Manager can install in one step.
Why doesn't my extension show up after installing?
Check that the zip has the loader and folder at its top level, that the path in SketchupExtension.new matches the folder name, and that the extension is enabled in the Extension Manager. Errors while loading show up in the Ruby Console.
Do I have to sign my extension?
No, unless the people using it have their loading policy set to Identified Extensions Only. Extension Warehouse signs extensions for you when it publishes them.