npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

markdown-it-smiles

v2.0.0

Published

A markdown-it plugin for rendering SMILES (Simplified molecular input line entry specification) chemical structures

Readme

markdown-it-smiles

Codacy Badge Codacy Badge

A markdown-it plugin for rendering chemical structures from SMILES notation using smilesDrawer.

🌐 Live Demo

View Interactive Demo →

Try the plugin live with interactive examples showcasing all features!

Features

  • 🧪 Block-level SMILES rendering with customizable options
  • 🔬 Inline SMILES rendering for seamless integration in text
  • 🚀 Dual rendering strategies: Parse-time (Node.js) or Display-time (Browser)
  • 🖼️ High-quality image output with Sharp.js integration (Node.js only)
  • ⚙️ JSON5 configuration for flexible option syntax
  • 🛡️ Enhanced error handling with custom callbacks and fallback images
  • 🎨 Responsive design with improved mobile support
  • 📦 Environment-specific builds for optimal performance
  • 🔧 Granular configuration with separate options for block/inline rendering
  • 📱 Cross-platform compatibility (Browser & Node.js)

Installation

npm install markdown-it-smiles

Usage

Basic Setup

import MarkdownIt from 'markdown-it';
import { MarkdownItSmiles } from 'markdown-it-smiles';

const md = new MarkdownIt().use(MarkdownItSmiles);

const result = md.render(`
# Chemical Structure

\`\`\`smiles
CCO
\`\`\`

The molecule $smiles{CCO} is ethanol.
`);

Advanced Configuration

import MarkdownIt from 'markdown-it';
import { MarkdownItSmiles } from 'markdown-it-smiles';

const md = new MarkdownIt().use(MarkdownItSmiles, {
  // Render immediately during parsing (Node.js only)
  renderAtParse: true,
  
  // Output format: 'svg' or 'img'
  format: 'svg',
  
  // Separate configuration for different contexts
  smilesDrawerOptions: {
    default: {
      width: 400,
      height: 300,
      theme: 'light'
    },
    inline: {
      width: 100,
      height: 100
    },
    block: {
      width: 500,
      height: 400,
      bondThickness: 0.8
    }
  },
  
  // Error handling (renderAtParse only)
  errorHandling: {
    onError: (err) => console.error('SMILES error:', err),
    fallbackImage: '/images/error-molecule.png'
  }
});

Browser Usage

<!DOCTYPE html>
<html>
<head>
    <title>SMILES Demo</title>
</head>
<body>
    <iframe id="content"></iframe>
    
    <script type="module">
        import MarkdownIt from 'https://esm.sh/markdown-it@14';
        import { MarkdownItSmiles } from 'https://esm.sh/markdown-it-smiles@2';
        
        const md = new MarkdownIt().use(MarkdownItSmiles, {
          // Browser environment: only display-time rendering supported
          smilesDrawerOptions: {
            default: { width: 300, height: 250 }
          }
        });
        
        const html = md.render(`
# Molecules
The molecule $smiles{CCO} is ethanol.

\`\`\`smiles {"width": 400}
c1ccccc1
\`\`\`
        `);
        
        document.getElementById('content').srcdoc = html;
    </script>
</body>
</html>

Rendering Strategies

Display-time Rendering (Default)

  • When: HTML includes smiles-drawer script, renders when displayed in browser
  • Where: Both Node.js and Browser environments
  • Benefits: Smaller HTML output, client-side processing
  • Usage: Set renderAtParse: false (default) or omit the option
const md = new MarkdownIt().use(MarkdownItSmiles, {
  renderAtParse: false // Default behavior
});

Parse-time Rendering (Node.js Only)

  • When: SMILES rendered immediately during markdown parsing
  • Where: Node.js environment only
  • Benefits: Pre-rendered images/SVG embedded in HTML, no client-side dependencies
  • Usage: Set renderAtParse: true
const md = new MarkdownIt().use(MarkdownItSmiles, {
  renderAtParse: true, // Renders during parsing
  format: 'svg', // or 'img' for PNG
  errorHandling: {
    onError: (err) => console.error(err),
    fallbackImage: '/error.png'
  }
});

Syntax

Block SMILES

Use fenced code blocks with the smiles language identifier:

```smiles
CCO
```

With JSON5 Options

You can specify rendering options using JSON5 syntax:

```smiles {width: 500, height: 400, bondThickness: 1.0}
C1CCCCC1
```

Advanced Block Configuration

```smiles {
  width: 600,
  height: 450,
  theme: 'dark',
  terminalCarbons: true,
  explicitHydrogens: false,
  atomVisualization: 'balls'
}
CC(C)CCCC(C)C1CCC2C1(CCC3C2CC=C4C3(CCC(C4)O)C)C
```

Inline SMILES

Use the $smiles{...} syntax for inline rendering:

The molecule $smiles{CCO} is ethanol, while $smiles{c1ccccc1} is benzene.

Inline with Options

Large inline molecule: $smiles{CN1C=NC2=C1C(=O)N(C(=O)N2C)C}{width: 200, height: 150}

Configuration Options

Plugin Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | renderAtParse | boolean | false | Render during parsing (Node.js only) | | format | string | 'svg' | Output format: 'svg' or 'img' | | fontUrl | string | - | Custom font URL for rendering | | smilesDrawerScript | string | CDN URL | Custom smiles-drawer script URL | | smilesDrawerOptions | object | {} | SmilesDrawer configuration | | errorHandling | object | - | Error handling options (renderAtParse only) |

