title: JavaScript client
Using Bareun from JavaScript and TypeScript
With the npm package bareun, you can use morphological analysis, spelling and grammar correction, homonym sense disambiguation,
and Urimalsaem phoneme search (Urimalsaem is the NIKL Open Korean Dictionary).
- Repository: bareun-js
- Current version: 2.0.0
- Node 18 or higher, and browsers
2.0.0 is being prepared for release
It has not been published to npm yet. Until then, get the repository, run
pnpm build, and reference it locally.
The already released 1.1.0 supports only morphological analysis and the custom dictionary, and is Node only. Spelling and grammar correction, sense disambiguation, phoneme search, and browser support are available from 2.0.0.
Installation
npm install bareun
Type definitions are included, so you can use it directly in TypeScript.
Prerequisites
- A running Bareun server. The default port is 5658 for a local installation and 5656 for Docker.
- An API key. It starts with
koba-. How to get one
Spelling and grammar correction and Urimalsaem phoneme search work only on a server that includes the spell-check feature.
Morphological analysis
import { createBareunClient, Tagger } from "bareun";
const client = createBareunClient({
apiKey: "koba-...",
host: "localhost",
port: 5656,
});
const t = await new Tagger(client).tag("아버지가 방에 들어가신다.");
t.pos(); // ["아버지/NNG", "가/JKS", "방/NNG", "에/JKB", "들어가/VV", ...]
t.morphs(); // ["아버지", "가", "방", "에", "들어가", "시", "ㄴ다", "."]
t.nouns(); // ["아버지", "방"]
t.verbs(); // ["들어가"]
When connecting to the cloud, give the whole address.
createBareunClient({ apiKey: "koba-...", baseUrl: "https://api.bareun.ai" });
In the browser
The server handles CORS itself, so you can call it without a proxy.
On public pages, the API key is exposed
The key goes into the bundle as is. For a public service, set up a server and call Bareun from there. It is convenient for internal tools and prototypes.
Position information
Requests are sent with UTF-16 offsets. JavaScript strings are UTF-16, so you can put the
positions the server returns straight into slice.
const span = t.response.sentences[0].tokens[0].text;
text.slice(span.beginOffset, span.beginOffset + span.length); // "아버지가"
Custom dictionary
const tagger = new Tagger(client, ["mydict"]);
Create and delete dictionaries with client.customDictionary. If you give several, the one that comes first
takes priority. See the Custom dictionary API.
Spelling and grammar correction
import { Corrector } from "bareun";
const c = new Corrector(client);
await c.correct("이거 안되요. 학교에 갔읍니다.");
// "이거 안되요. 학교에 갔습니다."
for (const ch of await c.changes("이거 안되요. 학교에 갔읍니다.")) {
console.log(`${ch.origin} → ${ch.revised} (${ch.category})`);
}
// 갔읍니다. → 갔습니다. (STANDARD)
beginOffset and length are also based on JavaScript strings, so you can use them directly with slice.
To see nested corrections or the help (explanation) too, get the server response as is with c.raw(text).
For details, see the Spell check API.
Homonym sense disambiguation
const t = await tagger.tag("나는 밤에 밤을 먹었다.", { withSense: true });
for (const s of t.senses()) {
console.log(`${s.morph}/${s.tag} ${s.senseNo} ${s.meaning}`);
}
// 밤/NNG 2 밤나무의 열매. ...
// 먹/VV 2 음식 따위를 입을 통하여 뱃속에 들여보내다.
Morphemes that carry no meaning, such as particles and endings, are not given a sense to begin with, so most morphemes do not appear in the result. See the Homonym sense disambiguation API.
Urimalsaem phoneme search
import { DictSearchAnchor } from "bareun";
const res = await client.dictSearch.searchDict({
pattern: "{ㅅ//ㄴ}다",
pos: ["동사"],
});
res.entries.map((e) => e.word); // ["신다"]
const suffix = await client.dictSearch.searchDict({
pattern: "아지",
anchor: DictSearchAnchor.SUFFIX,
limit: 5,
});
suffix.entries.map((e) => e.word); // ["아지", "가아지", "강아지", "개아지", "갱아지"]
For the pattern syntax, see the Urimalsaem phoneme search API.
Error handling
import { Code, isBareunError, describeError } from "bareun";
try {
await tagger.tag("문장");
} catch (e) {
if (isBareunError(e)) {
if (e.code === Code.PermissionDenied) console.error("Check your API key");
else console.error(describeError(e));
}
}
| Code | When |
|---|---|
Unavailable | Could not reach the server. Address typo, server not running, CORS |
PermissionDenied | The API key is invalid or the license has expired |
Unimplemented | A feature the server does not provide |
ResourceExhausted | Usage limit exceeded |
describeError(e) returns a Korean sentence that adds what you should check.
Moving over from 1.x
2.0.0 is not compatible with 1.x.
| 1.x | 2.0.0 |
|---|---|
@grpc/grpc-js, .proto parsing at run time | Connect, prebuilt types |
| Node only | Node 18+ and browsers |
| No types | Written in TypeScript, .d.ts included |
| CommonJS only | Both ESM and CJS |
| Morphological analysis, custom dictionary | + correction, sense disambiguation, phoneme search |
Features this library does not wrap
client.language, client.revision, client.dictSearch, and client.customDictionary
expose every method of the server as is. The request and response types are exported too.
import { EncodingType } from "bareun";
await client.language.analyzeSyntaxRaw({
document: { content: "문장", language: "ko_KR" },
encodingType: EncodingType.UTF16,
});
Frequently asked questions
Q. Can I use it directly in the browser? A. It works. The server handles CORS itself, so no proxy is needed. However, on a public page the API key is exposed in the bundle, so set up a server and call from there.
Q. Can I use it on Node 16?
A. It needs the global fetch, so we recommend Node 18 or higher. On 16, it may work if you
pass in a fetch implementation yourself (createBareunClient({ fetch })).
Q. Can I use it with plain JavaScript, without TypeScript?
A. Yes. It exports both ESM and CommonJS, so you can use it with both import and require.