How to move from Marvin JS or Ketcher to Athanor

Replace the Marvin JS scripts with https://athanor.arbastro.com/app/embed/athanor-marvin.js and keep the iframe. MarvinJSUtil.getEditor, importStructure, exportStructure and molchange keep working.

Marvin JS reaches end of sale on December 31, 2026 and end of life in December 2027. A page built on it can move to the Athanor editor by changing one script tag.

The one-line change

Before:

<script src="marvinjs/gui/lib/promise-1.0.0.min.js"></script>
<script src="marvinjs/js/marvinjslauncher.js"></script>
<iframe id="sketch" src="marvinjs/editor.html" style="width: 600px; height: 450px"></iframe>

After:

<script src="https://athanor.arbastro.com/app/embed/athanor-marvin.js"></script>
<iframe id="sketch" src="marvinjs/editor.html" style="width: 600px; height: 450px"></iframe>

The iframe keeps its id, size and styles; the script points it at the Athanor editor. The page's own code does not change:

MarvinJSUtil.getEditor('#sketch').then(function (sketcher) {
  sketcher.importStructure('mol', molfile);
  sketcher.on('molchange', function () {
    sketcher.exportStructure('mrv').then(save);
  });
});

If the page already has a real Marvin JS on it, MarvinJSUtil is left alone and the shim is reachable as AthanorMarvin.getEditor.

What maps

Marvin JS Athanor Notes
MarvinJSUtil.getEditor(sel) yes Resolves once the editor has answered the handshake
MarvinJSUtil.getPackage(sel) yes sketcherInstance, ImageExporter, onReady
exportStructure(format) yes mrv, mol (V2000), mol:V3, sdf, smiles, cxsmiles, cml, cdxml, inchi, inchikey, png, svg, and their MIME types
importStructure(format, data) yes mrv, mol, sdf (first record), smiles, cxsmiles, cdxml; null guesses
pasteStructure replaces Marvin adds to the drawing; this puts the structure on a fresh page
clear(), isEmpty() yes isEmpty is as of the last change the editor reported
on('molchange'), off yes Debounced by 300 ms: a drag is one change
setDisplaySettings({ toolbars: 'viewer' }) view only Other display settings are kept and handed back by getDisplaySettings, but do not change the drawing
setServices not needed Clean, name to structure and the rest are built in
ImageExporter.molToDataUrl returns a promise The one line a page has to change: .then(function (url) { ... })

cxsmiles is written as plain SMILES, which is valid CXSMILES; the extension block is not.

Ketcher pages

A Ketcher page reaches iframe.contentWindow.ketcher, which no browser allows across origins. Ask the shim instead:

AthanorKetcher.get('#ketcher').then(function (ketcher) {
  ketcher.setMolecule('CCO');
  ketcher.getSmiles().then(console.log);
  ketcher.getMolfile('v3000').then(save);
  ketcher.editor.subscribe('change', onChange);
});

getSmiles, getMolfile('v2000' | 'v3000'), getCml, getInchi, getInChIKey, getSdf, getCDXml, setMolecule, generateImage (a Blob) and editor.subscribe('change') work. getRxn, getKet and addFragment are refused with a sentence saying what to use instead.

Every call is a message of the embed protocol: the shim never reaches into the editor's page, and the editor answers the embedding page's origin only.

Is this helpful?

Last updated Nov 12, 2026