Library / SDK
reymond-group/smilesDrawer avatar
reymond-group/smilesDrawer

smiles-drawer: drawing molecular structures from SMILES in the browser

A small, highly performant JavaScript component for parsing and drawing SMILES strings. Released under the MIT license.

618 stars95 forksJavaScriptMIT

At a glance

What is it?
SmilesDrawer is a MIT licensed JavaScript library that parses SMILES strings and draws the corresponding molecular structure, to a canvas or to SVG, with no server, no images and no templates. It ships a parser built on a PEG grammar, a configurable drawing layer with one runtime dependency, and reference test suites for formulas and stereochemistry, and it is used in published chemistry work.
Who is it for?
SmilesDrawer suits anyone who needs a molecule drawn from a SMILES string inside a web page, a notebook, a documentation site or a dashboard, and who wants the drawing to happen in the browser rather than on a server that renders images.
Can I use it commercially?
Yes. MIT 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 last received commits 2 days ago.
What is it written in?
Mainly JavaScript, 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

No server, no images, no templates

SmilesDrawer 2.0 is a small, highly performant JavaScript component for parsing and drawing SMILES strings, and the README puts the pitch in three words: no server, no images, no templates, just a SMILES.

That is a precise description of a design decision rather than a slogan. The conventional way to show a molecule in a web application is to call a rendering service or a server side toolkit and receive a picture. SmilesDrawer does the work in the browser instead, from the string alone, so a page can show a structure without a network round trip and without a rendering infrastructure behind it.

The audience that follows is developers building chemistry-adjacent interfaces: a chemical database browser, a documentation page for a compound, a teaching tool, a dashboard over a dataset of molecules, a notebook output. The topics listed for the repository are biology, chemistry, data visualization, javascript-library and science, and the README links a live preview and presets, a playground for a single molecule, a playground in batch mode for many, and a documentation site.

The project is published on npm as smiles-drawer, the licence is MIT with a LICENSE.md file, and the package is not private, meaning it is installable from the registry rather than being an application.

There is also a citation request, which is unusual and worth taking seriously. If you use the code or the application, the README asks you to cite the original paper published by the Journal of Chemical Information and Modeling, with the DOI 10.1021/acs.jcim.7b00425. The author field in the package metadata names Daniel Probst and the Reymond Group at the University of Berne, which places the project in an academic group rather than a hobby project.

A PEG grammar parses, a layout engine draws

The mechanism has two halves, and the repository layout shows both.

The parsing half lives in the peg/ directory, and the name tells you the approach. A parsing expression grammar is a way of specifying a language formally and generating a parser from that specification, and SMILES is a small language with an irregular surface, so a grammar is a natural fit. The parse result is a tree, and the API hands that tree to you rather than a finished drawing.

The rendering half takes the tree and lays out the structure. The API distinguishes two drawing targets. SmilesDrawer.Drawer draws to a canvas element, and SmilesDrawer.SvgDrawer draws to an SVG element, which is what the Svelte example in the README uses. Both take the same tree and the same options, and the difference is the output medium.

The core call is the same in both cases. SmilesDrawer.parse takes the SMILES string and a callback, and the callback receives the parsed tree, which you then pass to the drawer along with the target element and a theme. The theme is a string, light or dark.

javascript
        SmilesDrawer.parse(input.value, function(tree) {
          // Draw to the canvas
          smilesDrawer.draw(tree, "example-canvas", "light", false);
          // Alternatively, draw to SVG:
          // svgDrawer.draw(tree, 'output-svg', 'dark', false);
        });

The last argument, false in the canvas call, is the flag the README uses for the light theme with the alternative SVG call shown with dark, so the arguments are target, theme and a boolean whose meaning the visible excerpt does not spell out.

One thing to know about the drawing is the font. The README says that for nice consistent font rendering you have to include the droid sans font from Google fonts, which is a real constraint: the atom labels are text in the drawing, so a page that does not load the font will render labels with whatever the system provides.

One canvas attribute is enough for a whole page

There is a shortcut in the API that the legacy documentation highlights, and it is the feature that makes the library usable across a page of molecules.

SmilesDrawer.apply() draws the structure for every canvas element that carries a data-smiles attribute. The example given is a canvas with data-smiles set to a cyclohexane string. No JavaScript call, no per-element wiring, no bookkeeping.

