Library / SDK
3dmol/3Dmol.js avatar
3dmol/3Dmol.js

3Dmol.js puts a WebGL molecular viewer inside a single div

WebGL accelerated JavaScript molecular graphics library

1,030 stars230 forksJupyter NotebookNOASSERTION

At a glance

What is it?
3Dmol.js is a JavaScript and TypeScript library that renders molecular structures in the browser through WebGL, covering a wide set of file formats, styling options and surface work. The code is permissive, but the project asks users to acknowledge and cite it, and the tutorials lean heavily on one file format.
Who is it for?
3Dmol.js fits teams that need a structure viewer inside an existing web page, a notebook, or a small teaching tool, and who can accept a permissive BSD licence with an attribution and citation obligation. It is a poor fit when you need a desktop-grade molecular application, a fully documented pipeline for the less common formats, or a graphics stack that is not WebGL.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A div with data attributes becomes the viewer

The project documents three ways in: a hosted viewer, an embeddable viewer, and a library you call from your own application. The embeddable route is the one that catches people off guard, because the entire viewer is declared in markup. A div carrying the class `viewer_3Dmoljs`, plus data attributes for the structure, the style and the surface, becomes the render target once the library script is loaded. The README example pulls the minified build from the project site and pairs it with a 400 by 400 div showing pdb 4N8T as a cartoon coloured by spectrum over a translucent white surface. No JavaScript appears in that snippet, so the same markup pattern drops into a page with no build step at all. The div is not a placeholder for a canvas you fill later. It is the viewer.

Downloading a structure by PDB id and styling it in the callback

The scripted path starts by creating a viewer from a selector. Structures arrive asynchronously, which is why the styling calls live inside the download callback rather than next to the viewer construction. The `multimodel` and `frames` options are passed to the downloader, then the whole model is styled with a cartoon and a spectrum colour scheme before a single render call. The order matters: the model has to exist in the viewer before a style can apply to it, and the render call at the end is what pushes the accumulated scene to the GPU. Note that the option object is passed to `$3Dmol.download` and the styling is applied through `viewer.setStyle`, so a single viewer can hold several differently styled models at once if you download more than one.

addSurface needs a volume you supply and a gradient you pick

Surfaces are the least self contained feature in the library. `viewer.addSurface` does not compute the density for you at the call site: you hand it a surface type, a `VolumeData` object built from raw cube data, and a gradient scheme. The cube data and its numeric range are variables the caller must already have, and the README example shows the range being passed to the ROYGB gradient in descending order, so the higher end of the range lands at the end of the spectrum. The README also lists parallelized molecular surface computation as a library feature, so in some code paths the heavy lifting is done for you. When it is not, the API splits the work: the caller supplies the field, the library builds the mesh. That split is worth understanding before you budget time for a surface, because the cube file format is listed among the supported inputs.

addCylinder places geometry the structure never contained

The shape API exists for annotation, not for molecular data. A cylinder is defined by a start point, an end point, a radius, a colour and two cap flags, and the README shows two of them drawn in the same scene: a teal segment capped at one end and a shorter black one with no caps on either end. The library also advertises spheres and arrows among the geometric shapes. The coordinates live in the same space as the loaded structure, but the README does not document how the cylinder axis is aligned with respect to the camera or the structure, so the orientation of a hand placed annotation is something you confirm by looking at the result. The caps are independent of each other, which is what lets you draw a pointer that touches a surface at one end and nothing at the other.

The test pipeline calls Python before it calls Jest

The package manifest is the place to look for install and build reality, and it is more informative than the README here. The package is named `3dmol`, the entry point is `build/3Dmol.js`, and TypeScript types are published at `build/types/index.d.ts`. The engines field requires npm 8.11 or newer and Node 16.16.0 or newer. The build itself is webpack in two passes, a development one and a production one, and the `prepare` script runs both, so an install from a git checkout rebuilds the bundle before anything else happens. The two modes are separate scripts:

bash
npm run build:dev
npm run build:prod

The test command is not a plain unit test run. It generates test fixtures first, and those generators are Python scripts:

