disarm for Node.js¶
Node.js bindings wrap the pure-Rust disarm core (no Python) via
napi-rs. Prebuilt native addons install with no local Rust
toolchain, and the package ships TypeScript types — no @types/disarm needed.
Install¶
npm install disarm
Requires Node 14+. npm install disarm pulls a prebuilt platform binary
(Linux x64/arm64, macOS x64/arm64, Windows x64) when one is available.
Quick start¶
Options are passed as an object; scheme/target tokens are typed string unions. The two operations people most often confuse are visual confusable folding (homoglyph defence) and phonetic transliteration (romanization) — see Which function do I want?.
import {
normalizeConfusables,
transliterate,
slugify,
isSuspiciousHostname,
} from 'disarm'
// Visual (TR39) confusable folding — homoglyph defence
normalizeConfusables('раypal') // => 'paypal'
// Phonetic romanization — readable ASCII, NOT a security control.
// A language profile sharpens the output: the uk profile gives Київ → Kyiv.
transliterate('Київ', { lang: 'uk' }) // => 'Kyiv'
slugify('Héllo Wörld') // => 'hello-world'
// Hostname / IDN spoof check (a false result is not a safety guarantee)
isSuspiciousHostname('pаypal.com') // => true
Errors¶
Bad input — an unknown scheme/target/form/platform token, etc. — throws
DisarmInvalidArgument, a subclass of DisarmError, so a single
instanceof DisarmError catches the whole surface:
import { transliterate, DisarmError, DisarmInvalidArgument } from 'disarm'
try {
transliterate('x', { scheme: 'klingon' })
} catch (e) {
if (e instanceof DisarmInvalidArgument) console.warn(e.message) // also an instanceof DisarmError
}
TypeScript¶
Every export is fully typed and the token arguments are string unions, so your editor completes and checks them:
import { transliterate, type Scheme } from 'disarm'
const scheme: Scheme = 'strict_iso9' // 'default' | 'strict_iso9' | 'gost7034'
transliterate('Юрий', { scheme }) // → 'Jurij'
Where next¶
- Node API reference — the full call surface, every function with a runnable example.
- Concepts (shared across every language) — start with Which function do I want?, then the topic guides under Guide in the sidebar.
- The binding inherits the core's guarantees and limits verbatim — read the Threat Model before relying on it in a security context.