This started as the thing I needed while staring at holin oligomer predictions: a way to flip through forty models, see which regions were confident, put two of them on top of each other, and get a figure out — without launching PyMOL, and without uploading unpublished coordinates to anyone's server.
The mistake the tool is built to make harder
pLDDT is the number everybody quotes, and it is per-residue and local. A model can average 96 and still have two domains in completely the wrong arrangement relative to each other, because pLDDT never had an opinion about their relative placement. For complexes this matters enormously: a high mean pLDDT across a predicted dimer tells you the two chains are each individually well-folded. It tells you approximately nothing about whether they actually touch the way the picture shows.
So the viewer puts predicted aligned error and interface confidence one tab away from the structure, not one folder away. Drop an AlphaFold result ZIP and it pulls the confidence JSON out of the archive itself: the PAE heatmap with chain boundaries drawn on it, per-token inspection on hover, chain-pair ipTM, chain-pair minimum PAE, pTM, ranking score, rank, clash flag. All of it exports to CSV with the file each number came from recorded next to it, because "where did this ipTM come from" is a question you will be asked six months later.
The interpretation guidance is in the tool, not just in the README. Press ? and the help panel says, in as many words, that high pLDDT is not evidence an interface is real. A tool that renders a beautiful predicted complex and stays silent about that is doing half a job.
Comparison that shows its work
Overlaying two predictions and quoting an RMSD is the most common way to make a comparison look more rigorous than it is. The number depends entirely on which atoms you paired, and that decision is usually invisible.
There are two pairing modes here and the tool always tells you which ran. Chain and residue IDs pairs Cα atoms with identical identifiers — strict, no heuristics, right when your models genuinely share a numbering scheme. Sequence-aware runs a global Needleman–Wunsch alignment between every reference chain and every target chain, then greedily assigns chain pairs by identity — which is what you need when two prediction runs disagree about chain order or numbering.
Either way the results table reports the aligned Cα count, the sequence identity, the chain mapping it chose, and the RMSD, and exports all of it as CSV. If the chain mapping looks wrong, the RMSD is wrong, and you can see that before you put it in a figure. For a homo-oligomer with near-identical chains the mapping is essentially arbitrary among equivalent chains, which is exactly the case where a bare RMSD misleads.
The report is the figure
Share report produces one HTML file with the coordinates embedded. Open it and you get the viewer, not a screenshot: pick models, step through them, cycle, follow the guided views and captions the author saved, read the pLDDT and PAE, export your own PNG. No server, no install, nothing to configure.
This is what I send to a collaborator instead of eleven PNGs and a paragraph explaining what they are looking at. It is also what a reviewer can be given so they can check the claim themselves rather than take the figure's word for it.
Alongside it there is a scene manifest: a JSON file recording a SHA-256 hash of every structure file, plus the camera, colours, labels, selections, measurements, saved views, alignment settings, and your provenance notes. Reload it a year later with the same coordinate files and you get the same figure; reload it with files that have changed and it says so, because it recomputes the hashes.
Three bugs worth naming
The recent pass over this was mostly unglamorous correctness work. Three are worth writing down because they are the kind that look fine in casual use and bite in real ones.
Exporting a figure could kill the viewport
Rendering a publication PNG happens off-screen, at full resolution, in a second WebGL context. Browsers cap
how many live WebGL contexts a page may hold — commonly eight to sixteen — and when you exceed it they
silently discard the oldest. Every export was creating a fresh context and never releasing it, so a
six-panel contact sheet would quietly destroy the main viewer's context somewhere around panel six. The fix
is one reusable off-screen target, explicitly released with WEBGL_lose_context when the job
finishes.
Dropping a file half an inch off target lost the session
The drop handler was attached to the upload card. Drop a PDB anywhere else on the page and the browser did its default thing: navigated to the file and threw away everything you had loaded, annotated, and aligned. Drops are now accepted across the whole window, and the default is suppressed everywhere regardless.
Fetching by accession was asking for a file that no longer exists
Database fetch built AlphaFold DB URLs by appending _v4 to the entry name. AlphaFold DB is on
v6. Every accession lookup would have 404'd. It now asks the EBI API for the current URLs, which also means
it can pull the entry's predicted-aligned-error file in along with the coordinates.
What it loads
| Input | What happens | Needs network? |
|---|---|---|
| .pdb / .cif / .mmcif | Loaded as a model, read locally | no |
| AlphaFold result .zip | Every model extracted and grouped by archive; template hits ignored | no |
| Confidence JSON / ranking CSV | pTM, ipTM, ranking score, rank, clash, PAE attached to matching models | no |
| Scene manifest JSON | Whole annotated scene restored, with hash verification | no |
1ubq | Fetched from RCSB | yes |
P69905 / AF-P0DTC2-F1 | Fetched from AlphaFold DB, with its PAE data | yes |
Privacy, stated precisely
Files you open are read by the browser and never leave the machine. The page makes network requests in exactly two situations, and it is worth being exact rather than waving at "privacy-first":
- On load, for the three pinned libraries (3Dmol.js, JSZip, numeric.js) from one CDN. All three carry Subresource Integrity hashes, so a tampered or substituted file refuses to execute.
- When you type an identifier and press Fetch, to RCSB or EMBL-EBI. That request carries only the identifier you typed.
A Content-Security-Policy restricts the page to those origins and nothing else. The icon set and tooltips used to be two more CDN downloads; they are inline now, which removed about 600 KB and two third-party origins, and means the interface renders correctly even when the network does not cooperate.
What it is not
It is not PyMOL or ChimeraX, and it is not trying to be. There is no molecular dynamics, no density fitting, no ray tracer, no scripting language. It does not compute buried surface area or contact maps yet — that is the next thing I want, for exactly the holin-interface question that started this.
And it does not turn a prediction into a result. Aligning two models and getting a small RMSD means two predictions agree with each other, which is a much weaker statement than either being correct. The tool is built to keep that distinction visible; it cannot make it for you.
Open it with one of your own models
No install, no account, no upload. Drop a PDB, or type 1ubq and press Fetch.