bash
npm run generate:tests
npm run generate:jest
npm run jest
npm run glcheck

So a contributor needs a working Python 3 interpreter alongside Node before the test suite means anything. The `glcheck` step is a separate render comparison stage with its own config at `tests/glcheck/glcheck.config.json`.

Twelve formats listed, one format demonstrated

The feature list names support for pdb, sdf, mol2, xyz, cif, cdjson, mmtf, prmtop, gro, pqr, cube and vasp, alongside sphere, stick, line, cross, cartoon and surface styles, atom property based selection and styling, labels, and clickable interactivity with molecular data. That is a wide surface area, and it is the strongest argument for the library. It is also where the documentation thins out. The structure-loading examples in the README work with a PDB identifier, either through a data attribute or through `$3Dmol.download`, and the tutorials linked from the README cover the hosted, embeddable and application component modes. Nothing in the examples shows a CIF or MMTF file being loaded and styled, so the format list is a claim about coverage rather than a demonstrated path. The repository does contain a `py3Dmol` directory alongside the `src` directory, which points to a Python facing side to the project, but the README does not describe how the two halves are meant to be used together.

Permissive BSD with an attribution and citation obligation

The README states that 3Dmol.js is licensed under a permissive BSD open source licence, and that you are free to use it in any project as long as the code is properly acknowledged and cited. The package manifest gives the identifier as `BSD-3-Clause`, while GitHub cannot classify the licence on the project page, which shows it as Other, a custom licence, with the LICENSE file as the authority. Those two statements are close but not identical, so the LICENSE file is the document to read before shipping anything. The citation requirement is separate from the licence terms and points at a Bioinformatics paper. Funding comes from the National Institute of General Medical Sciences under R35GM140753, with R01GM108340 as the earlier award. The last push to the default branch was on 2026-09-12, the most recent tagged release 2.5.5 came out on 2026-05-22, and 2.5.4 followed on 2026-01-22, so the cadence of recent work is roughly four to five months between releases.

Editorial conclusion

3Dmol.js fits teams that need a structure viewer inside an existing web page, a notebook, or a small teaching tool, and who can accept a permissive BSD licence with an attribution and citation obligation. It is a poor fit when you need a desktop-grade molecular application, a fully documented pipeline for the less common formats, or a graphics stack that is not WebGL. Before committing, check the LICENSE file directly, since GitHub shows the licence as a custom one while the package manifest declares BSD-3-Clause, and confirm that your formats and your target browsers behave the way the single PDB tutorial suggests.

Frequently asked questions

How do I put 3Dmol.js on a web page?

Add the library script to the page and give a div the class `viewer_3Dmoljs` with data attributes such as `data-pdb` and `data-style`. The README example loads the minified build from the 3Dmol.org build path and renders a 400 by 400 div this way, with no JavaScript required.

Which molecular file formats can 3Dmol.js read?

The feature list names pdb, sdf, mol2, xyz, cif, cdjson, mmtf, prmtop, gro, pqr, cube and vasp. Only the PDB path is worked through in the examples given.

How do I render a molecular surface with 3Dmol.js?

Call `viewer.addSurface` with a surface type such as `$3Dmol.SurfaceType.VDW`, a `VolumeData` object wrapping cube data, and a gradient scheme such as `$3Dmol.Gradient.ROYGB`. The volume and its range are supplied by the caller, and the README example passes the range bounds in descending order.

What licence does 3Dmol.js use?

The package manifest declares `BSD-3-Clause` and the README describes a permissive BSD licence, while GitHub shows the licence on the project page as a custom one it cannot classify. The README also requires that the code be properly acknowledged and that the project be cited.

How often is 3Dmol.js updated?

The last push to the master branch was on 2026-09-12. Tagged releases include 2.5.5 on 2026-05-22, 2.5.4 on 2026-01-22 and 2.5.3 on 2025-09-27.

Official sources

  1. 3dmol/3Dmol.js on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/3dmol-3dmol-js.svg)](https://hysenlabs.com/projects/3dmol-3dmol-js)

Was this useful?