Lesson 6.2Lesson 6.2 · Scripting Rhino & Grasshopper
RhinoScript & rhino3dm
Two toolsets for Rhino geometry: the ones that need Rhino running, and the standalone library that reads and writes .3dm files anywhere
Not all Rhino code needs Rhino. One library reads and writes .3dm files on any machine, with no Rhino installed at all.
When people say they script Rhino, they usually mean writing code inside Rhino or Grasshopper, driving a live model. That is one world - and it depends completely on Rhino being open, because it borrows Rhino's geometry engine to do the heavy lifting.
There is a second world that surprises people: rhino3dm, an open-source library you pip install like any other Python package, that reads and writes .3dm files on any computer - a laptop with no Rhino, a web server, a build pipeline. This lesson draws the line between the two, because knowing which world your code lives in tells you what it can and cannot do.
Inside Rhino: rs + RhinoCommon (has kernel). Outside: rhino3dm (data only). Bridge = the .3dm file.
rhinoscriptsyntax: the friendly layer inside Rhino
The gentlest way to script a live Rhino model is rhinoscriptsyntax, conventionally imported as rs. It is a large library of plain, verb-like functions - AddPoint, AddLine, AddCircle, ObjectLayer, MoveObject - that mirror the commands you already know from Rhino's toolbars. It was designed to be approachable for exactly the audience of this course: designers who think in Rhino commands, not in software objects.
import rhinoscriptsyntax as rs
pt = rs.AddPoint(0, 0, 0)
rs.AddCircle(pt, 5.0)
rs.AddTextDot("origin", [0, 0, 0])Run that in Rhino's Python editor and three objects appear in the open document. That last phrase is the crucial catch: rhinoscriptsyntax only works inside a running Rhino (or a Grasshopper script component), because every function talks to the current Rhino document. Take this code to a plain Python install with no Rhino and the import fails - there is no document for AddPoint to add a point to. rhinoscriptsyntax is a convenience layer; underneath, it calls the real engine, which is our next piece.
What makes rs so welcoming to designers is that its functions map almost one-to-one onto Rhino commands you already run with the mouse, and they mostly take and return simple things - lists of three numbers for points, object identifiers as strings. You can be productive with it after learning barely a dozen functions. The trade is that it hides detail: it is excellent for scripting routine document tasks - drawing, moving, layering, labelling, selecting - and less suited to heavy geometric computation, where you will want the richer objects of RhinoCommon. A good mental model is that rhinoscriptsyntax automates the things you do to a Rhino document, while RhinoCommon lets you compute with geometry itself. Many real scripts use both: rs to fetch and place objects, RhinoCommon for the maths in between.
Historically, rhinoscriptsyntax began as the Python descendant of RhinoScript, an even older scripting language built into Rhino, which is why so much advice online is phrased in its command-like style. For a designer starting today, the takeaway is simple: rs is the approachable on-ramp for automating a Rhino session, and everything you learn there transfers, because the concepts - make an object, move it, put it on a layer - are universal. You will not need most of its hundreds of functions; a working vocabulary of the dozen you use often, plus the confidence to look up the rest, is exactly the done-and-useful fluency this course aims for.
rs = friendly command-like functions. Needs a live Rhino document underneath.
RhinoCommon: the full SDK - also inside Rhino
Beneath the friendly rs functions sits RhinoCommon, Rhino's complete geometry and document SDK. When you write import Rhino.Geometry as rg in a Grasshopper script component, you are using RhinoCommon directly. It is more verbose and more object-oriented than rhinoscriptsyntax, but far more powerful - it exposes the actual geometry classes and their methods.
import Rhino.Geometry as rg
circle = rg.Circle(rg.Point3d(0, 0, 0), 5.0)
curve = circle.ToNurbsCurve()
length = curve.GetLength()The key thing to understand is that RhinoCommon carries the geometry kernel - the mathematics that can trim, split, loft, offset, intersect and boolean real surfaces and solids. That kernel is heavy and proprietary, and it only exists where Rhino (or Rhino.Compute, the server version) is running. So both rhinoscriptsyntax and RhinoCommon live in the same world: they need Rhino. rhinoscriptsyntax is the easy front door; RhinoCommon is the full workshop behind it. In Grasshopper you will mostly use RhinoCommon, because the geometry you make flows straight back onto the canvas.
One detail trips people who move between the two: rhinoscriptsyntax usually works with object identifiers - references to things living in the Rhino document - while RhinoCommon works with the geometry objects themselves, whether or not they are in a document yet. That is exactly why RhinoCommon suits Grasshopper: on the canvas you are building geometry that may never be added to a Rhino file at all, just passed down the wires. It is also why the same word, say a curve, can feel different in each library - in rs it is often an id you pass around, in RhinoCommon it is a Curve object with methods like GetLength() and PointAt() you call directly. When an AI assistant or a forum answer mixes the two styles, this is usually the source of the confusion. If code from the internet does not run, checking whether it expects object ids (rhinoscriptsyntax) or geometry objects (RhinoCommon) is one of the first things to try, and it resolves a surprising share of copy-paste failures.
rs sits on top of RhinoCommon. RhinoCommon = the kernel. Both need Rhino running.
rhino3dm: geometry as data, anywhere
Now the surprising world. rhino3dm is a small, open-source, freely installable library - pip install rhino3dm - that runs anywhere Python does, with no Rhino present. What it gives you is the ability to read and write the .3dm file format and work with geometry as data: create points, lines, curves, meshes and breps, put them on layers, set attributes, and save a valid Rhino file.
import rhino3dm
model = rhino3dm.File3dm()
model.Objects.AddPoint(0, 0, 0)
model.Objects.AddLine(
rhino3dm.Point3d(0, 0, 0),
rhino3dm.Point3d(10, 0, 0),
)
model.Write("out.3dm", 7) # 7 = the file version to saveThat script produces a real .3dm on a machine that has never seen Rhino. The essential limitation is the flip side of its portability: rhino3dm has no geometry kernel. It can hold a surface and a curve as data, but it cannot trim the surface with the curve, cannot boolean two solids, cannot loft. Those operations need the kernel, which lives only inside Rhino or Rhino.Compute. rhino3dm is a container and constructor, not a modeller. Think of it as the library that lets a script, a website or a data pipeline touch Rhino files without a Rhino licence.
rhino3dm is also refreshingly ordinary as Python. Once a .3dm is open, its contents are just collections you iterate with the same loops from Module 2 - for obj in model.Objects: walks every object, model.Layers is a sequence of layers, and each object carries geometry and attributes you can read like any other data. Because it installs with pip and needs nothing else, it slots naturally into the file-and-folder automation of Module 8: read a model, pull some numbers, write them to a CSV, move on to the next file. The library also exists for JavaScript and C#, so a design tool you build can share the exact same understanding of a Rhino file across a web front end and a Python back end - a genuinely powerful thing for a small practice building its own tooling.
rhino3dm = read/write .3dm as data, no Rhino needed. But NO kernel: no trim/loft/boolean.
Choosing between them - and reading a file
The decision is really one question: where does my code run? If it runs inside Rhino or a Grasshopper script component, and especially if you need to actually model - trim, offset, boolean - use rhinoscriptsyntax for quick tasks or RhinoCommon for real work. If it runs outside Rhino - a batch job over a folder of files, a web service, an automated export - and you only need to read, generate or rearrange geometry as data, use rhino3dm.
A classic rhino3dm job is auditing a folder of models without opening a single one:
import rhino3dm
model = rhino3dm.File3dm.Read("tower.3dm")
print("objects:", len(model.Objects))
for layer in model.Layers:
print("layer:", layer.Name)That runs in a fraction of a second, on any machine, over any number of files in a loop - the kind of automation Module 8 builds on. If you later need to change geometry with real modelling operations, that is the moment to move the work inside Rhino, or to call Rhino.Compute, a headless server that exposes the kernel over the web so even a remote script can trim and loft. For most designers, the practical map is simple: model inside Rhino, wrangle files outside with rhino3dm.
It helps to see the .3dm file as the neutral ground both worlds share. A Grasshopper definition using RhinoCommon can bake geometry into a Rhino document and save it; a standalone rhino3dm script on another machine can then open that same file and read it as data - no shared code, just a shared format. This is how a pipeline is often stitched together in practice: designers model interactively in Rhino, an automated rhino3dm job picks up the saved files overnight to audit or export them, and if a genuine modelling step is needed in that pipeline, a Rhino.Compute call fills the one gap rhino3dm cannot. Knowing which of the three you need for a given line of code - and it really is just those three - is most of what this lesson is teaching.
rhinoscriptsyntax
Command-style function library inside Rhino / GH
Import as rs. Reads like Rhino commands (AddPoint, AddLine). Needs a live Rhino document; will not run in plain Python.
RhinoCommon
Rhino full geometry and document SDK
import Rhino.Geometry as rg. Object-oriented, carries the geometry kernel, runs only inside Rhino or Rhino.Compute.
rhino3dm
Open-source standalone .3dm read/write library
pip install rhino3dm. Runs anywhere, no Rhino needed, but has no kernel - geometry as data only.
File3dm
The rhino3dm object representing a .3dm file
File3dm.Read(path) opens one; model.Write(path, version) saves. Holds Objects, Layers and materials.
Rhino.Compute
Headless server exposing the kernel over the web
How you get real modelling operations outside Rhino - the paid answer when rhino3dm is not enough.
Workshop - a folder auditor with rhino3dm
Write a standalone script - no Rhino needed - that opens every .3dm file in a folder and reports how many objects and which layers each one contains. This is the pattern behind real QA automation, and it proves you can touch Rhino files without Rhino.
Any Python 3 install with `pip install rhino3dm`. A few sample .3dm files. No Rhino licence required.
Goal: report object counts and layer names for every .3dm in a folder Inputs: a folder with a few .3dm files, plain Python (no Rhino) Time: ~30 minutes
- 1In a normal Python environment (not Rhino), install the library:
pip install rhino3dm. Confirm it imports withimport rhino3dmin a fresh script. - 2Use the
osmodule (from Module 3) to loop over the folder:for name in os.listdir(folder):and skip anything that does not end in.3dm. - 3For each file, open it with
model = rhino3dm.File3dm.Read(path). Guard for failure - Read returnsNoneif the file is unreadable - andcontinuepast those so one bad file does not crash the run. - 4Report
len(model.Objects)for the object count, then loopfor layer in model.Layers:and collectlayer.Nameinto a list. Print one tidy line per file. - 5Bonus: write the results to a CSV with the
csvmodule (Module 3) so the audit becomes a spreadsheet you can hand to a colleague - all without opening Rhino once.
You’ll walk away with
A standalone Python script that walks a folder of .3dm files and prints, for each, its object count and layer names - running with only rhino3dm installed and no Rhino present.
Three altitudes on the same idea
Read the band that fits you — or all three.
rhino3dm is how you touch hundreds of Rhino models without opening one. Audit a project folder for layer-naming compliance, count objects, extract a schedule of blocks, or generate stub site models from survey data on a server - all without a Rhino licence in the loop. When you genuinely need to model, you stay inside Rhino with RhinoCommon; the two worlds hand off cleanly through the shared .3dm file.
Most interiors scripting you will meet is the friendly rhinoscriptsyntax kind, inside Rhino. Place blocks, tag objects, tidy layers, add dimensions - rs functions read almost like the Rhino commands you already use. Save rhino3dm for the occasional housekeeping job, like pulling a list of every object and its layer out of a set of files to reconcile against an FF&E schedule, without disturbing the models themselves.
Knowing that rhino3dm needs no Rhino unlocks a lot of portfolio projects. You can build a small web tool that reads .3dm files, a data pipeline, or a batch exporter on a free machine - none of which is possible with rhinoscriptsyntax. Understanding the kernel boundary (data versus modelling) is exactly the kind of systems literacy that computational-design employers look for, and it feeds straight into the Computational Design course here.
“rhino3dm is just the free version of Rhino - I can do everything Rhino does with it, without paying.”
Do it yourself
Sort code into the right world.
- 1Which of the three - rhinoscriptsyntax, RhinoCommon, rhino3dm - can run on a laptop with no Rhino installed?
- 2You need to boolean two solids in a script. Can rhino3dm do it? If not, what are your options?
- 3What does File3dm.Read return if it cannot open the file, and how should your loop handle that?
- 4In one sentence, what is the relationship between rhinoscriptsyntax and RhinoCommon?
- 5You want a web server to generate .3dm files from user input. Which library, and why that one?
The one line to carry out
Peer-reviewed journals & authoritative standards
- 01Rhinoceros 3D — Wikipedia, 2026.
- 02Rhino Developer documentation — McNeel / Rhino Developer, 2026.
- 03Rhino.Python guides — McNeel / Rhino Developer, 2026.
- 04Library (computing) — Wikipedia, 2026.
We can now make and save geometry in either world. Next we get our hands dirty actually generating it - points, lines, curves and surfaces built from code, driven by numbers, in a couple of worked parametric examples.
The author
Amogh N P
Architect, interior designer, and creative polymath. Studio Matrx began in his notebooks — his vision of design made honest, useful, and open to everyone. Its Academy is written and taught in his memory, and free, forever.
More about Amogh →