Familiar power. Modern core. No legacy baggage.
A fast, programmable molecular viewer for research, scripting, and the web.
Patinae is a modern molecular visualization toolkit for interactive research, scripting, structural analysis, publication images, notebooks, and embedding.
It is built around a responsive GPU-first viewer, a command-driven workflow, and extension points for native, Python, and web applications. The aim is to keep the power of a full molecular workstation while making the everyday experience fast, light, and comfortable.
Patinae was called PyMOL-RS through the 0.3.x releases. The project started as a GPU-first remake experiment: keep the familiar molecular command workflow, but rebuild the viewer as a modern, independent application.
By 0.4.0, the project had outgrown the remake label. The renderer, command runtime, plugin host, desktop UI, Python surface, packaging, and web viewer were redesigned into an independent application and toolkit. The rename to Patinae marks that shift.
Patinae is not an official PyMOL project or a wrapper around PyMOL source code. It remains compatible with familiar command and session workflows where that is useful for users, but the implementation is its own codebase and rendering stack.
| Area | Design |
|---|---|
| Rendering | WebGPU via wgpu, GPU impostors, compute-heavy pipelines, native and web targets |
| Workflow | Interactive command line, object panel, sequence viewer, picking, measurements, sessions |
| Extensibility | Rust plugin SDK, Python plugin, Python package, reusable crates |
| Architecture | Independent patinae-* crates with explicit renderer, scene, command, IO, session, and plugin boundaries |
| Portability | Native desktop app, Python/Jupyter package, and WebAssembly/WebGPU viewer |
Download the latest release for your platform from Releases.
Standalone executable:
patinae protein.pdbPython package:
pip install patinaePrerequisites:
- Rust for the core workspace and desktop app.
- uv for Python package builds.
- Node.js for the web viewer and notebook widget assets.
git clone https://github.com/zmactep/pymol-rs
cd pymol-rs
make patinae
./target/release/patinae| Target | Command | Requires |
|---|---|---|
| Patinae release build | make patinae |
cargo |
| Patinae dev run | make patinae-dev |
cargo |
| Reference plugins | make plugins |
cargo |
| Python wheel | make python-release |
cargo, uv |
| Web viewer | make web-build |
cargo, npm |
| Rust check | make check |
cargo |
| Tests | make test |
cargo |
Run the baseline checks locally before opening a pull request:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo check --workspace
cargo test --workspace
cargo check --manifest-path python/Cargo.toml
rustup target add wasm32-unknown-unknown
cargo check --manifest-path web/Cargo.toml --target wasm32-unknown-unknownAdditional compliance tools are useful when installed locally:
cargo audit or cargo deny for dependency policy, cargo hack for feature
matrices, cargo udeps for unused dependencies, and Miri for targeted
unsafe-code tests.
Formats: PDB, mmCIF, bCIF, MOL2, SDF/MOL, XYZ, GRO, CCP4/MRC, trajectory formats such as XTC/TRR, and gzip-compressed inputs.
Representations: Spheres, sticks, lines, cartoon, ribbon, surface (SAS/SES/VdW), mesh, dots, labels, isomesh, isosurface, and isodot.
Selections: atom, residue, chain, object, proximity, polymer, solvent, and stored-selection expressions with a familiar molecular selection syntax.
chain A and name CA
byres around 5 ligand
polymer and not solvent
Commands: interactive verbs with completion and scriptability, including
load, fetch, show, hide, color, select, zoom, center, orient,
png, ray, align, cealign, symexp, isomesh, isosurface, and
isodot.
Structural analysis:
- Kabsch superposition and CE structural alignment.
- Distance, angle, and dihedral measurements with visual feedback.
- Crystallographic symmetry expansion with all 230 space groups.
- Secondary-structure assignment from geometry.
- Electron density map loading and contouring.
Sessions: save and load Patinae .prs sessions and import legacy .pse
sessions for interoperability.
Ray tracing: the raytracer plugin provides offline GPU ray tracing with
BVH acceleration, shadows, transparency, and edge detection.
The native Patinae app is a desktop interface around the same renderer, scene model, command runtime, and plugin host used by the rest of the workspace. It includes a command line, object panel, sequence viewer, plugin panels, mouse picking, native file workflows, and a GPU viewport.
The patinae Python package exposes a familiar command object for scripting,
automation, and notebook workflows.
from patinae import cmd
cmd.load("protein.pdb")
cmd.show("cartoon")
cmd.color("green", "chain A")
cmd.select("site", "byres around 5 ligand")
site_atoms = cmd.count_atoms("site")
cmd.do("set ambient, 0.8")The package also includes an anywidget-based Jupyter viewer:
from patinae.widget import Viewer
view = Viewer()
view.show()
cmd = view.get_cmd()
cmd.fetch("1CRN")
cmd.show("cartoon")
cmd.color("green", "chain A")Patinae runs in the browser through WebAssembly and WebGPU. The web viewer is
published as @patinae/viewer and can be embedded into applications or static
pages.
<div id="viewer" style="width: 800px; height: 600px"></div>
<script type="module">
import { PatinaeViewer } from "@patinae/viewer";
const viewer = new PatinaeViewer(document.getElementById("viewer"));
await viewer.init();
await viewer.loadUrl("https://models.rcsb.org/1IGT.bcif.gz", {
name: "1IGT",
format: "bcif",
});
viewer.execute("show cartoon");
viewer.execute("color green, chain A");
</script>The package can also register a custom element:
<script type="module">
import { registerElement } from "@patinae/viewer";
registerElement();
</script>
<patinae-viewer
src="https://models.rcsb.org/1IGT.bcif.gz"
command="show cartoon; color green, chain A">
</patinae-viewer>patinae/
├── patinae Native desktop application
├── crates/patinae-mol Molecular data model: atoms, bonds, molecules, coordinate sets
├── crates/patinae-io Structure, map, session, fetch, and trajectory IO
├── crates/patinae-select Selection parser and evaluator
├── crates/patinae-color Named colors, palettes, schemes, and ramps
├── crates/patinae-settings Configuration and settings system
├── crates/patinae-algos Alignment, symmetry, sequence, and analysis algorithms
├── crates/patinae-render WebGPU renderer
├── crates/patinae-scene Viewer state, scene graph, camera, input, and render bridge
├── crates/patinae-session `.prs` and `.pse` session support
├── crates/patinae-cmd Command parser, executor, and command registry
├── crates/patinae-framework Shared app messaging and component infrastructure
├── crates/patinae-plugin Plugin SDK
├── crates/patinae-plugin-host Runtime plugin host for front ends
├── plugins Reference Rust plugins
├── python Python package and Jupyter widget
└── web WebAssembly/WebGPU viewer package
Each crate is independently usable. Need only the selection parser? Use
patinae-select. Need molecular file parsing in a Rust pipeline? Use
patinae-io and patinae-mol. Need a viewer? Compose the scene, renderer,
command runtime, and front end that fit your application.
Patinae supports native Rust plugins loaded at startup from
~/.patinae/plugins/ or bundled beside the application. Plugins can register
commands, provide panels, hook into the command pipeline, and interact with the
viewer through the Patinae plugin APIs.
Plugins are compiled as dynamic libraries (.dylib on macOS, .so on Linux,
.dll on Windows). The workspace includes reference plugins:
| Plugin | Crate | Description |
|---|---|---|
| hello | hello-plugin |
Minimal plugin lifecycle and command-registration example |
| raytracer | raytracer-plugin |
GPU ray tracing with BVH acceleration, shadows, transparency, and edge detection |
| ipc | ipc-plugin |
Inter-process communication plugin for external tool integration |
| python | python-plugin |
Embedded CPython interpreter for scripting inside the native app |
Build and stage the reference plugins:
make pluginsInstall them into the user plugin directory:
make plugins-installThe python-plugin embeds CPython directly into the native application. It is
separate from the standalone Python package: scripts run inside the desktop app
and issue commands through the same dispatcher as native commands.