PyVista excludes two VTK versions by number and pins its validation API exactly
3D visualization and mesh analysis for science and engineering
At a glance
- What is it?
- pyvista/pyvista is an MIT licensed, NumFOCUS affiliated 3D visualization and mesh analysis library for Python, at v0.49.0 with the last commit on 2026-10-02. Its dependency block excludes VTK 9.4.0 and 9.4.1 by number, pins the validation API to an exact version with a comment saying it is unstable, and ships a command line tool inside a library that was once Python only.
- Who is it for?
- PyVista fits a scientific Python codebase that has meshes or volumetric grids and wants one plotting path for notebooks, batch scripts and CI, because the same dataset objects and filter chain work in all three. Three things to check before you depend on it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two VTK releases are excluded by number
The dependency list is short and unusually specific about the toolkit underneath it.
The VTK requirement is four constraints at once: a lower bound of 9.3.1, an upper bound below 9.8.0, and two explicit exclusions, `vtk!=9.4.0` and `vtk!=9.4.1`.
Excluding a specific patch release by number is unusual, and the document gives no reason. It may be a regression in the toolkit, an ABI mismatch with a wheel, or an incompatibility with the visual regression baselines, but none of that is written down. What it means practically is that a resolver which finds 9.4.0 available has to be told to keep looking, and a user with 9.4.0 already installed gets no error message explaining why it is wrong.
The upper bound matters just as much. Anything the project picks up in the extras inherits it: the separate VTK-linked visualization package in the optional groups is capped below the same 9.8.0 ceiling, so a user who installs that extra cannot move VTK past the boundary either.
The rest of the core list is conventional. NumPy with a floor of 1.22, matplotlib from 3.0.1, pillow, pooch for data downloads, scooby for environment reports, typing extensions, and cyclopts from 4.0.0, which is the command line framework behind the CLI described later. There is also a macOS-only dependency, a Cocoa framework bridge, marked with the platform check and a comment citing three pull request numbers as the reason.
The validation API is held at an exact pin with a reason in a comment
One dependency in that list behaves differently from all the others.
Every other requirement uses a range. The validation library is pinned to an exact version, `pyvista-validation==0.5.4`, and the reason is written in the file next to the pin: the validation API is still unstable.
That comment is the whole explanation, and it is a useful one. An exact pin in a library's core dependencies means every consumer resolves to the same version, so a patch release cannot change behaviour under you, and it also means the library will not pick up an improvement automatically.
The cost sits in the other direction too. Because the pin is in the core list rather than an extra, everyone installing the library gets this exact version whether or not they use the mesh validation feature at all.
That feature is the one the CLI exposes. The three documented commands are plotting a mesh file, converting one format to another, and validating a mesh's data, points and cells:
pyvista plot bunny.stl
pyvista convert bunny.stl .vtp
pyvista validate bunny.stlSo the exact pin is on the code path behind `pyvista validate`, which is why the comment matters more than it first appears.
io-override replaces the STL and miniply readers
The optional dependency groups are where PyVista's extension model becomes concrete.
There are six groups. The `all` group simply pulls in four others. `colormaps` adds three colour map collections. `jupyter` adds the widget layer, an async helper and the trame-based web view. `io` adds the readers and writers: a filesystem abstraction, an image library, a general mesh library, a finite-element reader and a zstd package.
The one to look at twice is `io-override`. It contains two packages, one for miniply and one for STL, and the name says what installing them does: they replace the readers the library would otherwise use for those two formats.
That is the same philosophy as the registered accessor extension API described in the document, where third-party code attaches domain-specific filters and plotter components with no subclassing, no monkey-patching and no vendoring of upstream algorithms. A package that wants to own a format implements the reader and takes over; it does not fork the library.
The other group worth naming is `cvista`, a separately maintained visualization package pinned with both a floor and the same sub-9.8.0 ceiling as VTK, which is the clearest sign that the toolkit version is a coordinated decision rather than a per-package one.
Image regression on every commit is the stated reason to use it
The document's argument for existing as a layer above the toolkit is spelled out in one section, and it is about assurance rather than features.
Three claims are made. The library is image-regression tested on every commit, across all Python versions still in their lifecycle and across VTK releases. It holds its public API stable through a deliberate deprecation lifecycle. And it locks rendering behaviour under visual regression baselines.
Then comes the comparison, which is unusually blunt: the C++ toolkit underneath provides few of these assurances and does not share the project's enthusiasm for testing and reliability, which is the stated reason downstream teams build on the library instead.
None of the three claims comes with a number in this document. There is no count of baselines, no list of the Python versions covered, no statement of what a failing image diff does to a merge. What the claim does establish is the mechanism, and the mechanism is checkable: a rendering change that alters output has to update a baseline, so visual behaviour is a reviewed artefact rather than an accident.
The positioning paragraph makes the same argument for the API shape, comparing the library's role for 3D data to the one pandas plays for tabular data and xarray for labelled n-dimensional arrays.
Coverage measures the test suite as well as the library
The build file is the place where the project's engineering habits are visible.
The coverage flags cover two directories: the library and the tests. Measuring the test suite's own executed lines is not a common choice, and the comment above the line explains it as matching the coverage environments defined elsewhere.
The list of directories style checks run against names five paths, one of which is `examples_trame`. There is no directory of that name at the repository root; the examples live in a single `examples/` directory. So one default variable points at a path that is not in the tree.
Everything else in the file is deliberate. The default goal is the test target, with an `all` alias added because `all` is a POSIX convention. A clean target removes build output, the tox directory, the pytest cache and the coverage artefacts. Dependency syncing goes through `uv sync` with a dev group. Linting runs pre-commit across all files, type checking goes through a tox environment running mypy, and prose style is checked by Vale through a script in the documentation directory.
Documentation coverage is its own target, which builds the docs with Sphinx in coverage mode and then prints the resulting text file.
Paid work is routed through sponsorship and a commercial steward
The governance paragraph is short and unusual for a scientific Python library.
It states that the project is open source, community owned and MIT licensed, and that it is affiliated with NumFOCUS. Then it names a commercial steward: a public benefit corporation founded by the maintainers acts as the project's commercial steward.
The support section routes everything through that arrangement. General inquiries go to an address at the project's own domain, and the document offers to connect people with community experts.
For actual paid work, the route is sponsorship rather than a rate card: consulting, custom development, feature design, integration support and training are all offered by sponsoring the project's core developers on GitHub, with the reasoning given as direct access to the people who do the work plus sustaining the maintenance. A discussion post is linked as the place with more detail.
The contributing section then says the project is mostly maintained on a volunteer basis and asks for bug reports, documentation fixes, new examples and filter ideas.
Those two paragraphs together are the real governance picture: MIT code, volunteer maintenance, and a company that sells the maintainers' time.
Python 3.10 through 3.14, two installers, and a browser option
The install story is deliberately short.
The floor is Python 3.10, and the classifiers list 3.10, 3.11, 3.12, 3.13 and 3.14, so five interpreter versions are declared supported.
Installation is one of two commands:
pip install pyvistaor the same package from conda-forge, named in the document as the alternative for anyone managing environments that way.
There is also a browser option. The document points at a hosted notebook environment where the examples repository can be opened without installing anything locally, which is the fastest way to find out whether the plotting stack suits a workflow before committing to a dependency of this size.
The build side of the packaging is unremarkable in a good way: setuptools as the backend with a fairly recent minimum, and the version marked as dynamic rather than written into the manifest, so it is read from the package at build time.
The project also asks to be cited, and gives a journal paper with authors, volume, issue, article number and a DOI, plus a BibTeX block so the citation can be copied in the right form.
Editorial conclusion
PyVista fits a scientific Python codebase that has meshes or volumetric grids and wants one plotting path for notebooks, batch scripts and CI, because the same dataset objects and filter chain work in all three. Three things to check before you depend on it. Plan around the VTK range, because the accepted versions exclude two specific releases by number with no explanation given, and the upper bound sits below 9.8 while the library also depends on VTK transitively through the VTK-linked visualization package in its extras. Expect a fast-moving dependency floor, since five Python versions are supported and the validation API is held at an exact pin because it is unstable. And read the extension contract early if you plan to build on it, since third-party code attaches through registered accessors rather than subclasses, which is a different shape from most library extension models. MIT licensed, a commercial steward for paid work, and image regression testing on every commit as the stated reason to prefer it over the underlying toolkit.
Frequently asked questions
how to install pyvista
With pip install pyvista, or conda install -c conda-forge pyvista. PyVista runs on Python 3.10 and newer, and the classifiers list 3.10 through 3.14. Optional dependency groups cover colour maps, input and output, reader overrides and Jupyter support, and the examples can also be opened in a browser notebook environment without installing anything.
Is PyVista free for commercial use?
Yes. The licence field is MIT, and the document describes the project as open source, community owned and MIT licensed, and also NumFOCUS affiliated. Paid work such as consulting, custom development and training is offered separately through sponsorship of the maintainers, which is a support arrangement rather than a licence condition.
What does pyvista do?
It provides a NumPy-native API for 3D visualization and mesh analysis, dataset structures and filters for points, surfaces and volumes, and one plotting framework that runs interactively in Jupyter notebooks, headlessly in CI and as embedded views inside larger web and desktop applications.
Can pyvista be used without writing Python?
For three tasks, yes. The package installs a pyvista CLI for quick plotting, format conversion and mesh validation, with the documented examples running pyvista plot, pyvista convert and pyvista validate against a mesh file. Anything beyond those three still needs the Python API.
How do third-party packages extend pyvista?
Through a small, lazily evaluated extension API using registered accessors, which attach domain-specific filters and plotter components without subclassing, monkey-patching or vendoring upstream algorithms. The same idea appears in the optional dependency groups, where io-override installs replacement readers for miniply and STL.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pyvista-pyvista)