SmilesDrawer Options

These options can be specified in smilesDrawerOptions.default, smilesDrawerOptions.block, smilesDrawerOptions.inline, or in block/inline SMILES directly:

| Option | Type | Default | Description | |--------|------|---------|-------------| | width | number | 500 | Canvas width in pixels | | height | number | 500 | Canvas height in pixels | | bondThickness | number | 0.6 | Thickness of chemical bonds | | bondLength | number | 15 | Length of chemical bonds | | shortBondLength | number | 0.85 | Short bond length ratio | | bondSpacing | number | 2.7 | Spacing between double bonds | | atomVisualization | string | 'default' | 'default', 'balls', or 'none' | | fontSizeLarge | number | 6 | Large font size for elements | | fontSizeSmall | number | 4 | Small font size for numbers | | padding | number | 20.0 | Canvas padding | | terminalCarbons | boolean | false | Show terminal carbons (CH3) | | explicitHydrogens | boolean | false | Show explicit hydrogens | | compactDrawing | boolean | true | Use compact drawing mode | | isometric | boolean | true | Draw isometric SMILES | | theme | string | 'light' | Color theme: 'light' or 'dark' | | experimental | boolean | false | Enable experimental features | | debug | boolean | false | Draw debug information |

Theme Configuration

const md = new MarkdownIt().use(MarkdownItSmiles, {
  smilesDrawerOptions: {
    default: {
      theme: 'dark',
      themes: {
        custom: {
          C: '#ffffff',
          O: '#ff6b6b',
          N: '#4ecdc4',
          // ... other atom colors
          BACKGROUND: '#2c3e50'
        }
      }
    }
  }
});

Examples

Basic Molecules

# Basic Molecules

Water: $smiles{O}
Methane: $smiles{C}
Ethanol: $smiles{CCO}

## Ethanol Structure
```smiles
CCO
```

Organic Compounds

# Organic Chemistry

## Aromatic Compounds

Benzene:
```smiles {width: 300, height: 250, theme: 'light'}
c1ccccc1
```

Toluene: $smiles{Cc1ccccc1}

## Complex Ring Systems
```smiles {
  width: 500, 
  height: 400, 
  bondThickness: 0.8,
  terminalCarbons: true
}
CC12CCC3C(C1CCC4=CC(=O)CCC34C)CCC5=C2C=CC(=C5)O
```

Pharmaceutical Compounds

# Drug Molecules

## Aspirin (Parse-time rendering)
```smiles {width: 400, height: 300}
CC(=O)OC1=CC=CC=C1C(=O)O
```

## Caffeine with options
```smiles {
  width: 350,
  height: 280,
  atomVisualization: 'balls',
  explicitHydrogens: true
}
CN1C=NC2=C1C(=O)N(C(=O)N2C)C
```

Ibuprofen: $smiles{CC(C)CC1=CC=C(C=C1)C(C)C(=O)O}{width: 180}

Stereochemistry Examples

# Stereochemistry

L-Alanine: $smiles{N[C@@H](C)C(=O)O}
D-Glucose: $smiles{C([C@@H]1[C@H]([C@@H]([C@H](C(O1)O)O)O)O)O}

## Cholesterol
```smiles {width: 600, height: 450, compactDrawing: false}
CC(C)CCCC(C)C1CCC2C1(CCC3C2CC=C4C3(CCC(C4)O)C)C
```

Environment Support

Node.js Environment

  • Uses dist/node build
  • Supports both rendering strategies
  • Full feature set including error handling
  • Requires Node.js dependencies: jsdom, sharp, deasync

Browser Environment

  • Uses dist/browser build
  • Display-time rendering only
  • Automatic script injection
  • No server-side dependencies

SMILES Notation

SMILES (Simplified molecular input line entry specification) is a specification for describing chemical molecule structures using ASCII strings:

Basic Examples:

  • C - Methane
  • CC - Ethane
  • CCO - Ethanol
  • C=O - Formaldehyde
  • C#N - Hydrogen cyanide

Ring Structures:

  • C1CCCCC1 - Cyclohexane
  • c1ccccc1 - Benzene (aromatic)
  • c1ccncc1 - Pyridine

Complex Molecules:

  • CC(=O)O - Acetic acid
  • CN1C=NC2=C1C(=O)N(C(=O)N2C)C - Caffeine
  • CC(C)CC1=CC=C(C=C1)C(C)C(=O)O - Ibuprofen

For comprehensive SMILES documentation, visit Daylight Chemical Information Systems.

Browser Compatibility

  • Chrome 85+
  • Firefox 78+
  • Safari 14+
  • Edge 85+

Dependencies

Core Dependencies

Node.js Dependencies (for renderAtParse)

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for a detailed history of changes.

Acknowledgments

  • smilesDrawer for excellent chemical structure rendering
  • markdown-it for the extensible markdown parser
  • The chemistry community for SMILES notation standards

Related Projects

  • smilesDrawer - JavaScript library for drawing chemical structures
  • markdown-it - Markdown parser with plugin support
  • RDKit - Cheminformatics toolkit
  • OpenEye - Chemical information management

Made with ❤️ for the chemistry and web development communities.