---
title: @streamdown/cjk
description: Improved handling of Chinese, Japanese, and Korean text.
type: reference
summary: Proper emphasis formatting and autolink handling for CJK text.
prerequisites:
  - /docs/plugins
related:
  - /docs/typography
---

# @streamdown/cjk



The `@streamdown/cjk` plugin improves handling of CJK (Chinese, Japanese, Korean) text with proper emphasis formatting and autolink handling. This is particularly important for AI-generated content, where language models naturally place emphasis markers around phrases that include or end with punctuation.

* Correct emphasis formatting near ideographic punctuation (bold, italic, strikethrough)
* Splits autolinks at CJK punctuation boundaries to prevent URLs from swallowing trailing punctuation
* Uses `remark-cjk-friendly` and `remark-cjk-friendly-gfm-strikethrough` for proper parsing

## Install

<CodeBlockTabs defaultValue="npm">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="yarn">
      yarn
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```bash
    npm install @streamdown/cjk
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```bash
    pnpm add @streamdown/cjk
    ```
  </CodeBlockTab>

  <CodeBlockTab value="yarn">
    ```bash
    yarn add @streamdown/cjk
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```bash
    bun add @streamdown/cjk
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Tailwind CSS

### Tailwind v4

Add the following `@source` directive to your `globals.css` or main CSS file:

```css title="globals.css"
@source "../node_modules/@streamdown/cjk/dist/*.js";
```

The path must be relative from your CSS file to the `node_modules` folder containing `@streamdown/cjk`. In a monorepo, adjust the number of `../` segments to reach the root `node_modules`.

### Tailwind v3

Add `@streamdown/cjk` to your `content` array in `tailwind.config.js`:

```js title="tailwind.config.js"
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./node_modules/@streamdown/cjk/dist/*.js",
  ],
  // ... rest of your config
};
```

In a monorepo, adjust the path to reach the root `node_modules`:

```js title="tailwind.config.js"
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "../../node_modules/@streamdown/cjk/dist/*.js",
  ],
  // ... rest of your config
};
```

## Usage

```tsx title="chat.tsx" lineNumbers
import { cjk } from '@streamdown/cjk';

<Streamdown plugins={{ cjk }}>
  {markdown}
</Streamdown>
```

For advanced configuration, use `createCjkPlugin`:

```tsx title="app/page.tsx"
import { Streamdown } from "streamdown";
import { createCjkPlugin } from "@streamdown/cjk";

const cjk = createCjkPlugin();

export default function Page() {
  return (
    <Streamdown plugins={{ cjk }}>
      {markdown}
    </Streamdown>
  );
}
```

## The Problem

The CommonMark/GFM specification has a [limitation](https://github.com/commonmark/commonmark-spec/issues/650) where emphasis markers (`**` or `*`) adjacent to ideographic punctuation marks occasionally fail to be recognized. This causes formatting to break in CJK text:

```markdown
**この文は太字になりません（This won't be bolded）。**この文のせいで（It is due to this sentence）。
```

Without CJK-friendly parsing, the text above would render as plain text instead of bold because the closing `**` appears next to the Japanese period.

## Supported Features

### Bold Text with Punctuation

Works correctly with all ideographic punctuation marks:

```markdown
**日本語の文章（括弧付き）。**この文が後に続いても大丈夫です。
**中文文本（带括号）。**这句子继续也没问题。
**한국어 구문(괄호 포함)**을 강조.
```

{/* The following lang="..." is crucial to ensure proper han character rendering */}

Japanese: <span lang="ja"><strong>日本語の文章（括弧付き）。</strong>この文が後に続いても大丈夫です。</span>

Chinese: <span lang="zh-Hans"><strong>中文文本（带括号）。</strong>这句子继续也没问题。</span>

Korean: <span lang="ko"><strong>한국어 구문(괄호 포함)</strong>을 강조.</span>

### Italic Text with Punctuation

