Self-hosted service
epam/ketcher avatar
epam/ketcher

ketcher: embedding a chemistry editor into your own web application

Web-based molecule sketcher

917 stars263 forksTypeScriptApache-2.0

At a glance

What is it?
Ketcher is EPAM's open source web based chemical structure editor, published as a React component library and as a ready-to-run standalone application that you can host and inject in an iframe. It is aimed at cheminformatics teams that need a sketcher inside a larger product rather than a desktop tool.
Who is it for?
Adopt ketcher when your product needs users to draw or edit chemical structures in the browser and you want a full editor with file format support and stereochemistry rather than a bare input field. Skip it if your users only need to paste a SMILES string, since the editor brings a large dependency surface, and skip it if you cannot run the Indigo service, since the chemistry backend is not optional.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, 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 sketcher aimed at product teams, not at chemists with a desktop

Ketcher is described as an open-source web-based chemical structure editor, and the README states the audience directly: it is designed for chemists, laboratory scientists and technicians who draw structures and reactions.

The positioning line lists high performance, good portability, light weight and the ability to easily integrate into a custom web application. That last one is what distinguishes this from the many standalone molecule editors. Ketcher is packaged for embedding, as a React component library and as a standalone application you can host and place in an iframe, and the npm packages are named for exactly those two modes.

The rendering approach is worth noting as a first decision rather than a detail. Ketcher uses SVG to achieve best quality in-browser chemical structure rendering. For a structure editor that is an unusual choice compared with a canvas, and it has a practical consequence: the output is vector, resolution independent, and inspectable in the DOM, which matters when a user wants to export or print a structure, and when you want to restyle parts of a drawing with CSS.

The project also supports 3D structure visualization, and it does so through a separate component. Ketcher uses Miew-React for viewing and editing data in 3D, with the last checked version listed as 0.12.0, and the package living in a separate repository at epam/miew.

The interface is localised in English and Simplified Chinese, with a live language switcher in Settings, and the repository carries a crowdin.yml.

Two embedding routes, and the npm command

The README states that at the moment Ketcher can be embedded into your application in two ways. The first is as a ready-to-run application, with the desired version taken from the Assets block of the releases, and that application can be injected as an iframe or served as a separate page. The second is as a react component library, published to npm as `ketcher-react`.

The installation for the component route is:

bash
npm install ketcher-core ketcher-react

Note that `ketcher-core` comes first and is not optional in that command. The core package holds the domain model, the shared services, the functions and the interface declarations, and the React package is only the component layer on top of it.

The basic setup in the README shows the whole shape of the integration:

javascript
import { Editor } from 'ketcher-react';
import { StandaloneStructServiceProvider } from 'ketcher-standalone';

import 'ketcher-react/dist/index.css';

const structServiceProvider = new StandaloneStructServiceProvider();

function App() {
  return (
    <Editor
      staticResourcesUrl="/public"
      structServiceProvider={structServiceProvider}
      onInit={(ketcher) => {
        window.ketcher = ketcher;
      }}
    />
  );
}

Three things are visible. The editor is given a struct service provider, which is the abstraction that decides where the chemistry actually runs. The stylesheet has to be imported explicitly, since the component renders SVG rather than shipping styled output. And `onInit` hands you the ketcher instance once it is ready, which is the moment you can start calling methods on it.

The iframe init handshake, and the undefined window.ketcher trap

The README has a section on accessing Ketcher when it is embedded via an iframe, and the problem it describes is the kind that costs an afternoon.

When you embed the ready-to-run standalone application as an iframe rather than using `ketcher-react` as a component library, Ketcher initializes asynchronously inside the frame, loading the Indigo service and WASM among other things. Because of that, `window.ketcher` inside the frame is only assigned once initialization finishes, so reading `iframeEl.contentWindow.ketcher` right after the frame's load event, or immediately after inserting the iframe, will typically still be undefined.

The fix the README recommends is to listen for the init message that the standalone application posts to its parent window once `onInit` has fired, rather than polling:

javascript
const iframeEl = document.getElementById('ifKetcher');

window.addEventListener('message', (event) => {
  if (event.source !== iframeEl.contentWindow) return;
  if (event.data?.eventType === 'init') {
    const ketcher = iframeEl.contentWindow.ketcher;
    // ketcher is now guaranteed to be initialized
  }
});

