Studio Matrx Monthly · Volume 1 · Issue 3 · August 2026
Amogh N P
 In loving memory of Amogh N P — Architect · Designer · Visionary 
Python in GrasshopperLesson 6.1
PSD for Architecture, Planning & Urban Design/Module 6 · Scripting Rhino & Grasshopper

Lesson 6.1 · Scripting Rhino & Grasshopper

Python in Grasshopper

The script component: a patch of real code sitting inside the visual graph, taking wires in and sending wires out

13 min Interactive lessonFree · open lessonByAmogh N P· Architect & interior designer
The hook

When the visual graph gets tangled, drop in a script component - a small window where you write Python that plugs straight into the wires.

Grasshopper is a visual programming language: you solve problems by dragging components and drawing wires between them. It is wonderful for many things and awful for a few - a loop that feeds itself, a fiddly bit of logic, a calculation that would take fifteen components and one line of code.

That is what the script component is for. It is a single component you drop on the canvas that contains real Python. Wires still flow in and out, so it lives happily beside every other component - but inside, you have the full language: variables, loops, conditionals, functions. This lesson is about that boundary: how data crosses from the graph into your code and back again.

Script component = code on the canvas. Inputs -> variables. Assign a -> output. Rhino 8 = CPython 3.

Why script inside a visual tool at all

Grasshopper solves problems by wiring components together, and for a huge range of parametric work that is faster and clearer than code. So why script at all? Because some things the visual graph does badly. Iterative logic - where each step depends on the last - is painful to wire but trivial to write as a for loop. Conditional branching - do this if a room is over 15 sqm, otherwise that - sprawls into a mess of Stream Filter and Dispatch components but reads as three lines of Python. And sometimes you simply know the code already and reaching for a component you half-remember is slower than typing what you mean.

The honest rule is: use components for the flow, drop to code for the knots. A mature Grasshopper definition is usually mostly components with a few script components at the awkward joints - not one giant script that ignores the canvas, and not a heroic all-visual contraption avoiding code on principle. You are not choosing sides; you are using the right tool for each stretch. This whole module lives at that boundary, and it starts with the mechanics of getting data in and out of a script component cleanly.

There is also a quieter reason to script inside Grasshopper: reuse and clarity. A component someone wired up two years ago is a puzzle to inherit - you have to trace every wire to understand it. A short, well-named script with a comment at the top often explains itself, and you can copy it between definitions without re-wiring anything. Once you are comfortable, a script component becomes a little reusable tool you carry from project to project: your own averaging component, your own labeller, your own bay-grid maker. That personal toolkit, built up over time, is one of the real dividends of learning to script rather than only to wire.

Be honest about the flip side, though: a script component is a black box on the canvas. Where a chain of components shows its working at every step - you can hover any wire and see the data - a script hides its logic inside, visible only if someone opens it. That is a fair trade for a knotty calculation, and a poor one for something a Dispatch and a Cull would show plainly. The skill is knowing which is which, and it is why this lesson keeps returning to the same rule: reach for code when it genuinely reads more clearly than the wires, not merely because you can.

GRASSHOPPER PYTHON SCRIPT COMPONENTxyinputsyour Python 3 code (CPython)import Rhino.Geometry as rgpt = rg.Point3d(x, y, 0)a = pta is wired to the outputaoutputInputs become variables; assigning the output name sends the value back into the canvas.Rename params on the component to rename the variables. Right-click a param to set Item, List or Tree access.
Zoom
The Python 3 Script component in Grasshopper: parameters wire in on the left, your code runs in the middle, and outputs wire out on the right. Inputs arrive as named variables (x, y by default); you produce results by assigning to the output names (a by default). The graph feeds the code; the code feeds the graph.

Components for the flow; code for the knots. Most defs are a mix.

Which Python is this, exactly

Being precise here saves confusion later, because Grasshopper has had two Python engines. The older GHPython component runs IronPython 2.7 - an implementation of the now-ancient Python 2 built on .NET. It is still around in older files and still works, but Python 2 has been end-of-life for years and you should not start new work in it.

Since Rhino 8, Grasshopper ships a new Python 3 script component running real CPython 3 - the same Python you install from python.org. This matters enormously: it means you can pip install normal libraries like numpy or pandas and use them right inside Grasshopper, which the old IronPython engine could not do cleanly. Throughout this module, the script component means this modern CPython 3 one unless stated otherwise.

Either way, one thing is constant: your code runs with access to Rhino's geometry library. Inside the component you typically write:

python
import Rhino.Geometry as rg

pt = rg.Point3d(3.0, 5.0, 0.0)
vec = rg.Vector3d(0, 0, 10)

Rhino.Geometry is part of RhinoCommon, Rhino's full geometry SDK, and it is what lets your script make points, curves and surfaces that the rest of the canvas understands. We meet it properly in lesson 6.3.

