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 🙏

© 2026 – Pkg Stats / Ryan Hefner

kekule-svelte

v0.1.1

Published

Svelte 5 wrapper for Kekule.js — render and edit organic compound structures from SMILES strings

Readme

kekule-svelte

Svelte 5 wrapper for Kekule.js - render and edit organic compound structures from SMILES strings.

npm version CI License: MIT

Overview

kekule-svelte provides Svelte 5 components for rendering and editing chemical molecular structures. It wraps Kekule.js, a powerful JavaScript library for chemoinformatics, and offers:

  • Read-only 2D molecular structure viewers
  • 3D molecular structure viewers with WebGL
  • Full interactive structure editors
  • Reaction diagram rendering
  • SMILES validation and conversion utilities
  • Molecular property calculations
  • Export to SVG and PNG formats

Installation

bun add kekule-svelte
# or
npm install kekule-svelte

Quick Start

<script lang="ts">
  import { KekuleViewer } from 'kekule-svelte';
</script>

<!-- Render Aspirin -->
<KekuleViewer smiles="CC(=O)Oc1ccccc1C(=O)O" height="360px" />

Components

KekuleViewer

A read-only 2D structure viewer. Renders molecular structures from SMILES strings with optional toolbar and mouse interaction.

<KekuleViewer
  smiles="CCO"
  width="100%"
  height="360px"
  showToolbar={false}
  interactive={false}
  background="transparent"
  onReady={(viewer) => console.log('Ready:', viewer)}
  onError={(error) => console.error('Error:', error)}
/>

Props

| Prop | Type | Default | Description | | ------------- | ---------- | --------------- | ----------------------------- | | smiles | string | required | SMILES string to render | | width | string | '100%' | CSS width | | height | string | '360px' | CSS height | | showToolbar | boolean | false | Show Kekule toolbar | | interactive | boolean | false | Enable mouse pan/zoom | | background | string | 'transparent' | Canvas background color | | class | string | '' | Additional CSS classes | | onReady | function | - | Callback when viewer is ready | | onError | function | - | Callback on render failure | | loading | Snippet | - | Custom loading indicator | | error | Snippet | - | Custom error display |

Exported Methods

Use bind:this to access these methods:

<script lang="ts">
  import { KekuleViewer } from 'kekule-svelte';
  let ref = $state<any>();
</script>

<KekuleViewer smiles="CCO" bind:this={ref} />

<button onclick={() => ref?.downloadSVG('ethanol.svg')}>Download SVG</button>

| Method | Returns | Description | | ------------------- | ---------------- | -------------------------- | | getViewer() | unknown | Raw Kekule viewer instance | | exportSVG() | string \| null | SVG data URI | | exportPNG() | string \| null | PNG data URI | | downloadSVG(name) | void | Trigger SVG download | | downloadPNG(name) | void | Trigger PNG download |

KekuleEditor

A full interactive structure drawing editor powered by Kekule.js Composer. Emits SMILES on every structural change.

<script lang="ts">
  import { KekuleEditor } from 'kekule-svelte';
  let smiles = $state('');
</script>

<KekuleEditor
  smiles="c1ccccc1"
  height="480px"
  onSmiles={(s) => (smiles = s)}
  onReady={(editor) => console.log('Editor ready:', editor)}
/>

Props

| Prop | Type | Default | Description | | ---------- | ---------- | --------- | ------------------------------ | | smiles | string | '' | Initial SMILES to load | | width | string | '100%' | CSS width | | height | string | '480px' | CSS height | | class | string | '' | Additional CSS classes | | onSmiles | function | - | Callback with SMILES on change | | onChange | function | - | Callback with raw Kekule mol | | onReady | function | - | Callback when editor is ready | | loading | Snippet | - | Custom loading indicator |

Exported Methods

| Method | Returns | Description | | ------------------- | ---------------- | --------------------------------- | | getEditor() | unknown | Raw Kekule Composer instance | | getSmiles() | string \| null | Current structure as SMILES | | getMolBlock() | string \| null | Current structure as MOL block | | setSmiles(s) | void | Load new SMILES programmatically | | clear() | void | Clear the canvas | | undo() | void | Undo last action | | redo() | void | Redo last undone action | | downloadSVG(name) | void | Download current structure as SVG |

KekuleReaction

Renders a 2D reaction diagram from a reaction SMILES string.

<KekuleReaction
  reaction="CCO.CC(=O)O>>CC(=O)OCC.O"
  height="220px"
  onReady={(viewer) => console.log('Ready:', viewer)}
  onError={(error) => console.error('Error:', error)}
/>

Reaction SMILES format: reactant1.reactant2>>product1.product2 (multiple reactants or products separated by dots).

Props

| Prop | Type | Default | Description | | ------------ | ---------- | --------------- | ----------------------------- | | reaction | string | required | Reaction SMILES string | | width | string | '100%' | CSS width | | height | string | '220px' | CSS height | | background | string | 'transparent' | Canvas background color | | class | string | '' | Additional CSS classes | | onReady | function | - | Callback when viewer is ready | | onError | function | - | Callback on render failure | | loading | Snippet | - | Custom loading indicator | | error | Snippet | - | Custom error display |

Kekule3DViewer

A 3D molecular structure viewer using Kekule.js WebGL renderer. Renders molecules in 3D space with rotation and zoom controls.