That matters for the data-heavy case, which is the case the batch playground exists for. A table of two hundred compounds becomes two hundred canvas elements with two hundred data attributes, and one call paints them all. It is the same reason the library is attractive for a documentation generator: the template emits the attribute and the drawing follows.

The Svelte example shows the explicit path, which you need when the molecule is not known at page load. The component holds a settings object with a width and a height, creates an SvgDrawer, and in an afterUpdate hook it parses the current SMILES and draws the result into a bound SVG element. The separation of parse from draw is what makes that work, since the tree can be produced once and drawn whenever the view updates.

The repository's example folder is a catalogue of these variations, with separate pages for the light theme, the SVG drawer, the SVG to canvas path, the experimental SSSR build, the old school API, a side by side layout, a reaction view, a next variant, and a drugbank example with its own CSS and JavaScript. There is also a Python notebook example, which is a useful hint about how the library gets used from a scientific Python workflow.

The example pages are also the documentation of what works. When a drawing looks wrong in your application, the fastest way to find out whether the problem is your markup or the library is to reproduce it in one of those pages.

Options are constructor arguments, and there is one runtime dependency

The options go to the constructor, and the README shows the shape:

javascript
let options = { ... };
let smilesDrawer = new SmilesDrawer.Drawer(options);

The visible part of the options table lists the drawing width at a default of 500, the drawing height at 500, and the bond thickness at 1.0, with the bond length row cut off in the visible documentation. The rest of the table is in the full documentation.

The README also says the colours of SmilesDrawer are completely configurable, which is the point for anyone rendering structures into a product with its own design system rather than into a paper figure.

The dependency list explains the colour story. The package has exactly one runtime dependency, chroma-js at version 2.4 or newer, and chroma is a colour library. So the colour configuration goes through a real colour manipulation API rather than hand-written arithmetic, and you can express things like a hue shift or a lightness ramp programmatically.

The build tooling around it is a modern TypeScript and JavaScript setup, even though the published artefact is plain JavaScript. The dev dependencies include esbuild for bundling, eslint 10 with the stylistic plugin, typescript 5.8 with the type aware linting plugin, vitest 4 for the tests, and jsdom for a DOM environment in the test run. The build itself is a node script, scripts/build.mjs, with a separate minify script and a watch script for development, and the type definitions are emitted separately with tsc --emitDeclarationOnly and shipped alongside the bundle.

That last point is what makes the package pleasant to consume from a typed project, and the exports map in the package metadata points at the type declarations for the main entry.

experimentalSSSR, and the ring systems that break the layout

The README names one experimental feature, and it is the one that matters in practice.

If you experience problems with the drawing of complex ring systems, including very long bonds, the instruction is to enable the experimentalSSSR option. SSSR is the smallest set of smallest rings, the standard way of describing the ring systems in a molecular graph, and getting that decomposition right is the hard part of a 2D layout algorithm.

The failure mode is worth understanding, because it is not random. A layout engine that miscounts the smallest rings produces a drawing that looks plausible but is chemically wrong, and the visible symptom is a bond that runs off the canvas or a ring that is drawn with the wrong number of vertices. Very long bonds make it worse, since the algorithm has to place nodes that are far apart in the graph while keeping the picture on screen.

The repository ships both variants, with example/index_experimental.html as a separate page, so you can compare the two behaviours on your own molecules rather than guessing.

The broader limitation follows from the same place. SmilesDrawer is a 2D depiction library for the browser, not a cheminformatics toolkit. It parses SMILES and draws what it parses. It does not tell you whether a structure is chemically sensible, it does not do stereochemical assignment, and it does not produce the sort of output a chemistry journal expects for a figure. For a screen, a dashboard or a teaching tool, that is exactly right. For a publication figure, it is the wrong category of tool.

Formula and stereochemistry reference suites in the test run

The test scripts are more revealing about how the project is maintained than the feature list is.

There is a single CI entry point, test:ci, which runs four directories of tests: the unit tests, the regression tests, the formula reference tests and the stereo reference tests. And there are separate scripts for the last two, test:formulae and test:stereo, so you can run just the chemistry references while iterating.

The distinction between unit and regression tests is standard, and it is the last two suites that are unusual. A formula reference suite checks the library against known molecular formulae, and a stereo reference suite checks stereochemistry handling, which is the part of SMILES most likely to break silently. Reference suites of that kind are how a chemistry library keeps its correctness claims honest, and running them in CI on every change is what makes the experimentalSSSR option a documented choice rather than folklore.

