Break large Grasshopper definitions into modules that hand off data via Speckle models.
Use this guide when one Grasshopper definition is becoming too large, or when multiple people or tools need to work on different stages of the same pipeline. It shows how to treat Speckle models as the
interfaces between Grasshopper modules. For users who already publish and load data with Speckle in Grasshopper.
Before you start: You need the Speckle Grasshopper connector installed and basic familiarity
with the Publish and Load nodes. If you are new to Speckle in Grasshopper, see the
Grasshopper connector guide first.
Connectors from 2026.8 or earlier cannot load versions published by the 2026.9 Publish node.
Everyone who loads a module’s output needs the 2026.9 connector. See Upgrade to
2026.9.
When to use: Your definition is complex enough that separate files or owners make sense.
1
Identify natural module boundaries
Look for stages that already exist in your definition such as “base geometry generation”,
“analysis setup”, “visualisation prep”, or “documentation”. Each of these is a candidate module.
2
Decide what each module owns
For each stage, decide what it is responsible for producing (e.g. cleaned room solids with
metadata, analysis meshes, layout curves). These become the public outputs that downstream
modules rely on.
3
Check who needs to work on each stage
If different people or teams own different stages (e.g. design vs analysis), componentising
makes collaboration clearer. Even for one person, modules help separate experiments from stable
logic.
Outcome: A list of modules with clear responsibilities that you can split into separate Grasshopper files.
When to use: Before creating separate Grasshopper files.
1
Create a Speckle project and models for the workflow
In Speckle, create a project that will hold all models for this workflow. For each module, plan
one or more models (e.g. 01_base-geometry, 02_analysis-input, 03_visualisation). A typical
pipeline: one module publishes base geometry to a model; a second consumes it and publishes
analysis input; a third consumes that and produces documentation or exports.
2
Define the contract for each module output
For each module, decide what data will be sent to Speckle. Be explicit about object types,
required properties, naming, and units. Treat this as a contract: downstream modules should be
able to rely on it remaining stable.
3
Choose how you will version data
Decide whether downstream modules should always use the latest version of a model or pin to
specific versions for repeatable runs. For automated or production workflows, prefer pinned
versions to avoid surprises.
The flow is: upstream Grasshopper file → Publish → Speckle model → Load → downstream Grasshopper file.Outcome: A simple map of which models carry data between modules, and what each of them contains.
Build an upstream module that publishes to Speckle
When to use: Creating the first module in the chain that produces data for others.
1
Start a Grasshopper file for the module
Copy only the part of your existing definition that belongs to this module into a new Grasshopper file. Keep its inputs focused on what this module actually needs to run.
2
Add a Publish node at the output
Place a Publish node from the Speckle Grasshopper connector at the point where you want to expose data. Connect the geometry and data you identified in your contract as its input.
3
Configure account, server, project, and model
Set up the Publish node with the correct Speckle account, server, project, and model name (e.g. 01_base-geometry). Use clear, stable names that reflect the module’s role.
4
Shape data for downstream consumers
Before publishing, clean and structure the data: group elements logically, wrap geometry in Speckle Object nodes so names and properties sit on the object, ensure important properties are present and named consistently, and avoid publishing unused or experimental data. Aim for a tidy
structure that downstream modules do not need to reinterpret.
5
Publish and verify in Speckle
Run the definition and publish. Open the project in Speckle, inspect the model, and confirm that objects, properties, and naming match your intended contract.
Outcome: A standalone Grasshopper module that publishes a well‑defined Speckle model for others to consume.
Build downstream modules that consume Speckle models
When to use: Creating modules that depend on data from earlier stages.
1
Start a new Grasshopper file per downstream module
Create a separate Grasshopper definition for each downstream stage (e.g. analysis, reporting, documentation). Keep inputs and outputs explicit so the file is easy to reason about.
2
Add Load nodes for upstream models
Place one or more Load nodes and point them at the upstream models (e.g. 01_base-geometry). If stability matters, pin the node to a specific version.
3
Adapt loaded data to local needs
Convert loaded objects into the types, structures, and units this module uses internally. This is also where you can add module‑specific properties or perform filtering based on tags or parameters.
4
Optionally publish this module's outputs
If another module will consume this stage, add a Publish node at your module’s output and repeat the configuration and shaping steps. Choose a model that clearly names this stage (e.g.
02_analysis-input).
5
Test modules together
Run the upstream module to publish fresh data, then run the downstream module and confirm that the Load nodes pick up the expected objects. Fix any contract mismatches before adding more complexity.
Outcome: One or more downstream modules that reliably consume Speckle models from upstream and can themselves publish clean outputs.
When to use: Multiple people, machines, or tools share responsibility for the pipeline.
1
Assign clear ownership per module
Decide who owns each module and where its Grasshopper file lives (e.g. version‑controlled
repository). Owners are responsible for keeping the Speckle contracts stable and documented.
2
Document contracts alongside the files
For each module, record which Speckle project and models it reads and writes, and what each
output contains. A short README next to the Grasshopper file is often enough.
3
Agree on change management
Establish how upstream changes are communicated. For example, require a brief note whenever
object structure or key properties change, and schedule time for downstream owners to adapt.
4
Run modules on appropriate machines
Let heavy geometry or analysis modules run on powerful workstations or dedicated machines, while
lighter reporting or visualisation modules can run elsewhere. Speckle models carry the data
between them.
Outcome: Teams can work on different stages without sharing one large Grasshopper file, and changes propagate via well‑defined Speckle models.
One module publishes base geometry; another prepares analysis input; a third produces documentation or exports. Each stage reads from and writes to a dedicated Speckle model.
Pattern: Branching workflows
A single upstream model feeds multiple downstream modules (e.g. daylight analysis, cost estimation, visualisation). All downstream Load nodes point at the same upstream model or version.
Pitfall: Publishing everything
Publishing the entire Grasshopper state makes downstream modules brittle and hard to understand. Instead, publish only what is needed and keep contracts small.
Pitfall: Unannounced schema changes
Changing property names or structures without coordination breaks downstream modules. Treat contracts as shared APIs and change them deliberately.
Use as many modules as you need to keep responsibilities clear and files manageable. A common
pattern is 2–4 modules (e.g. base geometry, analysis prep, reporting, and exports) rather than a
large number of very small ones.
Can multiple downstream modules consume the same Speckle model?
Yes. Any number of Grasshopper files or other tools can load from the same project and model.
This is a good way to centralise base geometry and fan out into specialised workflows.
Should downstream modules always use the latest version?
For exploratory work, using the latest version keeps things simple. For repeatable analysis or
production runs, pin Load nodes to specific versions so results can be reproduced and
compared reliably.
What if a downstream module needs extra data?
Update the upstream module’s contract to include the additional properties or objects, then add
them to the Publish node. Coordinate the change with all downstream owners so they can take
advantage of the new data without breaking existing logic.
How do I debug issues between modules?
First, inspect the upstream Speckle model in the web viewer to confirm that objects and
properties look as expected. Then check the Load node configuration and any conversion logic
in the downstream file. Work from the interface inwards rather than from deep inside the
definition.
Can non-Grasshopper tools participate in the workflow?
Yes. Any tool with a Speckle connector or SDK can read from and write to the same models. For
example, analysis tools, dashboards, or scripts can consume the outputs of Grasshopper modules
or publish new stages in the pipeline.
How big can the Speckle models between modules get?
Models can grow large, but very heavy payloads will affect publish and load times and downstream
performance. If models become unwieldy, consider splitting them by discipline, zone, or purpose
so modules only consume what they need.
Do I need Automate for componentised workflows?
No. Componentised workflows work with manual publishing and loading. Automate becomes useful
when you want these modules to run automatically on triggers, but it is not required for the
pattern itself.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Speckle Docs","colors":{"primary":"#2563EB","light":"#3B82F6","dark":"#2563EB"},"logo":{"light":"https://mintcdn.com/speckle/8FGkkbZZbcuHzOBq/logo/light.svg?fit=max\u0026auto=format\u0026n=8FGkkbZZbcuHzOBq\u0026q=85\u0026s=9fc87cac252fa8cc443a9828ecbace70","dark":"https://mintcdn.com/speckle/8FGkkbZZbcuHzOBq/logo/dark.svg?fit=max\u0026auto=format\u0026n=8FGkkbZZbcuHzOBq\u0026q=85\u0026s=560ffcf355d3abfde56e5f8e514a64b7"},"favicon":"https://mintcdn.com/speckle/EShMFmfm7tGBxVKq/favicon-smaller.svg?fit=max\u0026auto=format\u0026n=EShMFmfm7tGBxVKq\u0026q=85\u0026s=805ae0301be5e103926e84e99871779c","navbar":{"links":[{"href":"https://speckle.systems/","label":"Speckle"},{"href":"https://speckle.community/","label":"Support"}],"primary":{"type":"button","label":"Sign up","href":"https://app.speckle.systems/?utm_source=Docs\u0026utm_medium=SignUp\u0026utm_campaign=Docs"}},"footer":{"socials":{"linkedin":"https://www.linkedin.com/company/specklesystems","youtube":"https://www.youtube.com/@SpeckleSystems","github":"https://github.com/specklesystems","instagram":"https://www.instagram.com/specklesystems"}},"icons":{"library":"fontawesome"},"integrations":{"ga4":{"measurementId":"G-05WEYFZ28C"},"intercom":{"appId":"hoiaq4wn"},"mixpanel":{"projectToken":"acd87c5a50b56df91a795e999812a3a4"}},"contextual":{"options":["copy","chatgpt","claude"],"display":"header"},"metadata":{"timestamp":true},"markdown":{"instructions":["These docs describe Speckle as it works today, including everything released in 2026.9. Treat page content as current unless the page or section says it applies only to versions published before 2026.9.","Content scoped to versions published before 2026.9 (the object graph and root object, Proxies, Receive2, operations.receive, object.children) applies only to model versions in that earlier data format. For versions published in 2026.9, answer from the Object model pages and the SDK migration guides.","The What's new pages summarise what changed in 2026.9 and link to the page that documents each change. Answer from the linked page rather than from the summary. Legacy (v2) connectors are retired; send questions about them to the community help forum.","Match guidance to the customer's deployment, model data format, connector, plan and permissions. Self-hosted servers on a release before 2026.9 and compatibility-mode workflows follow the Compatibility mode page. If an unknown version or data format changes the answer, ask one focused question; do not infer the deployment version from the date alone."]},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"speckle","hasAudioNarration":false,"actualSubdomain":"speckle","customDomains":["docs.speckle.systems"],"gitSource":{"type":"github","owner":"specklesystems","repo":"speckle-docs-new","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae306ba36199f9bca5446ac","collectionId":"c0a27784-b9bd-4a60-804a-0f7ae4af7863","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae306ba36199f9bca5446ac"},"feedback":{"issues":true},"entitlements":{},"buildId":"6ae306ba36199f9bca5446ac","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"default","tag":"Developers","count":200},{"language":"default","tag":"User Guides","count":95},{"language":"default","tag":"SDKs","count":65},{"language":"default","tag":"API Reference","count":54},{"language":"default","tag":"Viewer","count":50},{"language":"default","tag":"Connectors","count":39},{"language":"default","tag":"Publishing \u0026 Loading","count":37},{"language":"default","tag":"C# .NET","count":33},{"language":"default","tag":"Python","count":30},{"language":"default","tag":"Guides","count":23}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"#footer div:first-child>div:first-child>div:first-child{display:none}.header-link+p{margin-top:.6rem}li .frame{margin-top:1rem;margin-bottom:1.5rem}div:has(>.frame)+div:has(>.frame){margin-top:.75rem}"}],"page":{"pagePath":"workflows/grasshopper-componentised-workflow","slug":"/workflows/grasshopper-componentised-workflow","pageMetadata":{"title":"Componentised Grasshopper workflow","sidebarTitle":"Grasshopper","description":"Break large Grasshopper definitions into modules that hand off data via Speckle models.","href":"/workflows/grasshopper-componentised-workflow"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Break large Grasshopper definitions into modules that hand off data via Speckle models.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{Accordion,AccordionGroup,Frame,Heading,Note,OptimizedImage,Step,Steps}=_components;if(!Accordion)_missingMdxReference(`Accordion`,true);if(!AccordionGroup)_missingMdxReference(`AccordionGroup`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Use this guide when one Grasshopper definition is becoming too large, or when multiple people or tools need to work on different stages of the same pipeline. It shows how to treat Speckle models as the\ninterfaces between Grasshopper modules. For users who already publish and load data with Speckle in Grasshopper.`}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Before you start:`}),` You need the Speckle Grasshopper connector installed and basic familiarity\nwith the `,_jsx(_components.strong,{children:`Publish`}),` and `,_jsx(_components.strong,{children:`Load`}),` nodes. If you are new to Speckle in Grasshopper, see the\n`,_jsx(_components.a,{href:`/connectors/grasshopper/grasshopper`,children:`Grasshopper connector`}),` guide first.`]})}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`Connectors from 2026.8 or earlier cannot load versions published by the 2026.9 `,_jsx(_components.strong,{children:`Publish`}),` node.\nEveryone who loads a module’s output needs the 2026.9 connector. See `,_jsx(_components.a,{href:`/connectors/grasshopper/grasshopper#upgrade-to-2026-9`,children:`Upgrade to\n2026.9`}),`.`]})}),`\n`,_jsx(Frame,{children:_jsx(OptimizedImage,{src:`https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_toolbar.jpg?fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=2dd5e6c0b1cc79623a49dcd5582ecc1c`,alt:`Grasshopper Speckle ribbon with the Publish and Load nodes`,\"data-og-width\":`2592`,width:`2592`,\"data-og-height\":`1728`,height:`1728`,\"data-path\":`images/connectors/grasshopper_toolbar.jpg`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_toolbar.jpg?w=280\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=407a6b5cc220655cc73f783358b0966e 280w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_toolbar.jpg?w=560\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=9c51883f819b2eae30b3f893ce101026 560w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_toolbar.jpg?w=840\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=339f8b89e0ac77a00f951e532eb2b9b4 840w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_toolbar.jpg?w=1100\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=4ded13d2a67777baf6ca7b93e59864a8 1100w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_toolbar.jpg?w=1650\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=e2ef377c243ec1024163fe688ead8b79 1650w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_toolbar.jpg?w=2500\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=fd3d421731cb60fb742d0224ed01a746 2500w`})}),`\n`,_jsx(Heading,{level:`2`,id:`when-to-componentise-a-grasshopper-definition`,children:`When to componentise a Grasshopper definition`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`When to use:`}),` Your definition is complex enough that separate files or owners make sense.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Identify natural module boundaries`,children:_jsx(_components.p,{children:`Look for stages that already exist in your definition such as “base geometry generation”,\n“analysis setup”, “visualisation prep”, or “documentation”. Each of these is a candidate module.`})}),_jsx(Step,{title:`Decide what each module owns`,children:_jsx(_components.p,{children:`For each stage, decide what it is responsible for producing (e.g. cleaned room solids with\nmetadata, analysis meshes, layout curves). These become the public outputs that downstream\nmodules rely on.`})}),_jsx(Step,{title:`Check who needs to work on each stage`,children:_jsx(_components.p,{children:`If different people or teams own different stages (e.g. design vs analysis), componentising\nmakes collaboration clearer. Even for one person, modules help separate experiments from stable\nlogic.`})})]}),`\n`,_jsx(_components.p,{children:`Outcome: A list of modules with clear responsibilities that you can split into separate Grasshopper files.`}),`\n`,_jsx(Heading,{level:`2`,id:`design-the-speckle-interfaces-between-modules`,children:`Design the Speckle interfaces between modules`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`When to use:`}),` Before creating separate Grasshopper files.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Create a Speckle project and models for the workflow`,children:_jsxs(_components.p,{children:[`In Speckle, create a project that will hold all models for this workflow. For each module, plan\none or more models (e.g. `,_jsx(_components.code,{children:`01_base-geometry`}),`, `,_jsx(_components.code,{children:`02_analysis-input`}),`, `,_jsx(_components.code,{children:`03_visualisation`}),`). A typical\npipeline: one module publishes base geometry to a model; a second consumes it and publishes\nanalysis input; a third consumes that and produces documentation or exports.`]})}),_jsx(Step,{title:`Define the contract for each module output`,children:_jsx(_components.p,{children:`For each module, decide what data will be sent to Speckle. Be explicit about object types,\nrequired properties, naming, and units. Treat this as a contract: downstream modules should be\nable to rely on it remaining stable.`})}),_jsx(Step,{title:`Choose how you will version data`,children:_jsx(_components.p,{children:`Decide whether downstream modules should always use the latest version of a model or pin to\nspecific versions for repeatable runs. For automated or production workflows, prefer pinned\nversions to avoid surprises.`})})]}),`\n`,_jsxs(_components.p,{children:[`The flow is: upstream Grasshopper file → `,_jsx(_components.strong,{children:`Publish`}),` → Speckle model → `,_jsx(_components.strong,{children:`Load`}),` → downstream Grasshopper file.`]}),`\n`,_jsx(_components.p,{children:`Outcome: A simple map of which models carry data between modules, and what each of them contains.`}),`\n`,_jsx(Heading,{level:`2`,id:`build-an-upstream-module-that-publishes-to-speckle`,children:`Build an upstream module that publishes to Speckle`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`When to use:`}),` Creating the first module in the chain that produces data for others.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Start a Grasshopper file for the module`,children:_jsx(_components.p,{children:`Copy only the part of your existing definition that belongs to this module into a new Grasshopper file. Keep its inputs focused on what this module actually needs to run.`})}),_jsxs(Step,{title:`Add a Publish node at the output`,children:[_jsxs(_components.p,{children:[`Place a `,_jsx(_components.strong,{children:`Publish`}),` node from the Speckle Grasshopper connector at the point where you want to expose data. Connect the geometry and data you identified in your contract as its input.`]}),_jsx(Frame,{children:_jsx(OptimizedImage,{src:`https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_publish.jpg?fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=86d7fe3d3f35cbecfa6fd149d82201ac`,alt:`Grasshopper definition with a Publish node publishing to Speckle`,\"data-og-width\":`2592`,width:`2592`,\"data-og-height\":`1728`,height:`1728`,\"data-path\":`images/connectors/grasshopper_publish.jpg`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_publish.jpg?w=280\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=4ab907ca9d64d32b20b58e192f974c53 280w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_publish.jpg?w=560\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=57b6aeb4bf689fc1aef0b298bdbbdb28 560w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_publish.jpg?w=840\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=aed356e78e819acf15881e57e59322ab 840w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_publish.jpg?w=1100\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=a26d30aedb4f55e35e6cc3080ff9c112 1100w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_publish.jpg?w=1650\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=53a18db4ef4538dc62f795788e439bee 1650w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_publish.jpg?w=2500\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=2168a5350aed7a8b6c1e698f21d3121c 2500w`})})]}),_jsx(Step,{title:`Configure account, server, project, and model`,children:_jsxs(_components.p,{children:[`Set up the Publish node with the correct Speckle account, server, project, and model name (e.g. `,_jsx(_components.code,{children:`01_base-geometry`}),`). Use clear, stable names that reflect the module’s role.`]})}),_jsx(Step,{title:`Shape data for downstream consumers`,children:_jsxs(_components.p,{children:[`Before publishing, clean and structure the data: group elements logically, wrap geometry in `,_jsx(_components.strong,{children:`Speckle Object`}),` nodes so names and properties sit on the object, ensure important properties are present and named consistently, and avoid publishing unused or experimental data. Aim for a tidy\nstructure that downstream modules do not need to reinterpret.`]})}),_jsx(Step,{title:`Publish and verify in Speckle`,children:_jsx(_components.p,{children:`Run the definition and publish. Open the project in Speckle, inspect the model, and confirm that objects, properties, and naming match your intended contract.`})})]}),`\n`,_jsx(_components.p,{children:`Outcome: A standalone Grasshopper module that publishes a well‑defined Speckle model for others to consume.`}),`\n`,_jsx(Heading,{level:`2`,id:`build-downstream-modules-that-consume-speckle-models`,children:`Build downstream modules that consume Speckle models`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`When to use:`}),` Creating modules that depend on data from earlier stages.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Start a new Grasshopper file per downstream module`,children:_jsx(_components.p,{children:`Create a separate Grasshopper definition for each downstream stage (e.g. analysis, reporting, documentation). Keep inputs and outputs explicit so the file is easy to reason about.`})}),_jsxs(Step,{title:`Add Load nodes for upstream models`,children:[_jsxs(_components.p,{children:[`Place one or more `,_jsx(_components.strong,{children:`Load`}),` nodes and point them at the upstream models (e.g. `,_jsx(_components.code,{children:`01_base-geometry`}),`). If stability matters, pin the node to a specific version.`]}),_jsx(Frame,{children:_jsx(OptimizedImage,{src:`https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_load.jpg?fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=4a718d9ea79960377476e5997aebc806`,alt:`Grasshopper definition with a Load node loading from Speckle`,\"data-og-width\":`2592`,width:`2592`,\"data-og-height\":`1728`,height:`1728`,\"data-path\":`images/connectors/grasshopper_load.jpg`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_load.jpg?w=280\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=fbcf07f0702a91c52008d07e9a6df9fa 280w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_load.jpg?w=560\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=d0df2d8321d2f541f176c7bdba876a0f 560w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_load.jpg?w=840\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=d926c345bb91618779bb693c80872a9b 840w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_load.jpg?w=1100\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=0cc113cb468aea0b87c987218af246ff 1100w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_load.jpg?w=1650\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=f6ac6a686894ddb8bca50b1c58aa4c0b 1650w, https://mintcdn.com/speckle/5UIlyL-HMgYLn0Bd/images/connectors/grasshopper_load.jpg?w=2500\u0026fit=max\u0026auto=format\u0026n=5UIlyL-HMgYLn0Bd\u0026q=85\u0026s=3dbce64ffc2bbf6e85bf7c8313172893 2500w`})})]}),_jsx(Step,{title:`Adapt loaded data to local needs`,children:_jsx(_components.p,{children:`Convert loaded objects into the types, structures, and units this module uses internally. This is also where you can add module‑specific properties or perform filtering based on tags or parameters.`})}),_jsx(Step,{title:`Optionally publish this module's outputs`,children:_jsxs(_components.p,{children:[`If another module will consume this stage, add a `,_jsx(_components.strong,{children:`Publish`}),` node at your module’s output and repeat the configuration and shaping steps. Choose a model that clearly names this stage (e.g.\n`,_jsx(_components.code,{children:`02_analysis-input`}),`).`]})}),_jsx(Step,{title:`Test modules together`,children:_jsxs(_components.p,{children:[`Run the upstream module to publish fresh data, then run the downstream module and confirm that the `,_jsx(_components.strong,{children:`Load`}),` nodes pick up the expected objects. Fix any contract mismatches before adding more complexity.`]})})]}),`\n`,_jsx(_components.p,{children:`Outcome: One or more downstream modules that reliably consume Speckle models from upstream and can themselves publish clean outputs.`}),`\n`,_jsx(Heading,{level:`2`,id:`coordinate-between-people-and-tools`,children:`Coordinate between people and tools`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`When to use:`}),` Multiple people, machines, or tools share responsibility for the pipeline.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Assign clear ownership per module`,children:_jsx(_components.p,{children:`Decide who owns each module and where its Grasshopper file lives (e.g. version‑controlled\nrepository). Owners are responsible for keeping the Speckle contracts stable and documented.`})}),_jsx(Step,{title:`Document contracts alongside the files`,children:_jsx(_components.p,{children:`For each module, record which Speckle project and models it reads and writes, and what each\noutput contains. A short README next to the Grasshopper file is often enough.`})}),_jsx(Step,{title:`Agree on change management`,children:_jsx(_components.p,{children:`Establish how upstream changes are communicated. For example, require a brief note whenever\nobject structure or key properties change, and schedule time for downstream owners to adapt.`})}),_jsx(Step,{title:`Run modules on appropriate machines`,children:_jsx(_components.p,{children:`Let heavy geometry or analysis modules run on powerful workstations or dedicated machines, while\nlighter reporting or visualisation modules can run elsewhere. Speckle models carry the data\nbetween them.`})})]}),`\n`,_jsx(_components.p,{children:`Outcome: Teams can work on different stages without sharing one large Grasshopper file, and changes propagate via well‑defined Speckle models.`}),`\n`,_jsx(Heading,{level:`2`,id:`common-patterns-and-pitfalls`,children:`Common patterns and pitfalls`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Pattern: Linear pipeline`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`One module publishes base geometry; another prepares analysis input; a third produces documentation or exports. Each stage reads from and writes to a dedicated Speckle model.`}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Pattern: Branching workflows`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`A single upstream model feeds multiple downstream modules (e.g. daylight analysis, cost estimation, visualisation). All downstream `,_jsx(_components.strong,{children:`Load`}),` nodes point at the same upstream model or version.`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Pitfall: Publishing everything`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Publishing the entire Grasshopper state makes downstream modules brittle and hard to understand. Instead, publish only what is needed and keep contracts small.`}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Pitfall: Unannounced schema changes`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Changing property names or structures without coordination breaks downstream modules. Treat contracts as shared APIs and change them deliberately.`}),`\n`]}),`\n`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`faq`,children:`FAQ`}),`\n`,_jsxs(AccordionGroup,{children:[_jsx(Accordion,{title:`How many modules should a workflow have?`,id:`how-many-modules-should-a-workflow-have`,children:_jsx(_components.p,{children:`Use as many modules as you need to keep responsibilities clear and files manageable. A common\npattern is 2–4 modules (e.g. base geometry, analysis prep, reporting, and exports) rather than a\nlarge number of very small ones.`})}),_jsx(Accordion,{title:`Can multiple downstream modules consume the same Speckle model?`,id:`can-multiple-downstream-modules-consume-the-same-speckle-model`,children:_jsx(_components.p,{children:`Yes. Any number of Grasshopper files or other tools can load from the same project and model.\nThis is a good way to centralise base geometry and fan out into specialised workflows.`})}),_jsx(Accordion,{title:`Should downstream modules always use the latest version?`,id:`should-downstream-modules-always-use-the-latest-version`,children:_jsxs(_components.p,{children:[`For exploratory work, using the latest version keeps things simple. For repeatable analysis or\nproduction runs, pin `,_jsx(_components.strong,{children:`Load`}),` nodes to specific versions so results can be reproduced and\ncompared reliably.`]})}),_jsx(Accordion,{title:`What if a downstream module needs extra data?`,id:`what-if-a-downstream-module-needs-extra-data`,children:_jsxs(_components.p,{children:[`Update the upstream module’s contract to include the additional properties or objects, then add\nthem to the `,_jsx(_components.strong,{children:`Publish`}),` node. Coordinate the change with all downstream owners so they can take\nadvantage of the new data without breaking existing logic.`]})}),_jsx(Accordion,{title:`How do I debug issues between modules?`,id:`how-do-i-debug-issues-between-modules`,children:_jsxs(_components.p,{children:[`First, inspect the upstream Speckle model in the web viewer to confirm that objects and\nproperties look as expected. Then check the `,_jsx(_components.strong,{children:`Load`}),` node configuration and any conversion logic\nin the downstream file. Work from the interface inwards rather than from deep inside the\ndefinition.`]})}),_jsx(Accordion,{title:`Can non-Grasshopper tools participate in the workflow?`,id:`can-non-grasshopper-tools-participate-in-the-workflow`,children:_jsx(_components.p,{children:`Yes. Any tool with a Speckle connector or SDK can read from and write to the same models. For\nexample, analysis tools, dashboards, or scripts can consume the outputs of Grasshopper modules\nor publish new stages in the pipeline.`})}),_jsx(Accordion,{title:`How big can the Speckle models between modules get?`,id:`how-big-can-the-speckle-models-between-modules-get`,children:_jsx(_components.p,{children:`Models can grow large, but very heavy payloads will affect publish and load times and downstream\nperformance. If models become unwieldy, consider splitting them by discipline, zone, or purpose\nso modules only consume what they need.`})}),_jsx(Accordion,{title:`Do I need Automate for componentised workflows?`,id:`do-i-need-automate-for-componentised-workflows`,children:_jsx(_components.p,{children:`No. Componentised workflows work with manual publishing and loading. Automate becomes useful\nwhen you want these modules to run automatically on triggers, but it is not required for the\npattern itself.`})})]}),`\n`,_jsx(Heading,{level:`2`,id:`see-also`,children:`See also`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/connectors/grasshopper/grasshopper`,children:`Grasshopper connector`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/connectors/overview`,children:`Connectors overview`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/analytics/intelligence-dashboards`,children:`Intelligence Dashboards`})}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Componentised Grasshopper workflow","sidebarTitle":"Grasshopper","description":"Break large Grasshopper definitions into modules that hand off data via Speckle models.","href":"/workflows/grasshopper-componentised-workflow"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"When to componentise a Grasshopper definition","slug":"when-to-componentise-a-grasshopper-definition","depth":2,"children":[]},{"title":"Design the Speckle interfaces between modules","slug":"design-the-speckle-interfaces-between-modules","depth":2,"children":[]},{"title":"Build an upstream module that publishes to Speckle","slug":"build-an-upstream-module-that-publishes-to-speckle","depth":2,"children":[]},{"title":"Build downstream modules that consume Speckle models","slug":"build-downstream-modules-that-consume-speckle-models","depth":2,"children":[]},{"title":"Coordinate between people and tools","slug":"coordinate-between-people-and-tools","depth":2,"children":[]},{"title":"Common patterns and pitfalls","slug":"common-patterns-and-pitfalls","depth":2,"children":[]},{"title":"FAQ","slug":"faq","depth":2,"children":[]},{"title":"See also","slug":"see-also","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/speckle/338e4d421a1293df/.omp/extensions/atlas-sync.js"],"subdomain":"speckle","siteName":"Speckle Docs","title":"Componentised Grasshopper workflow - Speckle Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-19T09:16:26.538Z","gitLastModified":"2026-10-19T08:27:13.000Z","originalFileLocation":"workflows/grasshopper-componentised-workflow.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Break large Grasshopper definitions into modules that hand off data via Speckle models.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Speckle Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Componentised Grasshopper workflow - Speckle Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Break large Grasshopper definitions into modules that hand off data via Speckle models.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Speckle Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://speckle.mintlify.app/_mintlify/api/og/v2?division=Workflows\u0026amp;title=Componentised+Grasshopper+workflow\u0026amp;description=Break+large+Grasshopper+definitions+into+modules+that+hand+off+data+via+Speckle+models.\u0026amp;theme=0f587db618e29aef1bad566c\u0026amp;signature=b22d6eecdb0e68f46c8894deaee104fe5e7eab22c732cebd0c3ff868627107f5\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Componentised Grasshopper workflow - Speckle Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Break large Grasshopper definitions into modules that hand off data via Speckle models.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://speckle.mintlify.app/_mintlify/api/og/v2?division=Workflows\u0026amp;title=Componentised+Grasshopper+workflow\u0026amp;description=Break+large+Grasshopper+definitions+into+modules+that+hand+off+data+via+Speckle+models.\u0026amp;theme=0f587db618e29aef1bad566c\u0026amp;signature=b22d6eecdb0e68f46c8894deaee104fe5e7eab22c732cebd0c3ff868627107f5\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/speckle/1IrIIntzKgAhEEgb/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Speckle Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#2563EB\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/workflows/grasshopper-componentised-workflow.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.speckle.systems/#organization\",\"name\":\"Speckle Docs\",\"url\":\"https://docs.speckle.systems\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/speckle/8FGkkbZZbcuHzOBq/logo/light.svg?fit=max\u0026auto=format\u0026n=8FGkkbZZbcuHzOBq\u0026q=85\u0026s=9fc87cac252fa8cc443a9828ecbace70\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.speckle.systems#website\",\"name\":\"Speckle Docs\",\"url\":\"https://docs.speckle.systems\",\"publisher\":{\"@id\":\"https://docs.speckle.systems/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow#webpage\",\"url\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow\",\"name\":\"Componentised Grasshopper workflow\",\"description\":\"Break large Grasshopper definitions into modules that hand off data via Speckle models.\",\"dateModified\":\"2026-10-19T08:27:13.000Z\",\"isPartOf\":{\"@id\":\"https://docs.speckle.systems#website\"},\"breadcrumb\":{\"@id\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Workflows\",\"item\":\"https://docs.speckle.systems/workflows/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Componentised Grasshopper workflow\",\"item\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow#article\",\"headline\":\"Componentised Grasshopper workflow\",\"name\":\"Componentised Grasshopper workflow\",\"description\":\"Break large Grasshopper definitions into modules that hand off data via Speckle models.\",\"url\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow\",\"mainEntityOfPage\":{\"@id\":\"https://docs.speckle.systems/workflows/grasshopper-componentised-workflow#webpage\"},\"dateModified\":\"2026-10-19T08:27:13.000Z\",\"publisher\":{\"@id\":\"https://docs.speckle.systems/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.speckle.systems#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Speckle Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Speckle Docs","nav":{"global":null,"dropdowns":[{"dropdown":"User Guides","icon":"book-open","groups":[{"group":"Quick Reference","pages":[{"title":"Welcome to Speckle","sidebarTitle":"Welcome","href":"/quickstart/welcome"},{"title":"Speckle's new data model: what has changed for you","sidebarTitle":"Data model migration","href":"/workspaces/data-model-migration"},{"title":"Quickstart Guide","href":"/quickstart/quickstart"},{"title":"Frequently Asked Questions","href":"/quickstart/faq"},{"title":"What's new in 2026.9 for workspace users","sidebarTitle":"What's new","href":"/whats-new/users"}]},{"group":"Your Speckle Workspace","pages":[{"title":"Organize teams and projects","sidebarTitle":"Overview","href":"/workspaces/introduction"},{"group":"Projects, Models, and Versions","pages":[{"title":"Projects","href":"/workspaces/projects"},{"title":"Models","href":"/workspaces/models"},{"title":"Version Control","href":"/workspaces/versions"}]},{"group":"Access and Identity","pages":[{"title":"Roles and permissions","href":"/workspaces/roles-and-seats"},{"title":"Invite to Workspace","href":"/workspaces/inviting"},{"title":"Workspace Discoverability","href":"/workspaces/workspace-discoverability"},{"title":"Domain Protection","href":"/workspaces/domain-protection"},{"title":"Single Sign-On (SSO)","tag":"Enterprise","href":"/workspaces/sso"},{"title":"User provisioning (SCIM)","sidebarTitle":"Provisioning (SCIM)","tag":"Enterprise","href":"/workspaces/scim"}]},{"group":"Plans and Governance","pages":[{"title":"Plans and Governance","sidebarTitle":"Overview","href":"/workspaces/plans-and-governance"},{"title":"Billing","href":"/workspaces/billing"},{"title":"Data Residency","tag":"Enterprise","href":"/workspaces/data-residency"}]},{"group":"Configuration","pages":[{"title":"Configuration","href":"/workspaces/configuration"},{"title":"Check workspace activity, plan limits, and AI spend","sidebarTitle":"Usage","href":"/workspaces/usage"},{"title":"Project metadata","tag":"Enterprise","href":"/workspaces/configuration/project-metadata"}]}]},{"group":"Viewing \u0026 Sharing","pages":[{"title":"Open and explore models in the 3D viewer","sidebarTitle":"Overview","href":"/3d-viewer/introduction"},{"title":"Interface and navigation","href":"/3d-viewer/interface-nav"},{"group":"Inspect and Compare","pages":[{"title":"Filter, browse, and measure your model","sidebarTitle":"Exploration","href":"/3d-viewer/exploration"},{"title":"Compare versions","href":"/3d-viewer/compare-versions"},{"title":"Combine models in one scene","sidebarTitle":"Model federation","href":"/3d-viewer/federation"}]},{"group":"Feedback and Tracking","pages":[{"title":"Issues","href":"/3d-viewer/issues"},{"title":"Sketch on your model","sidebarTitle":"Sketch","href":"/3d-viewer/markups"},{"title":"Saved views","href":"/3d-viewer/saved-views"}]},{"group":"Present and Share","pages":[{"title":"Present a model with saved views","sidebarTitle":"Presentation","href":"/3d-viewer/presentation"},{"title":"Share your models","href":"/3d-viewer/sharing"}]}]},{"group":"Publishing \u0026 Loading","pages":[{"title":"Connectors, cloud integrations, and file uploads","sidebarTitle":"Overview","href":"/connectors/overview"},{"group":"Connectors","pages":[{"title":"Installing Connectors","href":"/connectors/installation"},{"title":"Connector Assets \u0026 Templates","sidebarTitle":"Assets \u0026 Templates","href":"/connectors/assets"},{"group":"Revit","pages":[{"title":"How to use Speckle for Revit","sidebarTitle":"Quickstart","href":"/connectors/revit/revit"},{"title":"Loading blocks as families in Revit","sidebarTitle":"Blocks as Families","href":"/connectors/revit/blocks-to-families"}]},{"group":"Rhino","pages":[{"title":"How to use Speckle for Rhino","sidebarTitle":"Quickstart","href":"/connectors/rhino/rhino"},{"title":"Revit Categorization","href":"/connectors/rhino/rhino-revit"},{"title":"RhinoInside","sidebarTitle":"RhinoInside","href":"/connectors/grasshopper/grasshopper-integrations"}]},{"group":"Grasshopper","pages":[{"title":"How to use Speckle for Grasshopper","sidebarTitle":"Quickstart","href":"/connectors/grasshopper/grasshopper"},{"title":"Explore what an object is connected to","sidebarTitle":"Explore","href":"/connectors/grasshopper/explore"},{"title":"Models","href":"/connectors/grasshopper/grasshopper-models"},{"title":"Collections","href":"/connectors/grasshopper/grasshopper-collections"},{"title":"Objects","href":"/connectors/grasshopper/grasshopper-objects"},{"title":"Properties","href":"/connectors/grasshopper/grasshopper-properties"},{"title":"Developer Nodes","href":"/connectors/grasshopper/grasshopper-developer"},{"title":"Recommendations","href":"/connectors/grasshopper/grasshopper-recommendations"},{"title":"Karamba3D","sidebarTitle":"Karamba3D","tag":"Third-Party","href":"/connectors/third-party/karamba3d"},{"title":"ShapeDiver","sidebarTitle":"ShapeDiver","tag":"Third-Party","href":"/connectors/third-party/shapediver"}]},{"title":"How to use Speckle for SketchUp","sidebarTitle":"SketchUp","href":"/connectors/sketchup"},{"group":"Power BI","pages":[{"title":"How to use Speckle for Power BI","sidebarTitle":"Quickstart","href":"/connectors/power-bi/power-bi"},{"title":"Power BI Data Gateway","sidebarTitle":"Data Gateway","href":"/connectors/power-bi/gateway"}]},{"title":"How to use Speckle for Archicad","sidebarTitle":"Archicad","href":"/connectors/archicad"},{"title":"Publish Navisworks models to Speckle","sidebarTitle":"Navisworks","href":"/connectors/navisworks"},{"title":"How to use Speckle for Blender","sidebarTitle":"Blender","href":"/connectors/blender"},{"title":"How to use Speckle for Civil 3D","sidebarTitle":"Civil 3D","href":"/connectors/civil3d"},{"title":"How to use Speckle for Plant 3D","sidebarTitle":"Plant 3D","href":"/connectors/plant3d"},{"title":"How to use Speckle for AutoCAD","sidebarTitle":"AutoCAD","href":"/connectors/autocad"},{"title":"How to use Speckle for ETABS","sidebarTitle":"ETABS","href":"/connectors/etabs"},{"title":"How to use Speckle for Tekla Structures","sidebarTitle":"Tekla Structures","href":"/connectors/teklastructures"},{"title":"How to use Speckle for Vectorworks","sidebarTitle":"Vectorworks","tag":"Third-Party","href":"/connectors/third-party/vectorworks"}]},{"group":"Cloud Integrations","pages":[{"title":"Autodesk Forma Data Management","sidebarTitle":"Forma Data Management (ACC)","tag":"Enterprise","href":"/connectors/cloud-integrations/acc"},{"title":"Sync models from Trimble Connect","sidebarTitle":"Trimble Connect","tag":"Enterprise","href":"/connectors/cloud-integrations/trimble-connect"},{"title":"Sync models from SharePoint","sidebarTitle":"SharePoint","href":"/connectors/cloud-integrations/sharepoint"},{"title":"Bentley ProjectWise","sidebarTitle":"Bentley ProjectWise","tag":"Enterprise","href":"/connectors/cloud-integrations/projectwise"},{"title":"Databricks","sidebarTitle":"Databricks","href":"/connectors/cloud-integrations/databricks"},{"title":"Snowflake","sidebarTitle":"Snowflake","href":"/connectors/cloud-integrations/snowflake"}]},{"title":"Direct uploads","href":"/connectors/direct-uploads/introduction"}]},{"group":"Analytics \u0026 Intelligence","pages":[{"group":"Intelligence","pages":[{"title":"Ask questions about your models with Speckle Intelligence","sidebarTitle":"Speckle Intelligence","href":"/analytics/intelligence"},{"title":"Reuse organisation playbooks with Intelligence skills","sidebarTitle":"Skills","href":"/analytics/intelligence-skills"},{"title":"Set standing AI Rules for the workspace","sidebarTitle":"AI Rules","href":"/analytics/intelligence-rules"},{"title":"Create and share Intelligence Reports","sidebarTitle":"Reports","href":"/analytics/reports"}]},{"group":"Dashboards","pages":[{"title":"Intelligence Dashboards","sidebarTitle":"Overview","href":"/analytics/intelligence-dashboards"},{"title":"Retired and replaced dashboard widgets","sidebarTitle":"Widget availability","href":"/analytics/dashboards-widget-availability"},{"title":"Layout","sidebarTitle":"Layout","href":"/analytics/dashboards/layout"},{"title":"Sharing","sidebarTitle":"Sharing","href":"/analytics/dashboards/sharing"},{"title":"Filters","sidebarTitle":"Filters","href":"/analytics/dashboards/filters"},{"title":"Lookup tables","sidebarTitle":"Lookup tables","href":"/analytics/dashboards/lookup-tables"},{"title":"Calculated fields","sidebarTitle":"Calculated fields","href":"/analytics/dashboards/calculated-fields"},{"title":"Common workflows","sidebarTitle":"Common workflows","href":"/analytics/dashboards/common-workflows"}]},{"group":"Data Validation","pages":[{"title":"Data Validation","sidebarTitle":"Overview","href":"/analytics/data-validation/overview"},{"title":"Checks","sidebarTitle":"Checks","href":"/analytics/data-validation/checks"},{"title":"Project standards","sidebarTitle":"Standards","href":"/analytics/data-validation/standards"},{"title":"Viewing Results","sidebarTitle":"Viewing Results","href":"/analytics/data-validation/viewing-results"},{"title":"Validation Widgets in Dashboards","sidebarTitle":"Validation Widgets","href":"/analytics/dashboards/validation-widgets"}]},{"group":"Data Conditioning","pages":[{"title":"Update parameters from the model viewer","sidebarTitle":"Parameter Updater","href":"/beta/parameter-updater"}]}]},{"group":"Workflows","pages":[{"title":"Combine capabilities into outcomes","sidebarTitle":"Overview","href":"/workflows/overview"},{"title":"Assess model changes with Speckle Intelligence","sidebarTitle":"Compare versions with Intelligence","href":"/workflows/assess-model-changes"},{"title":"Take off quantities and cost with Speckle Intelligence","sidebarTitle":"Quantity \u0026 cost takeoff","href":"/workflows/take-off-quantities"},{"title":"Benchmark a project against your portfolio with Speckle Intelligence","sidebarTitle":"Portfolio benchmarking","href":"/workflows/benchmark-against-your-portfolio"},{"title":"Validate incoming models automatically","sidebarTitle":"Automatic model validation","href":"/workflows/validate-incoming-models-automatically"},{"title":"Design review workflow","sidebarTitle":"Design Review","description":"Run structured design reviews in Speckle using saved views, federation, sketches, and issues.","href":"/workflows/design-review-workflow"},{"title":"Componentised Grasshopper workflow","sidebarTitle":"Grasshopper","href":"/workflows/grasshopper-componentised-workflow"},{"title":"Compare parametric design options from Grasshopper","sidebarTitle":"Design Explorer","description":"Publish Grasshopper design options and compare their geometry and numeric properties in a dashboard.","href":"/workflows/grasshopper-design-explorer"},{"title":"Extract Revit room data with SpecklePy","sidebarTitle":"Revit room data extraction","href":"/workflows/revit-room-data-extraction-specklepy"},{"title":"Analyse model data with SpecklePy and DuckDB","sidebarTitle":"SpecklePy analytics","href":"/workflows/specklepy-model-data-analytics"}]}],"global":{"anchors":[]}},{"dropdown":"Developers","icon":"code","tabs":[{"tab":"Build with Speckle","groups":[{"group":"Overview","pages":[{"title":"Developer documentation","sidebarTitle":"Introduction","href":"/developers/introduction"},{"title":"What's new in 2026.9 for developers","sidebarTitle":"What's new","href":"/whats-new/developers"}]},{"group":"Getting Started","pages":[{"title":"Your learning path","sidebarTitle":"Your Learning Path","href":"/developers/getting-started"},{"group":"Authentication","pages":[{"title":"Authenticating with Speckle","sidebarTitle":"Introduction","href":"/developers/authentication/introduction"},{"title":"Building with PATs","sidebarTitle":"PATs","href":"/developers/authentication/pats"},{"title":"Building with OAuth2","sidebarTitle":"OAuth2 and PKCE","href":"/developers/authentication/oauth2"},{"title":"Single Sign-On (SSO) Authentication","sidebarTitle":"SSO Authentication","href":"/developers/authentication/sso"}]},{"title":"Key Concepts","sidebarTitle":"Key Concepts","href":"/developers/key-concepts"}]},{"group":"Building Custom Apps","pages":[{"title":"Building Custom Applications","sidebarTitle":"Building Custom Apps","href":"/developers/building-apps"}]},{"group":"Building Integrations","pages":[{"title":"Add Speckle connectivity to your authoring applications","sidebarTitle":"Overview","href":"/developers/building-integrations"},{"title":"Build integrations on the bundle format","sidebarTitle":"Bundles","href":"/developers/building-integrations/bundles"},{"title":"Publish a bundle from your own code","sidebarTitle":"Publish","href":"/developers/building-integrations/publish"},{"title":"Load a bundle in your own code","sidebarTitle":"Load","href":"/developers/building-integrations/load"},{"title":"Publish, load, and integration depth","sidebarTitle":"Publish \u0026 Load","href":"/developers/connectivity/integration-depth"},{"title":"Desktop host connectivity","sidebarTitle":"Desktop Host","href":"/developers/connectivity/desktop-host"},{"title":"Cloud and automation connectivity","sidebarTitle":"Cloud \u0026 Automation","href":"/developers/connectivity/cloud-automation"},{"title":"Middleware and orchestration","sidebarTitle":"Middleware","href":"/developers/connectivity/middleware"},{"title":"Hybrid connectivity","sidebarTitle":"Hybrid","href":"/developers/connectivity/hybrid"},{"title":"Data model and build order","sidebarTitle":"Data \u0026 Build Order","href":"/developers/connectivity/data-and-build"},{"title":"Connectivity resources","sidebarTitle":"Resources","href":"/developers/connectivity/resources"}]},{"group":"Migration notices","hidden":true,"pages":[{"title":"Speckle's new data model: what has changed for developers","sidebarTitle":"Data model migration","href":"/developers/migration/data-model-migration"},{"title":"Publish through model ingestions, not legacy send","sidebarTitle":"Publish via ingestions","href":"/developers/migration/publish-through-ingestions"}]}]},{"tab":"Data Schema","groups":[{"group":"Object model","pages":[{"title":"Object model","sidebarTitle":"Overview","href":"/developers/object-model/overview"},{"title":"Relations","sidebarTitle":"Relations","href":"/developers/object-model/relations"},{"title":"Where version metadata lives","sidebarTitle":"Version metadata","href":"/developers/object-model/version-metadata"},{"title":"Geometry encoding","sidebarTitle":"Geometry encoding","href":"/developers/object-model/geometry-encoding"}]},{"group":"Object graph (before 2026.9)","pages":[{"title":"Data schema","href":"/developers/data-schema/overview"},{"title":"Core Concepts","href":"/developers/data-schema/concepts"},{"title":"Versions and the root object","href":"/developers/data-schema/version-root-object"},{"title":"Object Schema","href":"/developers/data-schema/object-schema"},{"title":"Traversal Recipes","href":"/developers/data-schema/traversal-recipes"},{"title":"Geometry Schema","href":"/developers/data-schema/geometry-schema"},{"title":"Proxy Schemas","href":"/developers/data-schema/proxy-schema"}]},{"group":"Connectors","pages":[{"title":"Object Types by Connector","sidebarTitle":"Object Types","href":"/developers/data-schema/connector-index"},{"group":"Schemas by Data Source","pages":[{"title":"ArchiCAD Schema","href":"/developers/data-schema/connectors/archicad-schema"},{"title":"IFC Schema","href":"/developers/data-schema/connectors/ifc-schema"},{"title":"Navisworks Schema","href":"/developers/data-schema/connectors/navisworks-schema"},{"title":"Revit Schema","href":"/developers/data-schema/connectors/revit-schema"},{"title":"Tekla Schema","href":"/developers/data-schema/connectors/tekla-schema"},{"title":"AutoCAD Schema","href":"/developers/data-schema/connectors/autocad-schema"},{"title":"Civil 3D Schema","href":"/developers/data-schema/connectors/civil3d-schema"},{"title":"ETABS Schema","href":"/developers/data-schema/connectors/etabs-schema"},{"title":"Rhino Schema","href":"/developers/data-schema/connectors/rhino-schema"}]}]}]},{"tab":"Interfaces","groups":[{"group":"GraphQL","pages":[{"title":"API reference","href":"/developers/api/graphql"},{"title":"Subscriptions","href":"/developers/api/subscriptions"},{"title":"GraphQL Endpoint","deprecated":null,"version":null,"openapi":"/developers/api/graphql-openapi.json post /graphql","href":"/api-reference/graphql/graphql-endpoint"}]},{"group":"REST","pages":[{"title":"API reference","href":"/developers/api/rest"},{"title":"Preview Service","href":"/developers/api/previews/preview-service"},{"title":"Download a Single Object","deprecated":null,"version":null,"openapi":"/developers/api/rest-openapi.json get /objects/{projectId}/{objectId}/single","href":"/api-reference/objects/download-a-single-object"},{"title":"Download an Object and All its Children","deprecated":null,"version":null,"openapi":"/developers/api/rest-openapi.json get /objects/{projectId}/{objectId}","href":"/api-reference/objects/download-an-object-and-all-its-children"}]},{"group":"Webhooks","pages":[{"title":"Broadcast and Subscribe to Speckle Events with Webhooks","sidebarTitle":"Webhooks Overview","href":"/developers/api/webhooks"},{"title":"Events and Payloads","href":"/developers/api/webhooks/events"},{"title":"Creating and Managing Webhooks","href":"/developers/api/webhooks/management"},{"title":"Webhook Security","href":"/developers/api/webhooks/security"}]},{"group":"Guides","pages":[{"title":"Upload IFC and other files to Speckle","sidebarTitle":"Upload files","href":"/developers/api/guides/file-uploads"},{"title":"Read and Write Project Metadata via GraphQL","sidebarTitle":"Project metadata","tag":"Enterprise","href":"/developers/api/guides/project-metadata"},{"title":"Updating Cloud Integration Syncs via GraphQL","sidebarTitle":"Updating Syncs","href":"/developers/api/guides/updating-syncs"},{"title":"Get Data Validation Results with GraphQL","sidebarTitle":"Validation Results","href":"/developers/api/guides/data-validation-results"},{"title":"Send Slack Notifications from Speckle Webhooks","sidebarTitle":"Slack Notifications","href":"/developers/api/guides/slack-notifications"}]}]},{"tab":"SDKs","groups":[{"group":"Speckle SDKs","pages":[{"title":"Introduction","sidebarTitle":"Introduction","href":"/developers/sdks/introduction"}]},{"group":"Python","icon":"python","pages":[{"title":"specklepy","href":"/developers/sdks/python/introduction"},{"title":"Migrate a specklepy script to 2026.9","sidebarTitle":"Migrate to 2026.9","href":"/developers/sdks/python/migrate-to-2026-9"},{"group":"Getting Started","pages":[{"title":"Installation","href":"/developers/sdks/python/getting-started/installation"},{"title":"Authentication","href":"/developers/sdks/python/getting-started/authentication"},{"title":"Quickstart","href":"/developers/sdks/python/getting-started/quickstart"}]},{"group":"Core Concepts","pages":[{"title":"Python SDK concepts","href":"/developers/sdks/python/concepts/overview"},{"title":"Data Types in Speckle","href":"/developers/sdks/python/concepts/data-types"},{"title":"Objects \u0026 Base Class","href":"/developers/sdks/python/concepts/objects"},{"title":"Data Traversal","href":"/developers/sdks/python/concepts/data-traversal"},{"title":"Display Values","href":"/developers/sdks/python/concepts/display-values"},{"title":"Proxification","href":"/developers/sdks/python/concepts/proxification"}]},{"group":"API Reference","pages":[{"title":"SpeckleClient","href":"/developers/sdks/python/api-reference/client"},{"title":"Operations","href":"/developers/sdks/python/api-reference/operations"},{"group":"Resources","pages":[{"title":"ProjectResource","href":"/developers/sdks/python/api-reference/resources/project"},{"title":"ModelResource","href":"/developers/sdks/python/api-reference/resources/model"},{"title":"VersionResource","href":"/developers/sdks/python/api-reference/resources/version"},{"title":"ActiveUserResource","href":"/developers/sdks/python/api-reference/resources/active-user"},{"title":"OtherUserResource","href":"/developers/sdks/python/api-reference/resources/other-user"},{"title":"WorkspaceResource","href":"/developers/sdks/python/api-reference/resources/workspace"},{"title":"ServerResource","href":"/developers/sdks/python/api-reference/resources/server"}]},{"title":"Transports","href":"/developers/sdks/python/api-reference/transports"},{"title":"Exceptions","href":"/developers/sdks/python/api-reference/exceptions"}]},{"group":"Guides","pages":[{"title":"Working with Speckle Objects","href":"/developers/sdks/python/guides/how-to-work-with-objects"},{"title":"Finding and Extracting Data","href":"/developers/sdks/python/guides/how-to-find-and-extract-data"},{"title":"Performance and Complex Patterns","href":"/developers/sdks/python/guides/how-to-optimize-and-handle-complexity"},{"title":"Simple Data Patterns","href":"/developers/sdks/python/guides/simple-data-patterns"},{"title":"BIM Data Patterns","href":"/developers/sdks/python/guides/bim-data-patterns"},{"title":"Extracting Display Values and Transform Instances","href":"/developers/sdks/python/guides/working-with-proxies"},{"title":"Understanding Speckle Mesh","href":"/developers/sdks/python/guides/understanding-speckle-mesh"},{"title":"Working with Geometry","href":"/developers/sdks/python/guides/working-with-geometry"}]}]},{"group":"C# .NET","icon":"microsoft","pages":[{"title":"speckle-sharp","sidebarTitle":"speckle-sharp","href":"/developers/sdks/dotnet/introduction"},{"title":"Migrate a Speckle.Sdk script to 2026.9","sidebarTitle":"Migrate to 2026.9","href":"/developers/sdks/dotnet/migrate-to-2026-9"},{"group":"Getting Started","pages":[{"title":"Installation","sidebarTitle":"Installation","href":"/developers/sdks/dotnet/getting-started/installation"},{"title":"Build your first model analysis tool","sidebarTitle":"First analysis tool","href":"/developers/sdks/dotnet/guides/build-your-first-model-analysis-tool"},{"title":"Automate with scripts and notebooks","sidebarTitle":"Scripts","href":"/developers/sdks/dotnet/getting-started/scripts-and-notebooks"},{"title":"Authentication","sidebarTitle":"Authentication","href":"/developers/sdks/dotnet/getting-started/authentication"},{"title":"Publish and load a model from C#","sidebarTitle":"Quickstart","href":"/developers/sdks/dotnet/getting-started/quickstart"}]},{"group":"Guides","pages":[{"title":"Use SpeckleSharp in a Grasshopper C# node","sidebarTitle":"Grasshopper C#","href":"/developers/sdks/dotnet/guides/use-speckle-sdk-in-grasshopper-csharp"},{"title":"Find objects by property","sidebarTitle":"Find \u0026 extract","href":"/developers/sdks/dotnet/guides/finding-and-extracting-data"},{"title":"Export model data to CSV","sidebarTitle":"Export to CSV","href":"/developers/sdks/dotnet/guides/export-model-data-to-csv"},{"title":"Send analysis results back to Speckle","sidebarTitle":"Send results back","href":"/developers/sdks/dotnet/guides/send-analysis-results-back"},{"title":"BIM data patterns","sidebarTitle":"BIM patterns","href":"/developers/sdks/dotnet/guides/bim-data-patterns"},{"title":"Compare two model versions","sidebarTitle":"Compare versions","href":"/developers/sdks/dotnet/guides/compare-two-model-versions"},{"title":"Resolve groups and instances","sidebarTitle":"Proxies","href":"/developers/sdks/dotnet/guides/working-with-proxies"},{"title":"Read and create geometry","sidebarTitle":"Geometry","href":"/developers/sdks/dotnet/guides/working-with-geometry"},{"title":"Handling server capabilities","href":"/developers/sdks/dotnet/guides/handling-server-capabilities"},{"title":"Publish large models (connectors)","sidebarTitle":"Connector sends","href":"/developers/sdks/dotnet/guides/building-connector-scale-sends"}]},{"group":"Concepts","pages":[{"title":"How your code talks to Speckle Server","sidebarTitle":"Core concepts","href":"/developers/sdks/dotnet/concepts/overview"},{"title":"Work with model objects","sidebarTitle":"Objects","href":"/developers/sdks/dotnet/concepts/objects-and-traversal"},{"title":"Load and publish model data","sidebarTitle":"Send \u0026 receive","href":"/developers/sdks/dotnet/concepts/send-and-receive-paths"},{"title":"Dependency injection (connectors)","sidebarTitle":"DI (advanced)","href":"/developers/sdks/dotnet/concepts/dependency-injection"}]},{"group":"API Reference","pages":[{"title":"Client","sidebarTitle":"Client","href":"/developers/sdks/dotnet/api-reference/client"},{"title":"Service registration","sidebarTitle":"Registration","href":"/developers/sdks/dotnet/api-reference/service-registration"},{"title":"Operations","sidebarTitle":"Operations","href":"/developers/sdks/dotnet/api-reference/operations"},{"group":"Resources","pages":[{"title":"Project","sidebarTitle":"Project","href":"/developers/sdks/dotnet/api-reference/resources/project"},{"title":"Model","sidebarTitle":"Model","href":"/developers/sdks/dotnet/api-reference/resources/model"},{"title":"Version","sidebarTitle":"Version","href":"/developers/sdks/dotnet/api-reference/resources/version"},{"title":"Users","sidebarTitle":"Users","href":"/developers/sdks/dotnet/api-reference/resources/users"},{"title":"Workspace","sidebarTitle":"Workspace","href":"/developers/sdks/dotnet/api-reference/resources/workspace"},{"title":"Server","sidebarTitle":"Server","href":"/developers/sdks/dotnet/api-reference/resources/server"},{"title":"Model ingestion","sidebarTitle":"Ingestion","href":"/developers/sdks/dotnet/api-reference/resources/ingestion"}]},{"title":"Transports","sidebarTitle":"Transports","href":"/developers/sdks/dotnet/api-reference/transports"},{"title":"Exceptions","sidebarTitle":"Exceptions","href":"/developers/sdks/dotnet/api-reference/exceptions"}]}]},{"group":"JS/TS","icon":"javascript","pages":[{"title":"speckle.js","href":"/developers/sdks/typescript/introduction"}]}]},{"tab":"Viewer","groups":[{"group":"Speckle Viewer","pages":[{"title":"Developers Guide","sidebarTitle":"Getting Started","href":"/developers/viewer/introduction"},{"title":"Load a bundle in your Viewer app","sidebarTitle":"Loading bundles","href":"/developers/viewer/loading-bundles"},{"title":"Installation","href":"/developers/viewer/installation"},{"title":"Basic Setup","href":"/developers/viewer/basic-setup"},{"title":"Advanced Setup","href":"/developers/viewer/advanced-setup"}]},{"group":"Core Concepts","pages":[{"title":"3D Viewer","href":"/developers/viewer/overview"},{"title":"Data Tree","href":"/developers/viewer/viewer-data"},{"title":"Rendering","href":"/developers/viewer/viewer-rendering"},{"title":"Loaders","href":"/developers/viewer/loaders"}]},{"group":"API Reference","pages":[{"group":"Viewer Core","pages":[{"title":"AccelerationStructure","href":"/developers/viewer/acceleration-structure-api"},{"title":"Batch","href":"/developers/viewer/batch-api"},{"title":"BatchObject","href":"/developers/viewer/batch-object-api"},{"title":"GeometryConverter","href":"/developers/viewer/geometry-converter-api"},{"title":"Input","href":"/developers/viewer/input-api"},{"title":"Intersections","href":"/developers/viewer/intersections-api"},{"title":"Loader","href":"/developers/viewer/loader-api"},{"title":"Queries","href":"/developers/viewer/queries-api"},{"title":"NodeRenderView","href":"/developers/viewer/render-view-api"},{"title":"RenderTree","href":"/developers/viewer/render-tree-api"},{"group":"Rendering Pipelines","pages":[{"title":"Pipeline","href":"/developers/viewer/rendering-pipeline-api/pipeline-api"},{"title":"ProgressivePipeline","href":"/developers/viewer/rendering-pipeline-api/progressive-pipeline-api"},{"title":"GPass","href":"/developers/viewer/rendering-pipeline-api/g-pass-api"},{"title":"BaseGPass","href":"/developers/viewer/rendering-pipeline-api/base-g-pass-api"},{"title":"ProgressiveGPass","href":"/developers/viewer/rendering-pipeline-api/progressive-g-pass-api"}]},{"title":"SpeckleMaterial","href":"/developers/viewer/speckle-material-api"},{"title":"SpeckleRenderer","href":"/developers/viewer/speckle-renderer-api"},{"title":"TopLevelAccelerationStructure","href":"/developers/viewer/top-level-acceleration-structure-api"},{"title":"Viewer","href":"/developers/viewer/viewer-api"},{"title":"WorldTree","href":"/developers/viewer/world-tree-api"}]},{"group":"Extensions","pages":[{"title":"Extension","href":"/developers/viewer/extensions/extension-api"},{"title":"CameraController","href":"/developers/viewer/extensions/camera-controller-api"},{"title":"DifExtension","href":"/developers/viewer/extensions/diff-extension-api"},{"title":"FilteringExtension","href":"/developers/viewer/extensions/filtering-extension-api"},{"title":"MeasurementsTool","href":"/developers/viewer/extensions/measurements-tool-api"},{"title":"SelectionExtension","href":"/developers/viewer/extensions/selection-extension-api"},{"title":"SectionTool","href":"/developers/viewer/extensions/section-tool-api"},{"title":"SectionToolOutlines","href":"/developers/viewer/extensions/section-tool-outlines-api"},{"title":"SpeckleControls","href":"/developers/viewer/extensions/speckle-controls-api"},{"title":"SmoothOrbitControls","href":"/developers/viewer/extensions/smooth-orbit-controls-api"},{"title":"ViewModes","href":"/developers/viewer/extensions/view-modes-api"}]}]},{"group":"Examples","pages":[{"title":"Basic Example","href":"/developers/viewer/examples/basic-example"},{"title":"More Extensions","href":"/developers/viewer/examples/more-extensions-example"},{"title":"Filtering","href":"/developers/viewer/examples/filtering-example"},{"title":"Loading Data","href":"/developers/viewer/examples/loading-example"},{"title":"Object Manipulation","href":"/developers/viewer/examples/object-manipulation-example"},{"title":"Box Selection","href":"/developers/viewer/examples/box-selection-example"},{"title":"Animation \u0026 Custom Text","href":"/developers/viewer/examples/categorize-example"}]},{"group":"Reference","pages":[{"title":"Migration Guide","href":"/developers/viewer/migration-guide"},{"title":"Backwards Compatibility","href":"/developers/viewer/migration-guide-compatibility"},{"title":"API 1.0 Full Migration","href":"/developers/viewer/migration-guide-v1"}]}]},{"tab":"Server","groups":[{"group":"Speckle Server","pages":[{"title":"Hosting Your Own Speckle Server","sidebarTitle":"Overview","href":"/developers/server/introduction"},{"title":"Choosing a Speckle Deployment","sidebarTitle":"Choosing a Deployment","href":"/developers/server/self-hosted-vs-cloud-hosted-speckle"},{"title":"Docker Compose Quickstart","sidebarTitle":"Getting Started","href":"/developers/server/getting-started"},{"title":"Server Architecture","href":"/developers/server/architecture"},{"title":"Self-Hosted Deployment Options","href":"/developers/server/deployment-options"}]},{"group":"Deployment","pages":[{"title":"Deploy to Kubernetes","href":"/developers/server/deployment/kubernetes-with-helm"},{"title":"Server Maintenance","href":"/developers/server/deployment/backup-upgrade-restore"},{"title":"Deploying a Speckle Enterprise licensed server","sidebarTitle":"Enterprise Servers","tag":"Enterprise","href":"/developers/server/deployment/enterprise-license"},{"title":"Deploying a Speckle Enterprise licensed Automate server","sidebarTitle":"Enterprise Automate","tag":"Enterprise","href":"/developers/server/deployment/enterprise-license-automate"},{"title":"Deploying a Speckle Enterprise licensed Intelligence server","sidebarTitle":"Enterprise Intelligence","tag":"Enterprise","href":"/developers/server/deployment/enterprise-license-intelligence"},{"title":"Deploying a Speckle Enterprise licensed Desktop UI server","sidebarTitle":"Enterprise licensed Desktop UI","tag":"Enterprise","href":"/developers/server/deployment/enterprise-license-desktop-ui"}]},{"group":"Local Development","pages":[{"title":"Environment Setup","href":"/developers/server/development/setup"}]}]},{"tab":"Automate","groups":[{"group":"Speckle Automate","pages":[{"title":"Powering Your Automation Workflows","sidebarTitle":"Overview","tag":"Enterprise","href":"/developers/automate/introduction"},{"title":"Quickstart Guide","href":"/developers/automate/quickstart"},{"title":"API Reference","href":"/developers/automate/api-reference"},{"title":"Frequently Asked Questions","href":"/developers/automate/faq"}]},{"group":"Automate Functions","pages":[{"title":"Create an Automate function","sidebarTitle":"Creating Functions","href":"/developers/automate/create-function"},{"title":"Making Your Function","href":"/developers/automate/making-your-function"},{"title":"Function Inputs","href":"/developers/automate/function-inputs"},{"title":"Releasing a New Version","href":"/developers/automate/release-function-version"},{"title":"Publishing Automate Functions without the GitHub App","sidebarTitle":"Publish without GitHub","href":"/developers/automate/publishing-without-github"}]},{"group":"Working with Data","pages":[{"title":"Handling Data in Functions","href":"/developers/automate/function-data"},{"title":"AutomationContext","href":"/developers/automate/function-context"},{"title":"Annotating Function Results","href":"/developers/automate/function-results"},{"title":"Reporting Success","href":"/developers/automate/function-success"},{"title":"Function Artefacts","href":"/developers/automate/function-artefacts"}]},{"group":"Creating Automations","pages":[{"title":"Creating Automations","href":"/developers/automate/create-automation"},{"title":"Viewing Automation Results","href":"/developers/automate/viewing-results"},{"title":"Update an Automation","href":"/developers/automate/update-automation"}]},{"group":"Testing \u0026 Development","pages":[{"title":"Testing Your Functions","href":"/developers/automate/function-testing"},{"title":"Troubleshooting Automations","href":"/developers/automate/troubleshooting"}]},{"group":"Reference","pages":[{"title":"Considerations \u0026 Limitations","href":"/developers/automate/important-considerations"},{"title":"Function Specification","href":"/developers/automate/function-specification"}]}]}],"global":{"anchors":[]}},{"dropdown":"IT Administrators","icon":"wrench","groups":[{"group":"Deployment \u0026 Maintenance","pages":[{"title":"IT setup guide","href":"/it-admin/setup"},{"title":"Keep connectors current across your estate","sidebarTitle":"Connector updates","href":"/it-admin/connector-updates"},{"title":"Compatibility mode for ACC sync and uploads","sidebarTitle":"Compatibility mode","href":"/it-admin/compatibility-mode"},{"title":"Security","href":"/it-admin/security"},{"group":"Cloud Integrations","pages":[{"title":"Cloud Integrations: Access and Governance","sidebarTitle":"Introduction","href":"/it-admin/integrations/introduction"},{"title":"Enable Autodesk Forma Data Management integration","sidebarTitle":"Forma Data Management (ACC)","tag":"Enterprise","href":"/it-admin/integrations/acc"},{"title":"Configure Bentley ProjectWise Integration","sidebarTitle":"Bentley ProjectWise","tag":"Enterprise","href":"/it-admin/integrations/projectwise"},{"title":"Approve Speckle for SharePoint","sidebarTitle":"SharePoint","href":"/it-admin/integrations/sharepoint"},{"title":"Enable Databricks Integration","sidebarTitle":"Databricks","href":"/it-admin/integrations/databricks"},{"title":"Enable Snowflake Integration","sidebarTitle":"Snowflake","href":"/it-admin/integrations/snowflake"}]},{"title":"Admin Support Mode","href":"/it-admin/support-mode"},{"title":"Archive and unarchive projects","sidebarTitle":"Project Archival","tag":"Enterprise","href":"/it-admin/archived-projects"},{"title":"What's new in 2026.9 for IT admins","sidebarTitle":"What's new","href":"/whats-new/it-admins"}]},{"group":"Manual Connector Installation","pages":[{"title":"Manual installation","sidebarTitle":"Overview","href":"/connectors/manual-installation/introduction"},{"title":"Desktop Services","sidebarTitle":"Desktop Services (deprecated)","href":"/connectors/manual-installation/desktop-services"},{"title":"Archicad","href":"/connectors/manual-installation/archicad"},{"title":"AutoCAD","href":"/connectors/manual-installation/autocad"},{"title":"Blender","href":"/connectors/manual-installation/blender"},{"title":"Civil 3D","href":"/connectors/manual-installation/civil3d"},{"title":"ETABS","href":"/connectors/manual-installation/etabs"},{"title":"Navisworks","href":"/connectors/manual-installation/navisworks"},{"title":"Power BI","href":"/connectors/manual-installation/powerbi"},{"title":"Revit","href":"/connectors/manual-installation/revit"},{"title":"Rhino \u0026 Grasshopper","href":"/connectors/manual-installation/rhino-grasshopper"},{"title":"SketchUp","href":"/connectors/manual-installation/sketchup"},{"title":"Tekla Structures","href":"/connectors/manual-installation/teklastructures"}]}],"global":{"anchors":[]}},{"dropdown":"Get Involved","icon":"users","groups":[{"group":"Ways to get involved","pages":[{"title":"User testing and feedback","sidebarTitle":"User Testing","href":"/get-involved/user-testing"},{"title":"Join the Speckle Community","sidebarTitle":"Community","href":"/get-involved/community"},{"title":"Open source at Speckle","sidebarTitle":"Open source","href":"/get-involved/open-source"}]}],"global":{"anchors":[]}},{"dropdown":"Changelog","icon":"history","pages":[{"title":"Changelog — October 2026","sidebarTitle":"October 2026","href":"/technical-changelog/2026-10"},{"title":"Changelog — September 2026","sidebarTitle":"September 2026","href":"/technical-changelog/2026-09"}],"global":{"anchors":[]}}]},"title":"Componentised Grasshopper workflow - Speckle Docs","buildId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","deploymentId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","dynamics":["07c022d89b","a74be98ba7"],"chunks":["Frame-CIbhtp2j.js","DynamicMarkdown-CtpgKJwj.js","zoom-image-lightbox-CVZVK4hN.js","lightbox-handle-r17bVUz3.js"]}