Components / Molecular & cellular

Molecule viewer

Open a protein or nucleic acid structure from the Protein Data Bank and explore it residue by residue. The viewer parses PDB and mmCIF text itself, so it needs nothing beyond three.js.

Installation

bunx shadcn@4.22.1 add https://organui.com/r/molecule-viewer.json

Or by name: bunx shadcn@4.22.1 add @organui/molecule-viewer.

The source installs into your components directory and adds three.js, plus shadcn's alert, button, select and tooltip for its controls. Its toolbar composes them with Base UI's render prop, so it needs one of shadcn's Base UI styles, such as base-nova; on a Radix style its buttons do nothing. It uses your theme tokens and installs no global styles.

View registry item JSON

Usage

"use client"
import { useState } from "react"
import { MoleculeViewer } from "@/components/molecule-viewer"

export function StructurePanel() {
  const [selectedId, select] = useState<string | null>(null)
  return (
    <MoleculeViewer
      src="https://files.rcsb.org/download/1CRN.cif"
      selectedId={selectedId}
      onSelectionChange={select}
    />
  )
}

Pass a URL as src, or the file's text as data. RCSB serves every entry with CORS, as https://files.rcsb.org/download/<ID>.cif or .pdb. The crambin sample above is served at https://organui.com/models/crambin.pdb if you want a small structure to start from.

Only the first model and the first alternate location of each atom are read. Secondary structure comes from the file's HELIX and SHEET records, or _struct_conf and _struct_sheet_range in mmCIF; a file without them is drawn as coil. Bonds, including disulfides, are inferred from covalent radii; metal ions are left unbonded.

Behaviour

Selection is controlled and works on residues: pass selectedId, such as A:16 (chain, author number and insertion code), and update it from onSelectionChange, which also passes the residue record. The selected residue keeps its colour while everything else fades; in the cartoon style its atoms are drawn as ball and stick on the ribbon. The sequence strip below the stage selects the same way and is one tab stop, moved with the arrow keys, Home and End.

The style and colour menus are uncontrolled by default. Set representation (cartoon, ball-and-stick, spacefill) or colorScheme (secondary, chain, element, residue, rainbow) with their change callbacks to control them. Ligands are always drawn as atoms; water is hidden unless you pass water.

Drag or the arrow keys rotate; scroll, pinch, plus and minus zoom. The ref exposes zoom, rotate and reset. When the file names its PDB ID, the viewer links the entry on RCSB PDB; pass attribution={false} to hide it.

Use the parser on its own

import { parseStructure } from "@/components/molecule-viewer"

const structure = parseStructure(text) // PDB or mmCIF, detected
structure.residues[0] // { id: "A:1", name: "THR", kind: "protein", secondary: "sheet", ... }
structure.bonds       // atom index pairs inferred from covalent radii

WebGL is required. When it cannot start, or the file cannot be read, the viewer shows a message with a retry button. Very large assemblies (hundreds of thousands of atoms) work but are slow to build; trim them to the chains you need first.