```markdown
*これは斜体のテキストです（括弧付き）。*この文が後に続いても大丈夫です。
*这是斜体文字（带括号）。*这句子继续也没问题。
*이 텍스트(괄호 포함)*는 기울임꼴입니다.
```

Japanese: <span lang="ja"><em>これは斜体のテキストです（括弧付き）。</em>この文が後に続いても大丈夫です。</span>

Chinese: <span lang="zh-Hans"><em>这是斜体文字（带括号）。</em>这句子继续也没问题。</span>

Korean: <span lang="ko"><em>이 텍스트(괄호 포함)</em>는 기울임꼴입니다.</span>

### Strikethrough with Punctuation

Streamdown includes `remark-cjk-friendly-gfm-strikethrough` for proper strikethrough support:

```markdown
~~削除されたテキスト（括弧付き）。~~この文は正しいです。
~~删除的文字（带括号）。~~这个句子是正确的。
~~이 텍스트(괄호 포함)~~를 삭제합니다.
```

Japanese: <span lang="ja"><del>削除されたテキスト（括弧付き）。</del>この文は正しいです。</span>

Chinese: <span lang="zh-Hans"><del>删除的文字（带括号）。</del>这个句子是正确的。</span>

Korean: <span lang="ko"><del>이 텍스트(괄호 포함)</del>를 삭제합니다。</span>

### Mixed Content

CJK and English text work seamlessly together:

```markdown
**重要提示（Important Notice）：**请注意。
```

Result: <span lang="zh-Hans"><strong>重要提示（Important Notice）：</strong>请注意。</span>

## Supported Punctuation

The plugin handles all common ideographic punctuation marks:

* Parentheses: `（）`
* Brackets: `【】「」〈〉`
* Periods: `。．`
* Commas: `，、`
* Questions: `？`
* Exclamations: `！`
* Colons: `：`

## Why This Matters for AI

Language models generate markdown naturally, often placing emphasis markers around phrases that include punctuation. Without CJK-friendly parsing, AI-generated content in Chinese, Japanese, or Korean would have broken formatting.

<dl>
  <dt>
    ❌ Without CJK support:
  </dt>

  <dd>
    * The model writes:{" "}
      <span lang="ja">`**この用語（読み方など）**について説明します。`</span>- The
      user sees: <span lang="ja">
      \*\*この用語（読み方など）\*\*について説明します。
      </span> (not bold!)
  </dd>

  <dt>
    ✅ With CJK support:
  </dt>

  <dd>
    * The model writes:{" "}
      <span lang="ja">`**この用語（読み方など）**について説明します。`</span>- The
      user sees: <span lang="ja">
      <strong>この用語（読み方など）</strong>について説明します。
      </span> (properly bolded!)
  </dd>
</dl>

## Autolink Boundary Handling

The CJK plugin also prevents autolinks from swallowing trailing CJK punctuation. When a URL ends with CJK punctuation characters, the plugin splits the link so the punctuation appears as regular text.

**Example:**

```markdown
Check out https://example.com。这是一个链接。
```

Without CJK support, the trailing `。` would be included in the URL. With the plugin, the link ends at `https://example.com` and the period is rendered as text.

**Supported boundary characters:**

`。．，、？！：；（）【】「」『』〈〉《》`

## Plugin API

The CJK plugin provides remark plugins in a specific order for proper integration:

```tsx
interface CjkPlugin {
  // Plugins that run BEFORE remarkGfm (e.g., remark-cjk-friendly)
  remarkPluginsBefore: Pluggable[];

  // Plugins that run AFTER remarkGfm (e.g., autolink boundary, strikethrough)
  remarkPluginsAfter: Pluggable[];

  // @deprecated - Use remarkPluginsBefore and remarkPluginsAfter instead
  remarkPlugins: Pluggable[];
}
```

Streamdown automatically handles the plugin ordering. If integrating manually, ensure:

1. `remarkPluginsBefore` runs before `remarkGfm` (modifies emphasis handling)
2. `remarkPluginsAfter` runs after `remarkGfm` (enhances autolinks and strikethrough)


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)