Over the years, I’ve often struggled with connecting VSCode to Rhino/GH’s Python setup.
There are many posts here in this community, since I’m still a beginner myself, so I wrote this mainly as documentation for my own learning from the community.
But I’m sharing it here in case it helps anyone who’s going through the same confusion.
This is a very elementary introduction of how to use VSCode to write code and run it in Grasshopper.
If you spot any mistakes or have better ideas, please feel free to share — I’m learning too, and it would be great to grow together with the community.
- [!] Forget about plugins for now. They are great, but let’s use native functions — I believe this helps us set up the right mindset.
Why use VSCODE
Copilot, autocomplete, and smarter IntelliSense.
CPython
Environments in Rhino/Grasshopper
Rhino/Grasshopper has its own interpreter — that’s what we’ve been using inside Rhino and Grasshopper for script editing.
They locates in McNeel\Rhinoceros\8.0\scripts
I guess Rhino handles C# and Python differently behind the scenes — C# scripts are compiled, while Python uses an interpreter. But for this post, let’s focus only on Python
In this thread (as @Mahdiyar shows):
Rhino 8 How to use input code in Grasshopper script component - Scripting - McNeel Forum
There are 3 modes in the GH scripting component.
The third one shows how you can link an external script file and run it in Grasshopper.
shift + right click on the component and there is an option to turn on Script Input Parameter
If you want the component to auto-switch language, add a Shebang at the top of your file.
Rhino reads this to decide how to parse the script.
//#! csharp
#! python
Stubs
What are stubs?
They are like a table of contents for a library.
They usually refer to:
.pyi files
(Python Interface files / Type stubs)
They are not real code.
They are descriptions of code.
What do .pyi stub files contain?
- function names
- classes
- parameters
- docstrings
- type hints
But no implementation.
McNeel Python Stubs
Rhino automatically creates the latest stub files when we open the Script Editor.
You can find them here (instead of cloning from GitHub):
C:\Users\[you]\.rhinocode\py39-rh8\site-stubs
in some case, you would see many folders just pick the latest one, here is mine
C:\Users\[you]\.rhinocode\py39-rh8\site-stubs\rhino3d-8.25.25328.11001
Inside you’ll find python stubs for .NET assemblies
- RhinoCommon ([https://pypi.org/project/Rhino-stubs/](https://pypi.org/project/Rhino-stubs/))
- Eto ([https://pypi.org/project/Eto-stubs/](https://pypi.org/project/Eto-stubs/))
- Grasshopper ([https://pypi.org/project/Grasshopper-stubs/](https://pypi.org/project/Grasshopper-stubs/))
- GH_IO ([https://pypi.org/project/GH-IO-stubs/](https://pypi.org/project/GH-IO-stubs/))
- GH_Util ([https://pypi.org/project/GH-Util-stubs/](https://pypi.org/project/GH-Util-stubs/))
Missing rhinoscriptsyntax stub
You’ll notice rhinoscriptsyntax is not included — because:
It is:
- It’s a high-level helper library
- Originally created for IronPython
- Implemented as plain Python (
.py) - Not part of RhinoCommon.dll
- Therefore Rhino cannot auto-generate
.pyistubs for it
So if we want to use it in VSCode, we must add it separately via extraPaths.
Virtual Env
Create any virtual environment. This is good practice when using VSCode purely as a code editor, especially because:
- Our goal is to write code in VSCode
- But execute the code inside Rhino/GH
Even if your virtual env has numpy / pandas / TensorFlow installed,
they will not appear in Rhino unless explicitly declared like the template showed in the script-editor:
# requirements: package1, package2
# env: /path/to/site-packages/
Keeping the development environment separate is great.
In one project you may have many scripts — some are external processing scripts,
only a few need Rhino to represent geometry.
Write standalone scripts for data processing, algorithms, and model training (run within Conda)
For example:
Clustering / PCA / Optimization
CAD pre-processing
Generating JSON / CSV / Mesh / npy data
All these can run in your isolated environment without affecting Rhino.
Then load this data into Rhino
Rhino’s internal scripts only handle:
Reading data
Generating geometry
Rendering / manufacturing / interaction
No additional heavy dependencies.
This keeps Rhino lightweight, crash-resistant, and free from version conflicts
Meanwhile, your VSCode environment can be very “heavy” (numpy, torch, scikit-learn etc.).
Setup in VSCode
Install
- i use conda mini-forge to create an virtual env first:
conda create -n RhinoPy python=3.9
- after env creation, activate env and install rhino-stubs
conda activate RhinoPy
pip install Rhino-stubs
- [i] I think now we don’t have separately install Grasshopper-Stubs, it all comes together
- Install Python in VSCode
Setup
Create a .py file and open it in VSCode.
Press F1 → Select Interpreter, or use the interpreter selector in the bottom right.
Choose your env.

go to File-Preference-Settings-Extensions-Python, and open settings.json
add the following to the json, inside {}, change the to what you have on your computer
for windows, be aware change \ to \\
"python.analysis.stubPath": "C:\\Users\\[you]\\.rhinocode\\py39-rh8\\site-stubs\\rhino3d-8.25.25328.11001",
"python.analysis.extraPaths": ["C:\\Users\\[you]\\AppData\\Roaming\\McNeel\\Rhinoceros\\8.0\\Plug-ins\\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\\settings\\lib"
],
"python.defaultInterpreterPath": "C:\\Users\\[you]\\AppData\\Local\\miniforge3\\envs\\RhinoPy\\python.exe",
"python.analysis.stubPath" : for rhino site-stub file, i picked the latest
"python.analysis.extraPaths": for rhinoscriptsyntax
"python.defaultInterpreterPath": default interpreter path
now we can have auto-completion and prompts when we do coding:
add # type: ignore after import if u don’t like the missing-module warnings
-
[b] the current situation is:
-
Pylance can see Rhino’s stubs → autocompletion for things like Rhino.Geomertyis available -
However, it checks whether the “Rhino package exists in the current interpreter” → Conda environment lacks it → triggers a missing-module warning
**Your code is intended for Rhino,
but VSCode assumes you’ll run it via Conda, hence the warning that “this import will fail”.
Setup in Grasshopper
just link the external file and every time you save it would automatically update:







