Installation

hama publishes two packages: hama (Python) and hama-js (TypeScript). Both ship with embedded .hama weight packages, so no follow-up downloads are required.

Subpath exports: hama-js/g2p, hama-js/asr, hama-js/p2g, hama-js/g2p/browser, hama-js/asr/browser, hama-js/p2g/browser, hama-js/browser, hama-js/jamo, and hama-js/tokenizer.

Install from a package registry

uv pip install hama==1.7.0
# or
pip install hama==1.7.0

Verify the Python install with python -c “from hama import G2PModel; print(G2PModel().predict(‘안녕하세요’).ipa)”.

For live microphone ASR examples in Python, install the optional extra with uv pip install ‘hama[live]==1.7.0’.

Node / Bun

Save this as example.mjs. Bun handles the package’s JSON imports directly. The published 1.7.0 Node modules omit JSON import attributes, so running them directly with Node fails with ERR_IMPORT_ATTRIBUTE_MISSING. For Node, bundle the script and copy the runtime assets beside the output.

import { G2PNodeModel } from "hama-js/g2p";

const model = await G2PNodeModel.create();
console.log((await model.predict("안녕하세요")).ipa);

Browser setup (Vite / Astro)

Import browser classes from hama-js/browser or a modality’s /browser export in client-side code. The root and Node exports use node:fs. Version 1.7.0 imports JSON without import attributes, so its published browser modules need a bundler that handles JSON; a bare HTML module script cannot import them directly. Bare package names also require a bundler or import map.

From your project root, copy the weights into the public directory. Repeat after upgrading hama-js. These examples assume the site is served at /; prefix URLs with your deployment base path when needed.

mkdir -p public/hama-assets
cp node_modules/hama-js/dist/browser/assets/*.hama public/hama-assets/

Exclude browser entries from Vite dependency pre-bundling so asset resolution stays in Vite’s normal build pipeline. Use the Vite config below, or merge the same optimizeDeps object into vite in your Astro config.

import { defineConfig } from "vite";

export default defineConfig({
optimizeDeps: {
  exclude: [
    "hama-js/browser",
    "hama-js/g2p/browser",
    "hama-js/asr/browser",
    "hama-js/p2g/browser",
  ],
},
});

Vite bundles the default vocabularies and resolves the engine’s hama.wasm asset. No wasmUrl option exists in 1.7.0. Alternatively, use a separate literal new URL(”…/encoder.hama”, import.meta.url) for each weight, with a path relative to your source file. Avoid a dynamic filename helper.

Webpack and Next do not use optimizeDeps. Configure their client build to handle the package’s JSON imports and emit hama.wasm at the URL resolved by engine.browser.js. Explicit weight URLs alone do not fix the engine URL. In Next, load and create browser models on the client, such as inside an effect. Check both development and production asset requests when using another bundler.

Local development

These commands use the current repository source. Building the TypeScript engine requires Zig 0.16+.

git clone https://github.com/hamanlp/hama.git
cd hama/python
uv sync --extra test
uv run pytest

Notes

Python 3.9+ and Node 18+ (or Bun 1.1+) are recommended. Python installs include the model weights (and the native engine) inside the wheel; TypeScript installs ship the same .hama weights plus hama.wasm in dist/.

G2P uses split weights by default (encoder.hama + decoder_step.hama), run by a self-contained engine — no onnxruntime.

Versioning

hama and hama-js are versioned and released together. These examples target version 1.7.0.