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
- Still stuck? Read the FAQ or contact support.
- Something wrong on this page? Tell us.
- For AI tools: llms.txt
