A production-ready Vite-based application that embeds the Ketcher chemical structure editor with full iframe communication support. Demo at ketcher.mireklzicar.com
- βοΈ React 19 + TypeScript + Vite
- π§ͺ Ketcher 3.2.0 chemical structure editor
- π Full iframe communication via postMessage API
- ποΈ Standalone mode (no backend required)
- π± Responsive design
- π Production-ready build
- π± Fixed touch screen keyboard trigger on mobile devices
This project embeds and redistributes Ketcher β an open-source, web-based chemical structure editor developed and maintained by EPAM Life Sciences.
-
GitHub Repository: github.com/epam/ketcher
-
Documentation & Website: lifescience.opensource.epam.com/ketcher
-
License: Apache License 2.0
-
Acknowledgments and attributions: NOTICE
This project is not affiliated with or endorsed by EPAM Systems. It is an independent deployment and integration of Ketcher (version 3.2.0) with a custom iframe communication layer and self-hosted enhancements.
If you use this project in your research or work, please cite both this repository and the original Ketcher project:
@misc{ketcher-docker,
title = {Ketcher Docker - Chemical Structure Editor Docker Deployment},
author = {Miroslav LΕΎiΔaΕ},
year = {2025},
howpublished = {\url{https://github.com/miroslav-lzicar/ketcher-docker}},
note = {Accessed: 2025-06-07}
}@misc{ketcher,
title = {Ketcher: Web-based Chemical Structure Editor},
author = {{EPAM Systems}},
year = {2025},
howpublished = {\url{https://github.com/epam/ketcher}},
note = {Accessed: 2025-06-07}
}# Install dependencies
pnpm install
# Start development server
pnpm devThe app will be available at http://localhost:5173
# Build for production
pnpm build
# Preview production build
pnpm preview# Build and run with Docker
docker build -t ketcher-docker-app .
docker run -d -p 8080:80 --name ketcher-app ketcher-docker-app
# Access at http://localhost:8080<iframe
id="ketcher-iframe"
src="http://localhost:5173/"
width="800"
height="600"
title="Ketcher Chemical Editor">
</iframe>The Ketcher iframe communicates via postMessage. All communication is bidirectional and asynchronous.
const iframe = document.getElementById('ketcher-iframe');
// Set a molecule from SMILES
iframe.contentWindow.postMessage({
type: 'setMolecule',
payload: 'CCO' // SMILES string
}, '*');
// Get current SMILES
iframe.contentWindow.postMessage({
type: 'getSmiles'
}, '*');
// Clear the editor
iframe.contentWindow.postMessage({
type: 'clear'
}, '*');window.addEventListener('message', (event) => {
const { type, payload, smiles } = event.data;
switch (type) {
case 'init':
console.log('Ketcher initialized');
break;
case 'smiles':
console.log('SMILES received:', payload);
break;
case 'smiles-update':
console.log('SMILES updated:', smiles);
break;
case 'moleculeSet':
console.log('Molecule set successfully');
break;
case 'cleared':
console.log('Editor cleared');
break;
case 'error':
console.error('Ketcher error:', event.data.error);
break;
}
});setMolecule/set-molecule: Set molecule from SMILESgetSmiles/get-smiles: Request current SMILESclear: Clear the editor
init: Ketcher initialized and readysmiles: Response to getSmiles requestsmiles-update: Automatic SMILES updates when structure changesmoleculeSet: Confirmation that molecule was setcleared: Confirmation that editor was clearederror: Error occurred during operation
VITE_API_PATH: Custom API endpoint (fallback for remote mode)PUBLIC_URL: Base URL for static resources
The application is configured to allow iframe embedding from any origin. For production, consider restricting origins in vite.config.ts:
server: {
headers: {
'Access-Control-Allow-Origin': 'https://yourdomain.com',
// ... other headers
},
}The application is designed to be deployed as a static site. It includes:
- Standalone Ketcher service (no backend required)
- Optimized production build
- Proper CORS headers for iframe embedding
- Error handling and fallbacks
This project includes a complete Docker setup for production deployment with proper iframe support and CORS configuration.
# Build the Docker image
docker build -t ketcher-docker-app .
# Run the container
docker run -d -p 8080:80 --name ketcher-app ketcher-docker-app
# Access the application
# http://localhost:8080The Docker setup includes:
- Multi-stage build: Uses Node.js Alpine for building and Nginx Alpine for serving
- Optimized nginx configuration: Custom
nginx.confwith SPA routing support - Iframe-friendly: Removes X-Frame-Options to allow cross-origin iframe embedding
- CORS enabled: Configured for cross-origin access
- Asset optimization: Gzip compression and caching for static files
- Proper permissions: Handles file ownership and permissions correctly
Dockerfile- Multi-stage build configurationnginx.conf- Production nginx configuration with iframe support.dockerignore- Excludes development files and handles macOS compatibility
- Iframe Support: Full cross-origin iframe embedding capability
- SPA Routing: Proper handling of React Router routes
- Security Headers: Optimized security headers (except X-Frame-Options for iframe support)
- Performance: Gzip compression, asset caching, and optimized delivery
π Live Demo: https://ketcher-docker-e78uoiplu-miroslav-lzicars-projects.vercel.app
The application has been successfully deployed to Vercel with optimized configuration for iframe embedding and CORS support.
The project includes a vercel.json configuration file with:
- Framework Detection: Automatically detected as Vite
- Build Command:
pnpm build - Output Directory:
dist - CORS Headers: Configured for cross-origin iframe embedding
- SPA Routing: Proper handling of React Router routes
# Install Vercel CLI (if not already installed)
npm i -g vercel
# Deploy to production
vercel --prodOr deploy the static build directly:
pnpm build
# Upload dist/ folder to Vercel dashboardThe built application in dist/ can be deployed to any static hosting service (Vercel, Netlify, AWS S3, etc.). For iframe embedding, ensure your hosting platform allows:
- Custom headers configuration
- Cross-origin resource sharing (CORS)
- Removal of X-Frame-Options header
src/
βββ App.tsx # Main Ketcher component with iframe communication
βββ utils.ts # Ketcher service provider setup
βββ main.tsx # Application entry point
βββ index.css # Global styles
βββ types
β βββ ketcher-standalone.d.ts # Ketcher type definitions
βββ vite-env.d.ts # Vite type definitions
- App.tsx: Contains all iframe communication logic and Ketcher initialization
- utils.ts: Handles Ketcher standalone service provider setup
- vite.config.ts: Build configuration with CORS headers