The test runner is vitest 4 with jsdom, so the tests run in a simulated DOM rather than a real browser, and the unit and regression suites are what the test:unit script runs.

The release script is worth a mention too. It runs the typedefs step and then scripts/release.mjs, and the build, minify and watch scripts are separate, so the published artefact is a bundled and minified file rather than a transpiled source tree. The dist/ folder in the repository is where the latest release lives, which is what the README means when it says you can find the latest release in the dist folder.

There is also a jsdocConfig.json at the root, so the API documentation is generated with JSDoc rather than a hand-written site, and the docs/ directory holds the pages the README links to.

Versions, the citation, and where the project actually stands

The release history is compact. v2.4.0 is dated 2026-06-24, and then v2.3.3 and v2.4.1 are both dated 2026-06-26, the latter published a few minutes after the former. The last push to the repository was on 2026-09-10.

Two versions published on the same afternoon, one of them a patch on the previous minor line and one a minor release, is the pattern of a maintainer cutting a release after a fix landed on the older branch. It is also a pattern that means the two tags are close enough in time that you should read the changelog rather than assume the patch release is older in every respect.

The README keeps a Legacy Documentation section, and it says that as of now there is full backwards compatibility. That matters for anyone following a 1.x era tutorial, because the older API, the older examples and the older documentation are all still there, with the older colour and light and dark example pages still hosted.

Those legacy examples are also a curated dataset: pages showing molecules from Drugbank, GDB-17, FDB-17, SureChEMBL and ChEMBL. For anyone evaluating the library, that is a much better test set than five hand-picked SMILES, because it covers the range of sizes and ring systems that real databases contain.

The licence is MIT in a LICENSE.md file, the package is public on npm with the name smiles-drawer, and the package metadata gives both a CommonJS entry point and an ES module entry point along with the type declarations. The repository also carries a .npmignore, a tsconfig, an eslint configuration, a vitest configuration, an app.ts, a font.svg and a readme/ directory with the images used in the README.

The honest summary is that this is an academic project with a real test suite, a real citation and a real user base in chemistry tooling, where the browser is the deployment target and the limitations are known and documented rather than hidden.

Editorial conclusion

SmilesDrawer suits anyone who needs a molecule drawn from a SMILES string inside a web page, a notebook, a documentation site or a dashboard, and who wants the drawing to happen in the browser rather than on a server that renders images. It does not suit you if you need publication grade structures, since a browser drawing library is not a cheminformatics toolkit, and it does not suit you if your molecules contain ring systems the layout engine cannot resolve without the experimental option. Check three things before you adopt it: that the structure you need draws correctly, in particular whether you need the experimentalSSSR option, that the legacy API you may have seen still works, since the README states full backwards compatibility, and that you can live with a single runtime dependency plus a bundled font requirement for consistent text rendering. The newest release is 2.4.1 from 2026-06-26 and the last push to the repository was on 2026-09-10.

Frequently asked questions

What does smiles-drawer do?

It parses SMILES strings and draws the corresponding molecular structure in the browser, with no server, no images and no templates. The README says it is a small, highly performant JavaScript component released under the MIT licence.

How do I draw a molecule with smiles-drawer?

Call SmilesDrawer.parse with the SMILES string and a callback, then pass the parsed tree to the drawer. SmilesDrawer.Drawer draws to a canvas element and SmilesDrawer.SvgDrawer draws to an SVG element, both taking a theme such as light or dark.

Is there a way to draw many molecules at once?

Yes, SmilesDrawer.apply() draws the structure for every canvas element that carries a data-smiles attribute, for example a canvas with data-smiles set to a SMILES string. The README also links a playground in batch mode.

What is experimentalSSSR and when do I need it?

It is an option to enable when you experience problems drawing complex ring systems, including very long bonds. The repository ships a separate example page for the experimental variant so the two can be compared on your own molecules.

Is the older smiles-drawer API still supported?

Yes. The README keeps a Legacy Documentation section and states that there is full backwards compatibility, with the older example pages still available, and the package exports both a CommonJS and an ES module entry point along with type declarations.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. reymond-group/smilesDrawer on GitHub
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/reymond-group-smilesdrawer.svg)](https://hysenlabs.com/projects/reymond-group-smilesdrawer)

Was this useful?