One practical consequence of the CPython 3 shift is worth flagging now, because it will save you a confusing hour later. Because the new component is real CPython, code you write and test in a normal editor - or that an AI assistant generates - runs the same way inside Grasshopper, which was never quite true of the old IronPython. Standard-library modules like math, random, csv and json all behave exactly as they do everywhere else in this course. The main things unique to the Grasshopper context are the Rhino.Geometry types and the input/output plumbing; the plain Python underneath is just Python. That continuity is the reason this course teaches the language first and the tools second - the fundamentals genuinely transfer.

Old = GHPython / IronPython 2.7. New (Rhino 8) = Python 3 / CPython. Use the new one.

Inputs become variables; the a=... pattern sends values out

Here is the core mechanic, and it is beautifully simple. Every input on the script component becomes a variable in your code, named after the param. The defaults are x and y; rename the param to radius and a variable radius appears. Every output is a name your code assigns to; the default output is a. Whatever you store in a gets pushed back onto the canvas through that wire.

So the smallest useful script is genuinely this:

python
# inputs on the component: x, y
# output on the component: a
a = x + y

Wire two number sliders into x and y, and a carries their sum out. Add a second output param named b, and you can return two things:

python
a = x + y
b = x * y

The values can be anything Python holds - numbers, strings, lists, or Rhino geometry. This is the whole contract between code and canvas: read the inputs as variables, do your work, assign the outputs by name. There is no return, no print to the wires - just assignment. Forgetting to assign an output is the single most common beginner slip: the code runs, but the output param stays empty because nothing was ever put in a.

A subtle but important point: the output can hold a whole collection, not just one value. If you assign a Python list to a, Grasshopper unpacks it into a list on the wire, so one script can emit many items:

python
a = [rg.Point3d(i, 0, 0) for i in range(10)]   # ten points out

That list comprehension - straight from Module 2 - builds ten points and sends them all through the single output a. This is how a script becomes a generator of geometry rather than a calculator of one number, and it is the pattern behind every worked example later in this module. Assign a single value and you get one item on the wire; assign a list and you get many.

INPUT ACCESS: ITEM vs LIST vs TREEITEMruns once per valuex = 3a = x * 2simple, but no cross-item logicLISTruns once, whole branchx = [3, 5, 8]a = sum(x)totals, sorting, neighboursTREEruns once, all branchesx = DataTreewalk pathsfull control, more codeRight-click the input param to choose. Reach for the simplest mode the task allows.
Zoom
How a single input reaches your code depends on its access mode. Item access hands you one value and runs the script once per item. List access hands you a whole Python list in one run. Tree access hands you the entire data tree, branches and all. Choosing the right mode is half of scripting well in Grasshopper.

Input param name = variable in. Output param name = variable you assign. No return.

Item, list or tree: how much arrives at once

One setting changes everything about how your script behaves: the access mode of each input, set by right-clicking the param. There are three choices.

Item access (the default) hands your code one value at a time and runs the whole script once for each item. If you wire in a list of ten numbers with x set to Item access, your script executes ten times, with x being a single number each run. Simple, but you cannot see the other items - no totals, no sorting, no looking at neighbours.

List access hands your code the entire list in one run, as a real Python list. Now x might be [3, 5, 8] and you can do list things:

python
# x set to List access
a = sum(x) / len(x)   # the average

Tree access hands you the whole Grasshopper data tree - every branch - which we unpack in lesson 6.4. The guidance is to reach for the simplest mode the task allows: Item when each value is independent, List when you need to see a whole branch together, Tree only when the branch structure itself matters. Getting this choice right is often the difference between a script that works and one that quietly does the wrong thing to the wrong number of items.

There is a matching setting on the output side, called the output type or list access on the output, but the everyday rule is simpler than the inputs: if you assign a list, you get a list out. The one habit worth forming early is to decide the access mode deliberately for every input, rather than accepting the Item default and wondering why your averaging script keeps returning a list of unchanged numbers. When a script behaves strangely, the access modes are the first thing to check - more often than not, an input that should be List is still set to Item, so your code is being run once per value and never sees the collection it needs. We return to the fullest mode, Tree access, in lesson 6.4, once trees themselves make sense.

INPUT ACCESS: ITEM vs LIST vs TREEITEMruns once per valuex = 3a = x * 2simple, but no cross-item logicLISTruns once, whole branchx = [3, 5, 8]a = sum(x)totals, sorting, neighboursTREEruns once, all branchesx = DataTreewalk pathsfull control, more codeRight-click the input param to choose. Reach for the simplest mode the task allows.
Zoom
How a single input reaches your code depends on its access mode. Item access hands you one value and runs the script once per item. List access hands you a whole Python list in one run. Tree access hands you the entire data tree, branches and all. Choosing the right mode is half of scripting well in Grasshopper.
Components, engines and settings you will meet

Python 3 script component

The modern CPython 3 scripting component in Rhino 8 Grasshopper

Runs real CPython 3, so you can pip install numpy or pandas. This is the one to use for new work.

GHPython (IronPython 2.7)

The legacy Python 2 script component

Still present for old files, but Python 2 is end-of-life. Do not start new scripts in it.

RhinoCommon / Rhino.Geometry

Rhino geometry SDK available inside the script