The `event.source !== iframeEl.contentWindow` guard is not decoration. Any page can post a message to your window, so without the origin check you would accept an init claim from any source and then read a ketcher object that does not exist.

The practical difference between the two routes is therefore not just packaging. The component route gives you a synchronous handle through `onInit`. The iframe route gives you an asynchronous one, and if you write the integration as if it were synchronous you get an undefined object at exactly the moment your page is busiest.

Indigo is the chemistry, and it has to be configured

Ketcher does not implement cheminformatics itself. The README points to an Indigo service for service installation, hosted in the EPAM life science open source documentation, and the iframe section refers to loading the Indigo service and WASM during initialization.

That is a substantial architectural fact for anyone evaluating the project. The drawing surface, the tool palette and the SVG rendering are Ketcher's, but the parts that are hard, such as structure cleanup, aromatisation, CIP descriptor calculation, structure checking and atom mapping, are delegated to Indigo. The reader should treat Indigo as a required backend component and budget for deploying it.

The README's FAQ offers two pointers. One is the Indigo service installation instructions, the other is the `packages/ketcher-react/README.md` for details on using the React component library.

The interface between Ketcher and Indigo is the struct service provider. In the basic setup the `StandaloneStructServiceProvider` is used, and the project also ships a `build:example:remote` script and a `serve:remote` script, which suggests the remote form is the service-backed variant while the standalone build bundles what it can.

For file formats, the README lists the ability to load and save structures and reactions in MDL Molfile or RXN file format, InChI String, ChemAxon Extended SMILES and ChemAxon Extended CML file formats. The repository topics list the wider set the code touches, including CDX and CDXML, SMARTS, FASTA, HELM and IDT formats, and the macromolecules editor covers nucleotide and amino acid sequences.

The tool set is where the chemistry lives in the UI

The feature list and the editor builtin tools section describe a working professional editor rather than a diagram toy.

For 2D, there is fast structure representation that satisfies common chemical drawing standards. The tools include an Atom Tool, a Bond Tool and a Template Tool to draw and edit structures, an Aromatize and De-aromatize Tool, a Calculate CIP Descriptors Tool, a Structure Check Tool, and an MW and Structure Parameters Calculate Tool. There is a Selection Tool for selecting, modifying and erasing connected and unconnected atoms and bonds, or the Shift key as an alternative.

Cleanup comes in two flavours, which is a distinction worth making. The Advanced Structure Clean up Tool does stereochemistry checking and structure layout, while the Simple Structure Clean up Tool checks bonds length, angles and the spatial arrangement of atoms.

For grouping there are R-Group and S-Group tools, described as Generic, Multiple group, SRU polymer, peratom and Data S-Group, which is the feature set that separates a chemistry editor from a general node graph. A Reaction Tool covers reaction generating with manual and automatic atom-to-atom mapping, and there is a Flip and Rotate Tool.

Beyond the canvas, the README lists history of actions with rollback to a previous state, zoom, hotkeys, cut, copy and paste, a template library that includes custom and user templates, atom and bond basic properties and query features, aliases and Generic groups, and OCR, the ability to recognise structures at pictures, image files, and reproduce them.

That last one is worth a caveat. OCR from a picture is a convenience for the user who has a paper figure, and it is a source of structures that may not be what the figure intended. The tool exists; whether you trust its output for a registered compound is a decision your workflow has to make.

A workspace of four published packages and several examples

The package table in the README describes the split between the four published packages, and the distinction is by dependency weight.

`ketcher-core` carries the core functionality: domain, shared services, functions and interface declarations. `ketcher-standalone` contains only the functionality necessary to start Ketcher in standalone mode. `ketcher-react` contains only the functionality necessary to define components. And `ketcher-macromolecules` contains the macromolecules editor functionality and UI components.

That is a deliberate design for embedding. An application that only wants the React editor installs the core plus the React package. An application that wants the standalone app takes the standalone package instead, which avoids pulling the full component tree into a bundle it will not use.

The repository root package.json is a private npm workspace listing those packages plus `ketcher-autotests`, `example`, `example-ssr`, `example-separate-editors` and `demo`. The scripts show the workflow: `build:packages` builds core, then standalone and react in parallel, then macromolecules, `build:example` builds the example app, and `build:demo` produces the demo site

For development there are `serve:remote` and `serve:standalone` scripts that run the example in both modes at once, and `up` which runs a build and start script. Testing is split across the four packages with a `test:types` script running the type checks, and the `prepush` hook runs both the tests and the type checks, so type errors are caught before a push rather than at review.

