{"id":12650,"library":"wanakana","title":"WanaKana: Japanese Text Conversion and Input","description":"WanaKana is a JavaScript utility library designed for detecting and transliterating Japanese text between Hiragana, Katakana, Romaji, and handling Kanji. It provides a comprehensive set of functions for checking the type of script (e.g., `isJapanese`, `isKana`, `isRomaji`), converting between them (e.g., `toKana`, `toHiragana`, `toRomaji`), and includes DOM helpers for real-time input conversion (`bind`, `unbind`). The library is currently at version 5.3.1 and maintains an active release cadence, with minor updates and bug fixes occurring every few months. Its key differentiators include robust input method editor (IME) simulation capabilities for HTML text fields, comprehensive handling of various kana and romaji mapping rules, and support for custom mappings. WanaKana ships with TypeScript definitions, making it highly compatible with modern TypeScript-driven web development workflows.","status":"active","version":"5.3.1","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/WaniKani/WanaKana","tags":["javascript","english","japanese","hiragana","katakana","kana","romaji","conversion","transliteration","typescript"],"install":[{"cmd":"npm install wanakana","lang":"bash","label":"npm"},{"cmd":"yarn add wanakana","lang":"bash","label":"yarn"},{"cmd":"pnpm add wanakana","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library primarily uses named exports. A default import (`import wanakana from 'wanakana'`) will not provide all utility functions.","wrong":"import wanakana from 'wanakana';","symbol":"wanakana","correct":"import * as wanakana from 'wanakana';"},{"note":"Prefer named ESM imports for modern JavaScript environments. CommonJS `require` works but is discouraged for new projects.","wrong":"const { toKana, isRomaji } = require('wanakana');","symbol":"toKana, isRomaji","correct":"import { toKana, isRomaji } from 'wanakana';"},{"note":"These DOM helper functions are available as named exports. Ensure `wanakana` is properly imported before attempting to use them.","wrong":"wanakana.bind(element); // If wanakana was not imported correctly","symbol":"bind, unbind","correct":"import { bind, unbind } from 'wanakana';"},{"note":"For browser usage without a build step, WanaKana exposes a global `wanakana` object after loading the UMD bundle from unpkg or similar CDN.","symbol":"Wanakana (global)","correct":"<script src=\"https://unpkg.com/wanakana\"></script>\n<script>wanakana.toKana('...');</script>"}],"quickstart":{"code":"import { toKana, toHiragana, toRomaji, isJapanese, bind, unbind } from 'wanakana';\n\n// Convert Romaji to Hiragana and Katakana\nconst romajiInput = 'konnichiwa sekai';\nconst hiragana = toHiragana(romajiInput); // 'こんにちわせかい'\nconst katakana = toKatakana(romajiInput); // 'コンニチワセカイ'\n\nconsole.log(`Romaji: \"${romajiInput}\"`);\nconsole.log(`  -> Hiragana: \"${hiragana}\"`);\nconsole.log(`  -> Katakana: \"${katakana}\"`);\n\n// Check if a string contains Japanese characters\nconst japaneseText = '日本語を勉強します';\nconst containsJapanese = isJapanese(japaneseText); // true\nconsole.log(`\"${japaneseText}\" contains Japanese: ${containsJapanese}`);\n\n// Demonstrating DOM binding (browser environment required)\n// This part will only execute if 'document' is defined.\nif (typeof document !== 'undefined') {\n  const inputElement = document.createElement('input');\n  inputElement.type = 'text';\n  inputElement.id = 'wanakana-demo-input';\n  document.body.appendChild(inputElement);\n\n  console.log('Appended a demo input element to the document body.');\n\n  // Bind wanakana for real-time Romaji to Kana conversion\n  bind(inputElement, { IMEMode: true });\n\n  console.log('WanaKana is bound to the input element. Type romaji to convert to kana.');\n\n  // Simulate user input (programmatically)\n  inputElement.value = 'nihongo';\n  inputElement.dispatchEvent(new Event('input', { bubbles: true }));\n\n  // In a real browser, inputElement.value would now be 'にほんご'\n  // For console, we'll log what it *should* be:\n  console.log(`Simulated input 'nihongo'. Expected input value after conversion: 'にほんご'. Current value (may not reflect live conversion in Node): ${inputElement.value}`);\n\n  // Clean up\n  unbind(inputElement);\n  document.body.removeChild(inputElement);\n  console.log('WanaKana unbound and input element removed.');\n} else {\n  console.log('Skipping DOM binding example as `document` is not defined (likely a Node.js environment).');\n}","lang":"typescript","description":"This quickstart demonstrates basic Romaji to Hiragana/Katakana conversion, checks for Japanese text, and illustrates how to bind WanaKana to a DOM input element for real-time conversion."},"warnings":[{"fix":"Review calls to `stripOkurigana()` and update options according to the new API. For example, to strip all kana, use `[...text].filter(isKana)` manually.","message":"The `stripOkurigana()` function's options were changed significantly in v4.0.0. The `{ all: Boolean }` option was removed and replaced with `{ leading: Boolean, matchKanji: String }`.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Update any logic that relies on the previous classification of `々`, especially in custom character type detection or processing pipelines.","message":"In v5.2.0, the `々` (iteration mark) character was reclassified. It is now included in `isKanji()` checks and explicitly excluded from Japanese punctuation checks.","severity":"breaking","affected_versions":">=5.2.0"},{"fix":"Ensure that your application explicitly manages custom mapping states, passing the desired mapping every time if it might change, rather than relying on a potentially stale or implicitly set mapping.","message":"Starting from v5.0.0, providing `customKanaMapping` or `customRomajiMapping` in conversion options will always replace any existing custom mapping if different. Previously, it would only replace if no custom mapping was already set.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"Ensure `bind()` is called only once per element. If you need to re-bind with new options, `unbind()` first. Review applications for any dependencies on attributes `unbind()` might have previously left untouched.","message":"In v5.1.0, `bind()` was fixed to prevent binding the same element multiple times, and `unbind()` now removes only the attributes that were specifically added by WanaKana. This might affect applications that relied on `unbind()` leaving certain attributes or allowed multiple `bind()` calls on the same element.","severity":"gotcha","affected_versions":">=5.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Use `import { toKana } from 'wanakana';` for specific functions or `import * as wanakana from 'wanakana';` to import all named exports under a namespace.","cause":"Attempting to call `toKana` on a `wanakana` object that was imported incorrectly, often via `import wanakana from 'wanakana'` instead of `import * as wanakana from 'wanakana'` or named imports.","error":"TypeError: wanakana.toKana is not a function"},{"fix":"For browser use without a bundler, ensure `<script src=\"https://unpkg.com/wanakana\"></script>` is in your HTML. For module environments, ensure you have `import * as wanakana from 'wanakana';` or appropriate named imports.","cause":"The `wanakana` global object is not available, typically because the UMD bundle was not loaded in a browser environment, or the library was not correctly imported in a module environment.","error":"ReferenceError: wanakana is not defined"},{"fix":"Verify that the DOM element you are passing to `bind()` actually exists and is not `null` or `undefined`. Also, confirm that `wanakana` has been correctly imported and is accessible in the current scope.","cause":"This usually occurs when `wanakana.bind()` is called with an `undefined` or null DOM element, or when `wanakana` itself is not properly imported/defined, leading to `wanakana` being `undefined`.","error":"TypeError: Cannot read properties of undefined (reading 'bind')"}],"ecosystem":"npm"}