renkin 0.1.0

Ultra-fast retrosynthesis engine for computer-aided synthesis planning (CASP) — pure Rust, WASM-ready, Python bindings via PyO3
Documentation

RENKIN — Retrosynthesis Engine

Computer-Aided Synthesis Planning (CASP) · Pure Rust · WebAssembly · Python
Named after 錬金 (れんきん, renkin) — Japanese for alchemy: just as alchemists transformed base metals into gold, RENKIN transforms target molecules back into cheap starting materials.

Crates.io License: MIT WASM Pure Rust

日本語版 README


What is RENKIN?

RENKIN is an open-source retrosynthesis engine for computer-aided synthesis planning (CASP) that automatically discovers optimal chemical reaction routes from a target molecule back to cheap, commercially available starting materials — a core problem in drug discovery and medicinal chemistry.

Built entirely in Rust with the chematic cheminformatics crate, RENKIN solves the fundamental speed and dependency problems of existing Python-based CASP tools (AiZynthFinder, ASKCOS, Retro*, etc.). It ships as:

  • CLI — single binary, cargo build --release
  • Python packageimport renkin via PyO3 + maturin
  • WASM module — 493 KB bundle, runs in the browser with no server

All from a single pure-Rust codebase with zero C/C++ dependencies.


Key Features

Feature Detail
Pure Rust Zero C/C++ dependencies. Cross-platform with cargo build alone
A* / AND-OR Tree Search Retro*-equivalent algorithm proven more efficient than MCTS for retrosynthesis
SA Score heuristic chematic::chem::sa_score guides search toward synthetically accessible precursors
Beam search --beam-width N limits heap size for memory-bounded exploration
Graph-based Ar–Ar cleavage Bridge-bond detection via DFS — correctly handles biaryl (Suzuki) disconnections
Parallel rule application rayon parallelises SMIRKS rule evaluation; sequential fallback on WASM
Python bindings maturin extension — import renkin; renkin.find_routes(...)
WASM-ready 493 KB bundle via wasm-pack; browser demo with 2D structure rendering
~400 building blocks Curated commercial starting materials covering esters, amines, halides, heterocycles, amino acids, sulfonyl chlorides, boronic acids and more
Benchmark CLI renkin-bench --input targets.smi produces a JSON success/timing report

Architecture

Target SMILES
     │
     ▼
┌─────────────────────────┐
│     chem_env.rs         │  ← chematic wrapper
│  - SMILES parse         │     SMARTS VF2 building-block check
│  - SMIRKS retro rules   │     fragment sanitization
│  - Building block check │     HashMap O(1) pre-filter
└────────────┬────────────┘
             │  par_iter (rayon / sequential on WASM)
             ▼
┌─────────────────────────┐
│      search.rs          │  ← A* / AND-OR Tree Search
│  - Priority queue       │     SA Score heuristic
│  - Closed list          │     beam search pruning
│  - Degenerate filter    │
└────────────┬────────────┘
             │
             ▼
┌─────────────────────────┐
│      score.rs           │  ← Heuristic / Cost Function
│  - SA Score (chematic)  │     h = Σ(1 + 0.5·(sa−1)/9)
│  - MW step cost         │     g = Σ(1 + total_mw/2000)
└────────────┬────────────┘
             │
             ▼
  JSON  ←  CLI / Python / WASM

Technology Stack

  • Language: Rust (Edition 2024)
  • Cheminformatics: chematic v0.4.9+
    • chematic-smiles — SMILES parsing & canonical SMILES
    • chematic-smarts — VF2 substructure matching (building block identity)
    • chematic-rxn — SMIRKS reaction application (run_reactants)
    • chematic-chem — SA Score, molecular weight, aromaticity descriptors
  • Search: A* + AND/OR Tree (Retro* equivalent)
  • Parallelism: rayon — parallel SMIRKS rule application
  • Python: PyO3 + maturin
  • WASM: wasm-bindgen + wasm-pack

Installation

As a library

# Cargo.toml
[dependencies]
renkin = "0.1"

CLI (from source)

git clone https://github.com/kent-tokyo/renkin
cd renkin
cargo build --release

Python

pip install maturin
git clone https://github.com/kent-tokyo/renkin && cd renkin
python -m venv .venv && source .venv/bin/activate
maturin develop --features python

Getting Started

CLI

# Retrosynthesis (Aspirin, depth 3)
./target/release/renkin --target "CC(=O)Oc1ccccc1C(=O)O" --depth 3

# With beam search (top-50 nodes)
./target/release/renkin --target "CC(=O)Oc1ccccc1C(=O)O" --depth 5 --beam-width 50
--target / -t      Target molecule SMILES
--depth  / -d      Max retrosynthesis depth (default: 5)
--max-routes / -n  Max routes to return (default: 5)
--beam-width / -w  Beam search width, 0 = unlimited A* (default: 0)
--building-blocks  Path to .smi file of commercial starting materials

Python

import renkin, json

routes = json.loads(renkin.find_routes(
    "CC(=O)Oc1ccccc1C(=O)O",   # Aspirin
    depth=3,
    max_routes=5,
))
print(routes["routes_found"])   # number of routes found
for r in routes["routes"]:
    print(r["depth"], [s["rule"] for s in r["steps"]])

WASM