The repository also carries a `ketcher-autotests/` workspace, a `documentation/` directory, an `openspec/` directory, and editor and agent configuration files, including a CLAUDE.md and a `.memory-bank/` directory.

Localisation is a build flag, and the licence is Apache-2.0

The `.env.example` file at the repository root documents a build-time decision that is easy to miss. `KETCHER_MULTI_LANGUAGE_BUILD` controls whether the build includes every supported language, English and Simplified Chinese, into `ketcher-react` and `ketcher-macromolecules`, including the Settings language switcher. Unset, or set to anything other than `true`, it builds the default English-only bundle.

So the default build is English only, and the Chinese interface is opt-in at build time rather than a runtime download. The comment notes that a variable already set in the shell always takes precedence over the value in the file, and that the file is loaded by the rollup configs of the two packages that need it.

That is a sensible default for a package that most integrators will consume in English, and it explains the badge in the README about a live language switcher in Settings: the switcher is only present in a multi-language build.

On the licence, the repository licence field says Apache-2.0, the README carries an Apache 2.0 badge, and the tree has a LICENSE file alongside a NOTICE file and a LICENSE-history directory. Apache-2.0 is a good fit for a component you embed in a commercial product, since it includes an explicit patent grant and carries obligations that are manageable for commercial embedding, such as preserving notices.

On maintenance, the release list shows v3.16.2 and v3.17.2 both on 2026-08-31 and v3.18.0 on 2026-09-02, with the last push on 2026-10-19. Three releases inside four days in late August followed by a minor version is the pattern of a project that maintains several release lines at once, which is normal for a library with a standalone build, a React package, a macromolecules package and a demo site.

Editorial conclusion

Adopt ketcher when your product needs users to draw or edit chemical structures in the browser and you want a full editor with file format support and stereochemistry rather than a bare input field. Skip it if your users only need to paste a SMILES string, since the editor brings a large dependency surface, and skip it if you cannot run the Indigo service, since the chemistry backend is not optional. Verify first that your chosen embedding works, the React component with a struct service provider, or the standalone application with its asynchronous init handshake, and that the file formats your users need, MDL, RXN, InChI, ChemAxon Extended SMILES or CML, are on the list. The licence field on the repository says Apache-2.0, the last push was on 2026-10-19, and the current release is v3.18.0.

Frequently asked questions

What is Ketcher and who is it for?

Ketcher is an open-source web-based chemical structure editor for chemists, laboratory scientists and technicians who draw structures and reactions. The README describes it as offering high performance, good portability, light weight and easy integration into a custom web application.

How do I install Ketcher in a React application?

The README gives `npm install ketcher-core ketcher-react`, then imports the `Editor` from `ketcher-react`, a `StandaloneStructServiceProvider` from `ketcher-standalone`, and the stylesheet `ketcher-react/dist/index.css`, passing the provider to the editor with a `staticResourcesUrl`.

Why is window.ketcher undefined in an embedded Ketcher iframe?

When Ketcher runs as the standalone application inside an iframe it initializes asynchronously, loading the Indigo service and WASM, so `window.ketcher` is only assigned once that finishes. The README recommends listening for the `init` message the application posts to its parent window, and checking `event.source` against the iframe's contentWindow.

Which file formats can Ketcher load and save?

The README lists MDL Molfile or RXN file format, InChI String, ChemAxon Extended SMILES and ChemAxon Extended CML file formats. The macromolecules editor covers nucleotide and amino acid sequences, and the repository topics also list CDX, CDXML, SMARTS, FASTA, HELM and IDT.

What does Ketcher need for its chemistry backend?

Ketcher delegates the chemistry to Indigo, and the README points at the Indigo service installation instructions. The interface is the struct service provider, with `StandaloneStructServiceProvider` used in the basic setup.

How do I build Ketcher with a non-English interface?

Set `KETCHER_MULTI_LANGUAGE_BUILD` to `true` before the build, which includes every supported language, English and Simplified Chinese, into ketcher-react and ketcher-macromolecules along with the Settings language switcher. The default build is English only.

Official sources

  1. epam/ketcher on GitHub
  2. License: Apache-2.0
  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/epam-ketcher.svg)](https://hysenlabs.com/projects/epam-ketcher)

Was this useful?