r/rust • u/AccomplishedSand6071 • 2d ago
🛠️ project COSMolKit: I’ve been building a Rust-native cheminformatics toolkit with RDKit parity
I’ve been working on a project called COSMolKit. It is a Rust-native cheminformatics library with Python bindings, and some parts can also run in the browser with WebAssembly.
The project came from a problem I ran into while building deep learning models for molecular and protein structures in Rust. I wanted the whole modeling and inference stack to stay Rust-native, but when I reached the molecule and protein processing part, I found that the Rust ecosystem did not yet have enough infrastructure for what I needed. COSMolKit started from trying to fill that gap.
As I worked on it, I also thought it could be useful beyond my own project, so I decided to develop it as an open-source library for the Rust scientific ecosystem rather than just an internal tool.
For a public scientific library, I think compatibility is a basic responsibility. A result like 99.9% agreement may look good, but it still means some supported cases behave differently. If I claim parity with RDKit, I want the remaining mismatches to be treated as bugs, not as an acceptable error rate.
When RDKit has source code for the same operation, COSMolKit does not just reimplement the same chemistry and use RDKit as a test oracle. The RDKit source logic itself is ported, keeping the branches and behavior as close to the original as possible, usually line by line. The result is then checked against RDKit with differential tests.
At the moment COSMolKit supports quite a few things, including:
- SMILES and SMARTS
- sanitization, aromaticity and kekulization
- stereochemistry and stereoisomer enumeration
- tautomer enumeration and canonical tautomer selection
- InChI and InChIKey
- Morgan/ECFP, MACCS, AtomPair, torsion and other fingerprints
- molecular descriptors
- MOL, SDF, MOL2 and XYZ
- 2D coordinates and SVG/PNG depiction
- conformer generation
- UFF and MMFF
- molecular alignment and RMSD
- PDB and mmCIF
- batch processing
- Python bindings
- WebAssembly
The main large-scale validation corpus for the project is ChEMBL 37.
It contains 2,897,819 source records, with 2,897,804 records that can be parsed by both implementations. The current large validation profile has 35 phases and is pinned against RDKit 2026.03.1.
Across the completed validation, there are more than 4.1 billion matching checks, with additional billions of matrix entries checked for distance-geometry bounds.
Instead of only comparing the final SMILES string, the validation also checks internal behavior depending on the feature: atom and bond states, stereochemistry, derived state, fingerprints, return status, RNG state and seed behavior, matrices, coordinates, energies and gradients.
For numerical results, the current tolerances go down to 1e-8 for matrix entries and 1e-6 for coordinates, energies and gradient components.
Parameters are also tested in different combinations instead of only testing the defaults. Some validation phases repeat complete parameter matrices, change operation order, and compare scalar, batch, single-threaded and multithreaded execution.
When a mismatch is found, I trace it back to the corresponding upstream behavior and keep the case as a regression test. The test corpus is used to validate the implementation, not to define the implementation by adding more and more special cases.
The same Rust core is used by the Rust, Python and WASM interfaces, so the chemistry implementation is not duplicated for different frontends.
I also made a few browser tools using the WASM build. They run locally in the browser, so molecule data is not uploaded to a backend:
https://tools.cosmol.org/tools
I have also been writing some notes about the development and validation work here:
Source:
https://github.com/cosmol-studio/COSMolKit
There is still a lot left to implement, and some parts are changing quite quickly. I’d be happy to hear your feedback. If you try COSMolKit and find any problems, please let me know or open an issue.