ballistics-engine
v0.25.0
Published
High-performance ballistics trajectory engine with professional physics (WASM build)
Maintainers
Readme
ballistics-engine (WASM)
WebAssembly build of ballistics-engine, a
high-performance ballistics trajectory engine (RK4 integration, wind/Coriolis/spin-drift/Magnus
effects, custom drag tables, Monte Carlo, and more). This package exposes the same CLI-style
command surface as the native Rust binary, plus a small object-oriented Calculator class, to
JavaScript/TypeScript.
Built with wasm-pack and --no-default-features — the native crate's default pdf/online
features pull in dependencies that don't compile for wasm32-unknown-unknown, so the PDF dope-card
export and the online BC-estimation API are not available from WASM.
This package is built from
pkg/(thewasm-pack --target bundleroutput) viascripts/build-npm.shin the source repo. The same script also produces apkg-web/build (--target web) for use without a bundler — see "Browser without a bundler" below.
Install
npm install @SCOPE/ballistics-engine@SCOPE is a placeholder — see the source repo's README.md ("WASM / npm Package" section) for
the real published name once one exists.
Quick start (bundler: webpack, Vite, Rollup, Parcel)
This package's main entry imports its .wasm file as a native ES module, which is how
wasm-pack --target bundler output is meant to be consumed. It works out of the box with Vite and
Rollup (@rollup/plugin-wasm), and with webpack once experiments.asyncWebAssembly (or
experiments.syncWebAssembly) is enabled — check your bundler's WASM docs if the import fails.
import { WasmBallistics } from '@SCOPE/ballistics-engine';
const calc = new WasmBallistics();
// The command surface mirrors the native CLI (see CLI_USAGE.md in the source repo for the full
// flag reference): .308 Winchester, 168gr @ 2700 fps, zeroed at 200 yd, table out to 500 yd.
const table = calc.runCommand(
'trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500 --auto-zero 200',
);
console.log(table);Custom drag tables (loadDragTable)
Supply a measured or manufacturer-published Mach:Cd drag curve (Hornady CDM data, a Lapua/Doppler
deck, or your own) instead of a G1/G7 model + BC. Once loaded it's applied automatically to every
trajectory, zero, lead, and monte-carlo run — no extra flag needed.
const csv = 'mach,cd\n0.5,0.220\n0.8,0.230\n1.0,0.520\n1.2,0.480\n1.5,0.400\n2.0,0.330\n2.5,0.300\n';
calc.loadDragTable(new TextEncoder().encode(csv));
calc.hasDragTable(); // true
calc.runCommand('trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500');loadDragTable takes raw bytes because WASM has no filesystem access — fetch the CSV yourself
(fetch() in the browser, fs.readFileSync in Node) and pass the bytes in. The CSV format is
documented in the source repo's CLI_USAGE.md ("Custom Drag Tables"); a matching
loadBc5dTable(bytes) / hasBc5dTable() pair exists for BC5D correction tables.
Browser without a bundler
For a plain <script type="module"> page (no build step), use the pkg-web/ build instead —
produced by the same scripts/build-npm.sh, and the same build already deployed at
ballistics.sh. It ships an explicit async init() you call once before
constructing WasmBallistics:
<script type="module">
import init, { WasmBallistics } from './ballistics_engine.js';
await init(); // fetches and instantiates ballistics_engine_bg.wasm relative to this file
const calc = new WasmBallistics();
console.log(calc.runCommand('trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500'));
</script>Serve ballistics_engine.js and ballistics_engine_bg.wasm from the same directory, and make sure
your host serves .wasm with Content-Type: application/wasm (all major static hosts and CDNs do
this by default).
This pkg-web/ build is not published to npm as part of this package in the current release —
it's built locally alongside pkg/ for direct use or self-hosting. If you need it from npm, either
vendor the files from pkg-web/ yourself or publish it as a second package.
Node.js without a bundler
Plain Node import/require cannot load this package's bundler-target .wasm import directly.
Use the pkg-web/ build instead, passing the file bytes explicitly (Node's fetch() does not
support file:// URLs):
import { readFileSync } from 'node:fs';
import init, { WasmBallistics } from './pkg-web/ballistics_engine.js';
const wasmBytes = readFileSync(new URL('./pkg-web/ballistics_engine_bg.wasm', import.meta.url));
await init({ module_or_path: wasmBytes });
const calc = new WasmBallistics();
console.log(calc.runCommand('trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500'));If you need a CommonJS (require()) Node build, generate one yourself:
wasm-pack build --target nodejs --no-default-features.
Caveats
- Size: the
.wasmbinary is roughly 430 KB (about 175 KB gzipped). It is not code-split or lazily loaded — the whole engine loads up front. - Single-threaded: no SIMD/threads assumptions; no
SharedArrayBufferor cross-origin-isolation (COOP/COEP) headers required. - No filesystem/network: table loaders (
loadDragTable,loadBc5dTable) and any file-based CLI flags (e.g. native--drag-table <FILE>) need the host to fetch bytes and hand them in; seeloadDragTableabove. pdf/onlinefeatures are unavailable: this build excludes them (see above), so PDF dope-card export and the online BC-estimation API are not part of the WASM surface.- Full API surface (including the
Calculatorbuilder class) is documented in the bundled.d.ts; the full CLI flag referencerunCommandaccepts is documented in the source repo'sCLI_USAGE.md.
License
MIT OR Apache-2.0 — see LICENSE and LICENSE-APACHE in this package.
Source
https://github.com/ajokela/ballistics-engine
