npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

megane-rdkit

v0.1.0

Published

RDKit compiled to WebAssembly for megane: ETKDG conformer embedding and MMFF/UFF minimisation today, more RDKit features as megane needs them

Readme

megane-rdkit

RDKit compiled to WebAssembly with Emscripten, for megane. It is a thin wrapper over an unmodified RDKit release: the official RDKit.js (@rdkit/rdkit, MinimalLib) exposes only 2D coordinate generation (set_new_coords), so RDKit features megane needs in the browser that MinimalLib does not ship are built here instead.

Today the wrapper exposes 3D conformer embedding (ETKDG) with MMFF94/UFF minimisation, written for megane Builder's "embed a flat sketch in 3D" feature; a pure-JS alternative (openchemlib-js) measured 10–50× slower than RDKit on the same molecules. New features are added as further bindings in src/megane_rdkit.cpp, each following the same string-in / JSON-out convention, and RDKit itself is upgraded by changing RDKIT_TAG in scripts/build.sh.

Build

Requirements: git, curl, cmake ≥ 3.20, ninja (optional), a host C++ compiler for Boost's bootstrap.sh, Python 3 (emsdk), Node 22+. Eigen headers are taken from /usr/include/eigen3 when present (apt install libeigen3-dev) and cloned otherwise.

bash scripts/build.sh          # deps → rdkit → wrapper → test
bash scripts/build.sh rdkit    # just rebuild the RDKit libraries
bash scripts/build.sh wrapper  # just relink the wrapper into dist/
node test/smoke.mjs

The same steps are exposed as npm scripts (npm run build, npm run build:rdkit, npm run build:wrapper, npm test).

Everything the build downloads or compiles lives in .deps/ (override with MEGANE_RDKIT_DEPS_DIR), which the CI workflow caches so only the wrapper relinks on a normal run. Only the RDKit targets the wrapper links (currently DistGeomHelpers, ForceFieldHelpers, FileParsers, SmilesParse) and their dependencies are compiled; drawing, fingerprints, reactions, InChI, coordgen and the other externals are switched off, and RDKit's configure-time downloads (RingDecomposerLib, …) are disabled so the build also works behind egress policies that block GitHub release archives. A feature that needs another RDKit library adds its *_static target to step_rdkit in scripts/build.sh; CMakeLists.txt links every static library it finds.

Outputs: dist/megane-rdkit.mjs (Emscripten ES-module glue) and dist/megane-rdkit.wasm. Neither is committed; the CI workflow (.github/workflows/build.yml) builds them on every pull request and push to main and uploads them as the megane-rdkit-<RDKIT_TAG> artifact.

Install

npm install megane-rdkit

The package ships the loader (index.mjs, index.d.ts) and the built module (dist/megane-rdkit.mjs, dist/megane-rdkit.wasm). The .wasm is fetched at runtime, so a bundler has to know where it ends up; pass that URL as locateFile. With Vite (and other bundlers that understand new URL(..., import.meta.url)):

import { loadRDKit } from "megane-rdkit";

const wasmUrl = new URL("megane-rdkit/dist/megane-rdkit.wasm", import.meta.url).href;
const rdkit = await loadRDKit({ locateFile: () => wasmUrl });

In Node the module finds the .wasm next to itself and locateFile is not needed. The calls are synchronous and embed takes tens to hundreds of milliseconds for drug-sized molecules, so in the browser load and call it from a Web Worker.

API

import { loadRDKit } from "megane-rdkit";

const rdkit = await loadRDKit({ locateFile: () => wasmUrl });
rdkit.version(); // "2026.03.6"

const { molblocks, energies, converged, forceField, warnings } = rdkit.embed(molfileFromKetcher, {
  numConfs: 1,          // ETKDG conformers to generate
  forceField: "MMFF94s", // "MMFF94s" | "MMFF94" | "UFF" | "none"; MMFF falls back to UFF when untyped
  maxIters: 500,
  randomSeed: 42,       // the loader's default; -1 lets RDKit pick
  embedParams: { useRandomCoords: true }, // any RDKit EmbedParameters override
});

embed accepts a SMILES or an MDL mol block (auto-detected). Hydrogens are added before embedding (addHs: true) and kept in the output unless removeHs: true. Stereo from wedge bonds in the mol block is honoured by ETKDG (enforceChirality). The result is one V2000 mol block per conformer, which any MOL parser (megane's included) reads directly.

Layout

| Path | What it is | | --- | --- | | src/megane_rdkit.cpp | The embind wrapper; one emscripten::function per feature (version, setVerbose, embed) | | CMakeLists.txt | Links the wrapper against the RDKit static libraries; Emscripten flags live here | | scripts/build.sh | Fetches the toolchain and dependencies, builds RDKit, links the wrapper, runs the smoke test | | index.mjs / index.d.ts | The loader and its TypeScript types | | test/smoke.mjs | Loads dist/, embeds a few molecules and asserts the geometry is 3D | | test/bench.mjs | Timing harness (nothing asserted) for comparing against RDKit in Python |

This repository is deliberately separate from megane: the build takes tens of minutes and needs emsdk, Boost and a C++ compiler that the rest of megane never touches; the artifact is a versioned binary that megane consumes as a dependency rather than rebuilds; and RDKit's release cadence is independent of megane's.

Releasing

Releases are cut by pushing a version tag; .github/workflows/publish.yml builds the module from the pinned toolchain, checks the tarball, publishes to npm with provenance and attaches the tarball and dist/ files to a GitHub release.

npm version 0.2.0 --no-git-tag-version     # bump package.json
git commit -am "chore: release 0.2.0"
git tag v0.2.0
git push origin main v0.2.0

The tag must equal v + the package.json version or the workflow stops before building. Authentication is npm trusted publishing (OIDC) once it is configured for the package on npmjs.com; until then the workflow uses the NPM_TOKEN repository secret (a granular access token with publish rights). The package follows semver for the wrapper's own API; the RDKit release it embeds is reported by rdkit.version() and pinned by RDKIT_TAG in scripts/build.sh.

Licensing

The wrapper is BSD-3-Clause (see LICENSE), the same licence as RDKit, so the package and the RDKit code compiled into it are under one set of terms. dist/megane-rdkit.wasm statically links RDKit (BSD-3-Clause), Boost (BSL-1.0), zlib (zlib licence) and Eigen (MPL-2.0, header only); THIRD_PARTY_LICENSES.md carries the notices a redistribution of the binary must keep, RDKit's in full. All of these are compatible with megane's MIT licence. Open Babel was ruled out for being GPL-2.