Skip to content

RENKIN

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.

CI Crates.io PyPI npm License: MIT

What is RENKIN?

RENKIN is a retrosynthesis engine that automatically plans multi-step chemical syntheses by working backwards from a target molecule to commercially available starting materials. Given a target SMILES, it searches for synthetic routes using a library of retrosynthetic reaction rules.

Try It Now

→ Open Playground

Runs entirely in WebAssembly — no server, no installation.

Open In Colab

One-click Python notebook — pip install renkin + aspirin example + RDKit visualization.

pip install renkin
import renkin
result = renkin.find_routes(target="CC(=O)Oc1ccccc1C(=O)O", depth=5)

Key Features

Feature Details
Pure Rust Zero C/C++ dependencies — safe, fast, cross-platform
WebAssembly Runs in the browser at near-native speed
Python bindings pip install renkin — no RDKit required
22 hand-crafted rules + up to 50k extracted via --templates Ester, amide, Suzuki, Heck, Wittig, sulfonamide, and more; extended via rdchiral-extracted templates
Building blocks 402 unique compounds in data/building_blocks.smi (used when found relative to the current working directory); otherwise CLI/Python fall back to a compiled-in 152-compound set, which WASM always uses. Pass --building-blocks/building_blocks= to specify explicitly
A* / beam search Frequency-weighted A* with beam-width control; step_cost reduced for high-frequency templates (Phase A)
Route scoring Per-step confidence, success_probability (Retro-prob), route_cost with optional --bb-prices CSV
Stable template IDs + evidence sidecar Every template has a stable template_id; attach curated conditions/yields/warnings via --template-metadata — see Template Evidence
Constraint DSL --avoid-elements Br,I --require-elements B filters routes by element profile
Forward validation renkin-forward validate verifies each retrosynthetic step by forward prediction; pipe-friendly (stdin support)
Failure diagnostics renkin-bench --failure-taxonomy classifies unsolved targets by cause (beam limit, depth limit, template gap, stock near-miss)
Cascade search Two-stage search: fast defaults → hard cases re-run at higher beam/depth
Stability testing --quietset-out exports observations for quietset cross-config stability analysis
MCP server renkin-mcp exposes find_routes, diagnose_failure, validate_route to Claude Desktop

Quick Example

"""RENKIN Python quickstart. Runs as part of CI so this example can never
silently drift from the real API (see .github/workflows/ci.yml)."""

import json

import renkin

result = json.loads(
    renkin.find_routes(
        target="CC(=O)Oc1ccccc1C(=O)O",  # Aspirin
        depth=5,
        max_routes=3,
    )
)

print(f"Routes found: {result['routes_found']}")
for route in result["routes"]:
    print(f"Route (depth {route['depth']}):")
    for step in route["steps"]:
        print(f"  {step['target']} -> {' + '.join(step['precursors'])}")
        print(f"  via {step['rule']}")
//! RENKIN Rust quickstart. Compiled and run as part of CI (see
//! .github/workflows/ci.yml) so this example can never silently drift from
//! the real `find_routes` API.

use renkin::chem_env::{ChemEnv, default_rules};
use renkin::search::{SearchConfig, find_routes};

fn main() -> anyhow::Result<()> {
    let env = ChemEnv::load("data/building_blocks.smi")?;
    let rules = default_rules();
    let config = SearchConfig {
        max_depth: 5,
        max_routes: 3,
        ..Default::default()
    };

    let (routes, _stats) = find_routes("CC(=O)Oc1ccccc1C(=O)O", &env, &rules, &config)?;
    println!("Routes found: {}", routes.len());
    for route in &routes {
        println!("Route (depth {}):", route.depth);
        for step in &route.steps {
            println!("  {} -> {}", step.target, step.precursors.join(" + "));
            println!("  via {}", step.rule);
        }
    }
    Ok(())
}
import init, { find_routes } from './pkg/renkin.js';

await init();
const result = JSON.parse(find_routes("CC(=O)Oc1ccccc1C(=O)O", 5, 3, 0));
console.log(`Found ${result.routes_found} routes`);

How It Works

Target molecule (SMILES)
  Retrosynthetic   ←── 22 built-in + up to 50k extracted (--templates)
  rule application
  Precursor set    ←── Check against building block stock (402 file / 152 fallback)
  A* / BFS search  ←── Beam width, depth limit
  Synthetic routes (depth, steps, precursors)

Reaction Rules

RENKIN ships 22 hand-crafted rules (a mix of graph-based dispatch and SMIRKS-based patterns) covering common pharmaceutical bond disconnections, plus supports up to 50k rdchiral-extracted templates via --templates:

  • Acyl disconnections: ester hydrolysis, amide cleavage (graph-based), Friedel-Crafts acylation, acyl chloride formation
  • Aryl C-heteroatom: Ullmann ether (C-O), sulfonamide formation, decarboxylation
  • Aryl C-halide: chloride/bromide halogen exchange
  • Aryl C-C coupling: Suzuki (graph-based), Heck, Sonogashira
  • Sulfone disconnections: diaryl sulfone cleavage (graph-based)
  • Protecting groups: Boc, Cbz deprotection (graph-based)
  • Aliphatic: reductive amination, Wittig, Claisen condensation
  • Oxidation: alcohol → carbonyl

See Benchmark for current USPTO-50k results and methodology — historical figures (78.0%/95.9%/81.8%) shown elsewhere on the web are invalidated and not representative of current performance; do not cite them.

Installation

pip install renkin
[dependencies]
renkin = "0.21"
npm install renkin

See Installation for details.