Molecule Viewer
Loading molecule viewer…
This example uses @nitro-bio/molstar-easy 0.0.19. Install it via:
pnpm add @nitro-bio/molstar-easy@^0.0.19
The published 0.0.19 release targets React 18 and includes a React 18 JSX runtime. This React 19 docs app applies a compatibility patch that uses the host React runtime. React 19 integrations need this fix until the package publishes a compatible build.
Basic Usage
"use client";
import { useEffect, useState } from "react";
import { MoleculeViewer } from "@nitro-bio/molstar-easy";
export const Demo = () => {
const [pdbStrs, setPdbStrs] = useState<[string, string] | null>(null);
useEffect(function fetchPDB() {
const pdbUrls = [
"https://files.rcsb.org/download/1CRX.pdb",
"https://files.rcsb.org/download/1CRN.pdb",
];
Promise.all(
pdbUrls.map((url) => fetch(url).then((res) => res.text())),
).then((pdbStrs) => {
setPdbStrs([pdbStrs[0], pdbStrs[1]]);
});
}, []);
return (
<div>
{pdbStrs && (
<MoleculeViewer
moleculePayloads={pdbStrs.map((pdbStr) => ({
structureString: pdbStr,
format: "pdb", // or "mmcif"
}))}
defaultStructureHexColor="#7279df"
backgroundHexColor="#f4f4f4"
/>
)}
</div>
);
};
With Highlights
const highlights = [
{
label: { text: "Active Site", hexColor: "#881337", scale: 1 },
start: 14,
end: 30,
},
];
<MoleculeViewer
moleculePayloads={[
{
structureString: pdbString,
format: "pdb",
highlights: highlights,
},
]}
/>;
With Custom Styling
<MoleculeViewer
moleculePayloads={[
{
structureString: pdbString,
format: "pdb",
style: {
type: "surface", // "ribbon" | "ball-and-stick" | "spacefill" | "surface"
params: {}, // optional Molstar-specific params
},
},
]}
/>
With Transforms
import { ModelTransform } from "@nitro-bio/molstar-easy";
const transform: ModelTransform = {
position: { x: 10, y: 0, z: 0 },
rotation: { x: 0, y: 45, z: 0 }, // degrees
};
<MoleculeViewer
moleculePayloads={[
{
structureString: pdbString,
format: "pdb",
transform: transform,
},
]}
/>;
With Custom Per-Residue Colors
const indexToColor = new Map([
[1, "#ff0000"],
[2, "#00ff00"],
[3, "#0000ff"],
]);
<MoleculeViewer
moleculePayloads={[
{
structureString: pdbString,
format: "pdb",
indexToColor: indexToColor,
},
]}
defaultStructureHexColor="#94a3b8"
/>;
Advanced: Using the Hook Directly
For more control, you can use the useMolstarViewer hook directly:
"use client";
import { useEffect, useRef } from "react";
import {
useMolstarViewer,
type MoleculePayload,
} from "@nitro-bio/molstar-easy";
export const CustomViewer = ({ pdbString }: { pdbString: string }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const parentRef = useRef<HTMLDivElement>(null);
const { ready, api } = useMolstarViewer("my-viewer-id");
useEffect(() => {
if (canvasRef.current && parentRef.current) {
api.init(canvasRef.current, parentRef.current, {
background: "#f4f4f4",
defaultColor: "#94a3b8",
});
}
}, []);
useEffect(() => {
if (ready) {
const payloads: MoleculePayload[] = [
{
structureString: pdbString,
format: "pdb",
},
];
api.ensurePayloads(payloads);
}
}, [ready, pdbString]);
return (
<div ref={parentRef}>
<canvas ref={canvasRef} />
</div>
);
};
API Reference
MoleculeViewer Props
moleculePayloads:(MoleculePayload | null)[]- Array of molecule structures to displayclassName?:string- CSS class for the containerbackgroundHexColor?:string- Background color (default:#f4f4f4)defaultStructureHexColor?:string- Default structure color (default:#94a3b8)viewerId?:string- Unique ID for the viewer instance
MoleculePayload
structureString?:string- PDB or mmCIF structure dataformat?:"pdb" | "mmcif"- Format of the structure data (default:"pdb")highlights?:MoleculeHighlight[]- Residue highlightsindexToColor?:Map<number, string>- Custom per-residue colors (residue index → hex color)style?:{ type: MoleculeStyle, params?: Record<string, unknown> }- Rendering styletransform?:ModelTransform- Position and rotation transform
MoleculeHighlight
label:{ text: string, hexColor: string, scale?: number }- Label configurationstart:number- Start residue indexend:number- End residue indexhidden?:true- Hide this highlight
ModelTransform
position:{ x: number, y: number, z: number }- Translation in 3D spacerotation:{ x: number, y: number, z: number }- Rotation in degrees (Euler angles)