wasm-pack build --target web --no-default-features
# Output: pkg/  (npm-ready package)
# Browser demo: python3 -m http.server 8080 → http://localhost:8080/demo/
import init, { find_routes } from './pkg/renkin.js';
await init();

const result = JSON.parse(find_routes(
  "CC(=O)Oc1ccccc1C(=O)O",  // target SMILES
  3,   // depth
  5,   // max_routes
  0,   // beam_width (0 = unlimited A*)
));
console.log(result.routes_found);

Benchmark

# Input: one SMILES per line, optional name after whitespace
./scripts/run_benchmark.sh --input data/benchmark_targets.smi --depth 5
{
  "total": 42, "solved": 37, "success_rate": 0.88,
  "avg_depth": 1.05, "avg_time_ms": 2.5,
  "results": [...]
}

CLI Output Example

{
  "target": "CC(=O)Oc1ccccc1C(=O)O",
  "routes_found": 2,
  "routes": [
    {
      "steps": [
        {
          "rule": "ester_cleavage",
          "target": "CC(=O)Oc1ccccc1C(=O)O",
          "precursors": ["CC(=O)O", "Oc1ccccc1C(=O)O"]
        }
      ],
      "depth": 1
    }
  ]
}

depth: 0 means the target itself is a commercially available starting material (buy directly).


Retro-Rules (14 total)

Rule Reaction type Strategy
ester_cleavage Ester → acid + alcohol SMIRKS
amide_cleavage Amide → acid + amine SMIRKS
friedel_crafts_acylation_retro Ar-C(=O)R → Ar-H + acyl chloride SMIRKS
aryl_carboxylation_retro Ar-COOH → Ar-H + CO₂ surrogate SMIRKS
aryl_amine_retro Ar-N → Ar-H + amine SMIRKS
buchwald_hartwig_retro Ar-N → Ar-Br + amine SMIRKS
aryl_ether_retro Ar-O → Ar-OH + fragment SMIRKS
suzuki_retro Ar-Ar → Ar-Br + Ar-H Graph (bridge-bond DFS)
cc_single_cleavage C–C → two fragments SMIRKS
wittig_retro C=C → C=O + C=O SMIRKS
reductive_amination_retro C–N → C=O + amine SMIRKS
cn_aliphatic_cleavage C–N → two fragments SMIRKS
co_aliphatic_cleavage C–O → two fragments SMIRKS
alcohol_oxidation_retro C–OH → C=O SMIRKS

suzuki_retro uses a graph-based bridge-bond algorithm instead of SMIRKS to correctly handle symmetric biaryls (biphenyl, 4-fluorobiphenyl, etc.) without the BFS leakage artifacts that affect SMIRKS-based approaches.


Project Structure

renkin/
├── Cargo.toml
├── src/
│   ├── lib.rs           # public library (DEFAULT_BUILDING_BLOCKS, re-exports)
│   ├── main.rs          # CLI binary
│   ├── bin/
│   │   └── benchmark.rs # renkin-bench binary
│   ├── chem_env.rs      # chematic wrapper — parse, retro rules, BB check
│   ├── score.rs         # SA Score heuristic + step cost
│   ├── search.rs        # A* / AND-OR tree engine + beam pruning
│   ├── python.rs        # PyO3 bindings (--features python)
│   └── wasm.rs          # wasm-bindgen bindings (cfg = wasm32)
├── data/
│   ├── building_blocks.smi      # Commercial starting materials (~400 entries)
│   └── benchmark_targets.smi   # 42-molecule benchmark set
├── demo/
│   └── index.html       # Browser WASM demo with 2D structure rendering
└── scripts/
    └── run_benchmark.sh # Benchmark runner with human-readable summary

Roadmap

  • Phase 1 — SMIRKS retro-reaction rules + fragment sanitization
  • Phase 2 — A* / AND-OR tree search, closed list, degenerate-route filter
  • Phase 3 — SA Score heuristic + beam search (--beam-width)
  • Phase 4 — Parallel rule application (rayon; sequential fallback on WASM)
  • Phase 5 — Python bindings (PyO3 + maturin)
  • Phase 6 — WASM build (493 KB, pkg/ npm-ready)
  • Phase 7 — Benchmark CLI (renkin-bench)
  • Phase 8 — 21 unit tests, SMIRKS rules 5→14, building blocks ~30→~400
  • Phase 9 — Browser WASM demo (SmilesDrawer 2D rendering), benchmark target set
  • Phase 10 — Graph-based biaryl cleavage (suzuki_retro), O(1) BB HashMap index
  • Phase 11 — Formal benchmark vs. AiZynthFinder / Retro* on USPTO-50k
  • Phase 12 — PyPI / npm publish

Competitive Landscape

Tool Language Algorithm WASM Zero-dep build
ASKCOS Python MCTS / A* No No (Docker, 64 GB RAM)
AiZynthFinder Python MCTS primary No No (conda, model download)
IBM RXN Closed Transformer No No (cloud only)
SYNTHIA Closed SMARTS + AND/OR No No (proprietary)
Retro* Python A* + AND/OR No No (unmaintained)
★ RENKIN Rust A* + AND/OR Yes Yes (cargo build)

All existing open CASP tools are Python-based. RENKIN fills the vacant niche: Rust-native, WASM-deployable, zero-dependency, A* search.


License

MIT


GitHub Topics: retrosynthesis cheminformatics wasm rust drug-discovery casp synthesis-planning computational-chemistry