<Kekule3DViewer
  smiles="CCO"
  height="400px"
  renderMode="ballAndStick"
  showToolbar={true}
  onReady={(viewer) => console.log('3D Ready:', viewer)}
  onError={(error) => console.error('Error:', error)}
/>

Props

| Prop | Type | Default | Description | | ------------- | ---------- | ---------------- | ------------------------------------------------------------- | | smiles | string | '' | SMILES string to render | | molBlock | string | '' | MOL block content (alternative) | | width | string | '100%' | CSS width | | height | string | '400px' | CSS height | | showToolbar | boolean | false | Show 3D viewer toolbar | | renderMode | string | 'ballAndStick' | Rendering mode (ballAndStick, spaceFill, wireframe, cylinder) | | background | string | 'white' | Canvas background color | | class | string | '' | Additional CSS classes | | onReady | function | - | Callback when viewer is ready | | onError | function | - | Callback on render failure | | loading | Snippet | - | Custom loading indicator | | error | Snippet | - | Custom error display |

Exported Methods

| Method | Returns | Description | | ------------------- | ---------------- | ----------------------------- | | getViewer() | unknown | Raw Kekule 3D viewer instance | | exportSVG() | string \| null | SVG data URI | | exportPNG() | string \| null | PNG data URI | | downloadSVG(name) | void | Trigger SVG download | | downloadPNG(name) | void | Trigger PNG download | | rotate(x, y, z) | void | Rotate molecule | | zoomToFit() | void | Zoom to fit molecule |

Utilities

Loader Functions

import { loadKekule, isKekuleReady } from 'kekule-svelte';

// Load Kekule.js from CDN (singleton - safe to call multiple times)
const K = await loadKekule();

// Check if already loaded
if (isKekuleReady()) {
  // Kekule.js is available
}

Kekule.js is loaded once from jsDelivr CDN when the first component mounts. Subsequent calls return the same Promise.

Property Calculations

import { getMoleculeProperties, computeLipinski, formatFormula, loadKekule } from 'kekule-svelte';

// Get molecular properties from SMILES
const K = await loadKekule();
const props = getMoleculeProperties('CCO', K);
// Returns: { formula: 'C2H6O', molecularWeight: 46.07, atomCount: 9, ... }

// Check Lipinski's Rule of Five
const lipinski = computeLipinski({ mw: 180.16, logp: 1.19, hbd: 1, hba: 4 });
// Returns: { pass: true, rules: [...] }

// Format formula with subscript characters
formatFormula('C9H8O4'); // Returns 'C\u2089H\u2088O\u2084'

Available Functions

| Function | Description | | ---------------------------------- | ----------------------------------------------- | | getMoleculeProperties(smiles, K) | Extract MW, formula, ring count from SMILES | | computeFormula(atoms) | Compute molecular formula in Hill notation | | computeMolecularWeight(atoms) | Calculate molecular weight | | computeRingCount(bonds, atoms) | Estimate ring count via Euler's formula | | computeLipinski(input) | Lipinski's Rule of Five with per-rule breakdown | | formatFormula(formula) | Convert ASCII digits to Unicode subscripts | | validateSmiles(smiles, K) | Validate SMILES string syntax | | smilesToMol(smiles, K) | Convert SMILES to MOL V2000 format | | smilesToSDF(smiles, K) | Convert SMILES to SDF format | | smilesToSmarts(smiles, K) | Convert SMILES to SMARTS pattern | | parseMolBlock(molBlock, K) | Parse MOL block and return molecule object |

SvelteKit SSR Support

For SvelteKit applications with server-side rendering, use the SSR-safe entry point:

// In a +page.svelte or +layout.svelte
<script lang="ts">
  import { onMount } from 'svelte';
  let KekuleViewer: any;

  onMount(async () => {
    // Dynamic import ensures client-side only
    const mod = await import('kekule-svelte/index-ssr');
    KekuleViewer = mod.KekuleViewer;
  });
</script>

{#if KekuleViewer}
  <svelte:component this={KekuleViewer} smiles="CCO" />
{/if}

Custom Loading and Error States

Use Svelte 5 snippets to customize loading and error displays:

<KekuleViewer smiles="CCO">
  {#snippet loading()}
    <div class="my-spinner">Loading molecule...</div>
  {/snippet}
  {#snippet error({ error })}
    <div class="my-error">Failed to render: {error}</div>
  {/snippet}
</KekuleViewer>

How It Works

kekule-svelte loads Kekule.js from jsDelivr CDN the first time a component mounts. The loader is a singleton - it returns the same Promise regardless of how many components call it:

const K1 = await loadKekule();
const K2 = await loadKekule();
console.log(K1 === K2); // true

Svelte 5 Patterns

This library uses modern Svelte 5 patterns:

| React Pattern | Svelte 5 Equivalent | | --------------------- | --------------------------------- | | useRef(null) | let el = $state() + bind:this | | useEffect([deps]) | $effect(() => { ... }) | | useEffect cleanup | Return function from onMount | | useImperativeHandle | export function getViewer() | | useState(initial) | let value = $state(initial) | | Render props | {#snippet name()}...{/snippet} |

Requirements

  • Svelte 5.0.0 or higher
  • Browser environment (Kekule.js requires DOM)

Documentation

Full documentation available at kekule-svelte.makeez.dev

License

MIT - Makeez Labs