import Rhino.Geometry as rg gives you Point3d, Curve, Brep and more that the canvas understands.

Item / List / Tree access

Per-input setting for how much data arrives at once

Right-click an input to set it. Item runs the script per value; List gives a whole branch; Tree gives everything.

Hands-on workshop

Workshop - a script component that averages and labels

Build the smallest useful script that actually needs code: take a list of numbers, return both their average and a short text label. It exercises List access, multiple outputs, and the assign-the-output rule in one go.

Rhino 8 (for the CPython 3 script component) with Grasshopper. No extra libraries required.

Given & goal
Goal: return the average of a list plus a text label, from one script component
Inputs: one number slider set feeding a list into x
Time: ~25 minutes
  1. 1In Rhino 8, open Grasshopper and drop a Python 3 script component on the canvas. Wire a list of numbers (a Number param with several values, or a Series component) into the input x.
  2. 2Right-click the x input and set its access to List - this is essential, or your script runs once per number and can never average them.
  3. 3Add a second output param: right-click near the outputs, add one, and rename it b. You now have outputs a and b.
  4. 4In the code, compute a = sum(x) / len(x) for the average, then build a label such as b = "avg of " + str(len(x)) + " values = " + str(round(a, 2)). Assign both - remember, nothing comes out of an output you never set.
  5. 5Hover the outputs to confirm a is one number and b is the text. Now change the input list and watch both update. Bonus: guard against an empty list with an if len(x) == 0: check so the script never divides by zero.

You’ll walk away with
A working Python 3 script component with List access on its input and two outputs - a numeric average and a formatted text label - that updates live as the input list changes.

The worked example

Three altitudes on the same idea

Read the band that fits you — or all three.

For the architectAutomate busywork & build custom tools

A script component is the escape hatch for the logic your definition cannot wire cleanly. Adaptive facade rules, floor-by-floor massing that depends on the floor below, code-compliance checks that branch on room type - these are natural as a few lines of Python inside an otherwise visual definition. You keep the parametric responsiveness of Grasshopper and gain the expressiveness of a real language exactly where the graph would otherwise sprawl.

For the interior designerScripts for data, schedules & layouts

Even interiors work that lives in Rhino has knots worth scripting. Distributing furniture on a grid, labelling a set of panels, computing a running total of areas across a layout - each is cleaner as a short script feeding back into your Grasshopper layout than as a wall of components. You do not need to script everything; you need the one small window where typing the logic beats hunting for the component.

For the studentA hireable computational skill

Grasshopper plus a little Python is one of the most employable combinations in the studio. Learning where the script component fits - and the input-becomes-variable, assign-the-output contract - puts you ahead of peers who only ever wire components. It is also the gentlest on-ramp from pure code into computational design, and it feeds directly into the Computational Design and Generative AI courses in this Academy.

Misconception check

If I use a script component, I am admitting Grasshopper failed - real GH users solve everything with components.

This is a persistent bit of studio machismo and it is wrong. The most fluent Grasshopper users script constantly; they just do it surgically. A visual graph is superb for the shape of a computation - the flow of data through transformations - and clumsy for tight logic, iteration and branching. Refusing to script means either an unreadable mat of Dispatch and Stream Filter components, or avoiding whole classes of problem. The skilled move is a mostly-visual definition with small script components at the joints where code is simply the clearer language. Using the script component is not a failure of Grasshopper; it is using Grasshopper the way it was designed to be used - as a canvas that welcomes code.
Try it

Do it yourself

Reason about the code-canvas boundary.

  1. 1On a script component, what determines the name of the variable you read an input from?
  2. 2How does a value leave a script component and get back onto the canvas - what do you do in the code?
  3. 3Your output param is empty even though the code ran without error. What is the most likely cause?
  4. 4You wire a list of 20 numbers into an input set to Item access. How many times does your script run, and what is the input each time?
  5. 5Which Python engine should you use for new work in Rhino 8, and why not the older one?
Take this with you

The one line to carry out

The script component is a patch of real Python inside the visual graph: inputs arrive as named variables, and you send results out by assigning to the output names - a by default, no return. Use components for the flow and code for the knots.
Take it further
References & further reading

Peer-reviewed journals & authoritative standards

  1. 01Grasshopper 3DWikipedia, 2026.
  2. 02Rhinoceros 3DWikipedia, 2026.
  3. 03Rhino.Python guidesMcNeel / Rhino Developer, 2026.
  4. 04Python (programming language)Wikipedia, 2026.
Related lessons
Recap
Grasshopper is visual, but tight logic, iteration and branching are clearer as code, and the script component lets you drop Python straight into the canvas. In Rhino 8 use the CPython 3 component, not the legacy IronPython 2.7 one. Inputs become variables named after their params; outputs are names you assign, with a as the default. The per-input access mode - Item, List or Tree - decides how much data arrives and how many times your script runs.
Carry forward →

We have been writing geometry with Rhino.Geometry inside a live Grasshopper session. But what about code that runs where Rhino is not open at all? Next we compare the tools that need Rhino running with the standalone library that reads and writes .3dm files anywhere.

A

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 →