This guide provides comprehensive instructions for using SwissEph WebAssembly across different platforms and frameworks.
npm install swisseph-wasmimport SwissEph from 'swisseph-wasm';
async function example() {
const swe = new SwissEph();
await swe.initSwissEph();
const jd = swe.julday(2023, 6, 15, 12.0);
const sunPos = swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
console.log(`Sun longitude: ${sunPos[0].toFixed(2)}°`);
swe.close();
}
example().catch(console.error);Works out of the box with ES modules:
// package.json should have "type": "module"
import SwissEph from 'swisseph-wasm';
async function nodeExample() {
const swe = new SwissEph();
await swe.initSwissEph();
// Your calculations here
swe.close();
}Add to your vite.config.js:
import { defineConfig } from 'vite'
export default defineConfig({
// ... your existing config
server: {
fs: { allow: ['..'] }
},
assetsInclude: ['**/*.wasm'],
optimizeDeps: {
exclude: ['swisseph-wasm']
}
})For CRA, you may need to eject or use CRACO to configure webpack for WASM support.
Add to your next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
esmExternals: true,
},
webpack: (config) => {
config.experiments = {
...config.experiments,
asyncWebAssembly: true,
};
return config;
},
};
module.exports = nextConfig;Add to your webpack.config.js:
module.exports = {
experiments: {
asyncWebAssembly: true,
},
module: {
rules: [
{
test: /\.wasm$/,
type: 'webassembly/async',
},
],
},
};<script setup>
import SwissEph from 'swisseph-wasm';
import { onMounted, onUnmounted, ref } from 'vue';
const swe = ref(null);
const isReady = ref(false);
const result = ref('');
onMounted(async () => {
try {
swe.value = new SwissEph();
await swe.value.initSwissEph();
isReady.value = true;
} catch (error) {
console.error('SwissEph initialization failed:', error);
}
});
onUnmounted(() => {
if (swe.value) {
swe.value.close();
}
});
const calculateSun = () => {
if (!isReady.value) return;
const jd = swe.value.julday(2023, 6, 15, 12.0);
const pos = swe.value.calc_ut(jd, swe.value.SE_SUN, swe.value.SEFLG_SWIEPH);
result.value = `Sun: ${pos[0].toFixed(2)}°`;
};
</script>
<template>
<div>
<button @click="calculateSun" :disabled="!isReady">
Calculate Sun Position
</button>
<p v-if="result">{{ result }}</p>
</div>
</template>import { useState, useEffect, useCallback } from 'react';
import SwissEph from 'swisseph-wasm';
function useSwissEph() {
const [swe, setSwe] = useState(null);
const [isReady, setIsReady] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
let mounted = true;
const initSwissEph = async () => {
try {
const swissEph = new SwissEph();
await swissEph.initSwissEph();
if (mounted) {
setSwe(swissEph);
setIsReady(true);
}
} catch (err) {
if (mounted) {
setError(err);
}
}
};
initSwissEph();
return () => {
mounted = false;
if (swe) {
swe.close();
}
};
}, []);
const calculate = useCallback((callback) => {
if (!isReady || !swe) return null;
return callback(swe);
}, [swe, isReady]);
return { swe, isReady, error, calculate };
}
// Usage in component
function AstrologyComponent() {
const { calculate, isReady } = useSwissEph();
const [result, setResult] = useState('');
const handleCalculate = () => {
const sunPos = calculate((swe) => {
const jd = swe.julday(2023, 6, 15, 12.0);
return swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
});
if (sunPos) {
setResult(`Sun: ${sunPos[0].toFixed(2)}°`);
}
};
return (
<div>
<button onClick={handleCalculate} disabled={!isReady}>
Calculate Sun Position
</button>
{result && <p>{result}</p>}
</div>
);
}<!DOCTYPE html>
<html>
<head>
<title>SwissEph CDN Example</title>
</head>
<body>
<div id="app">
<button id="calculate">Calculate</button>
<div id="result"></div>
</div>
<script type="module">
import SwissEph from 'https://cdn.jsdelivr.net/gh/prolaxu/swisseph-wasm@main/src/swisseph.js';
let swe = null;
// Initialize
(async () => {
try {
swe = new SwissEph();
await swe.initSwissEph();
console.log('SwissEph ready!');
} catch (error) {
console.error('Initialization failed:', error);
}
})();
// Calculate button
document.getElementById('calculate').addEventListener('click', () => {
if (!swe) return;
const jd = swe.julday(2023, 6, 15, 12.0);
const sunPos = swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
document.getElementById('result').textContent =
`Sun: ${sunPos[0].toFixed(2)}°`;
});
// Cleanup
window.addEventListener('beforeunload', () => {
if (swe) swe.close();
});
</script>
</body>
</html>Always clean up resources:
// ✅ Good
try {
const swe = new SwissEph();
await swe.initSwissEph();
// ... calculations
} finally {
swe.close(); // Always clean up
}
// ✅ Better - with error handling
async function safeCalculation() {
let swe = null;
try {
swe = new SwissEph();
await swe.initSwissEph();
return performCalculations(swe);
} catch (error) {
console.error('Calculation failed:', error);
throw error;
} finally {
if (swe) swe.close();
}
}For multiple calculations, reuse the same instance:
// ✅ Efficient
const swe = new SwissEph();
await swe.initSwissEph();
for (const date of dates) {
const jd = swe.julday(date.year, date.month, date.day, date.hour);
const sunPos = swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
// Process result
}
swe.close();Handle initialization and calculation errors:
async function robustCalculation() {
let swe = null;
try {
swe = new SwissEph();
await swe.initSwissEph();
const jd = swe.julday(2023, 6, 15, 12.0);
const result = swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
if (!result || result.length < 4) {
throw new Error('Invalid calculation result');
}
return result;
} catch (error) {
console.error('SwissEph error:', error);
throw new Error(`Astronomical calculation failed: ${error.message}`);
} finally {
if (swe) swe.close();
}
}- Forgetting to initialize: Always call
await swe.initSwissEph() - Not cleaning up: Always call
swe.close()when done - Wrong date format: Use UTC dates and proper Julian Day conversion
- Missing WASM config: Configure your bundler for WASM support
- Blocking the main thread: Use Web Workers for heavy calculations
- Documentation: DOCUMENTATION.md
- Examples: examples/
- Issues: GitHub Issues
- Quick Reference: QUICK_REFERENCE.md