Back

BunでMarkdownをネイティブにパースする

BunでMarkdownをネイティブにパースする

unifiedremark-parseremark-rehyperehype-stringifyを組み合わせてMarkdown文字列をHTMLに変換したことがある方なら、そのオーバーヘッドをご存知でしょう。Bun 1.3.8(2026年1月リリース)には、この一連の処理を単一のAPI呼び出しで置き換える組み込みMarkdownパーサーが搭載されています。インストール、インポート、プラグイン設定は一切不要です。

本記事では、新しいBun.markdown APIの機能、動作原理、そしてワークフローへの組み込み方について解説します。

要点

  • Bun.markdownは、Bunランタイムに組み込まれたネイティブMarkdownパーサーで、md4c CライブラリのZigポートによって駆動されます。
  • html()メソッドは、外部ライブラリを必要とせず、単一の呼び出しでMarkdownをHTMLに変換します。
  • render()は、各要素タイプに対するJavaScriptコールバックを通じて、カスタム出力形式(スタイル付きHTML、ANSI、プレーンテキスト)をサポートします。
  • react()はReact要素を直接返し、Markdownコンテンツをコンポーネントツリーの一部としてレンダリングできます。
  • このAPIはまだ不安定版とマークされているため、Bunのバージョンを固定し、本番環境にデプロイする前に出力を検証してください。

Bun Markdownパーサーとは?

Bun.markdownは、Bunランタイムに直接組み込まれたネイティブMarkdownパーサーです。CommonMark仕様に準拠しており、Qtなどのパフォーマンス重視の環境で使用されているmd4c CライブラリのZigポートとして実装されています。

JavaScriptではなくコンパイル済みのZigコードとして実行されるため、unifiedremarkなどのJavaScriptベースのパース処理のオーバーヘッドを回避できます。複数のパッケージを連鎖させる代わりに、BunはMarkdown処理のための単一のランタイムAPIを提供します。

注意: Bun.markdown APIは現在、公式Bunドキュメントで**不安定版(unstable)**とマークされています。このインターフェースは現時点で動作しますが、特定のオプションやメソッドシグネチャは将来のBunリリースで変更される可能性があります。本番環境でアップグレードする前に、Bunリリースノートを確認してください。

BunでMarkdownをHTMLに変換:html()メソッド

最もシンプルなユースケース — MarkdownをHTML文字列に変換する — は、セットアップ不要です:

const html = Bun.markdown.html("# Hello **world**")
// "<h1>Hello <strong>world</strong></h1>\n"

第2引数としてオプションを渡すことができます。headingsオプションは、ドキュメントサイトや目次生成に便利です:

const html = Bun.markdown.html("## Getting Started", {
  headings: { ids: true }
})
// '<h2 id="getting-started">Getting Started</h2>\n'

GitHub Flavored Markdown(GFM)拡張機能はデフォルトで有効になっており、テーブル、取り消し線(~~text~~)、タスクリスト(- [x] done)、寛容な自動リンクが含まれます。wikiLinkslatexMath、見出しの自動リンクなどの追加オプションもサポートされています。

Bun.markdown.render()によるカスタムレンダリング

標準的なHTMLではない出力 — スタイル付きマークアップ、ANSIターミナル出力、プレーンテキスト — が必要な場合、render()は各要素タイプに対するJavaScriptコールバックを受け付けます:

// 要素にCSSクラスを追加
const html = Bun.markdown.render("# Title\n\nHello **world**", {
  heading: (children, { level }) => `<h${level} class="title">${children}</h${level}>`,
  paragraph: (children) => `<p class="body">${children}</p>`,
  strong: (children) => `<b>${children}</b>`,
})

// すべての書式をプレーンテキストに削除
const plain = Bun.markdown.render("# Title\n\n**bold** text", {
  heading: (children) => children + "\n",
  strong: (children) => children,
  paragraph: (children) => children + "\n",
})

// nullを返すことで特定の要素を完全に省略
const noImages = Bun.markdown.render("# Title\n\n![logo](img.png)", {
  image: () => null,
  heading: (children) => `<h1>${children}</h1>`,
})

これにより、render()はCLIツール、メール生成、またはHTMLがターゲット形式ではないあらゆるパイプラインで有用です。

react()によるBun Markdown Reactレンダリング

Bun.markdown.react()は、コンポーネントツリーで直接使用できるReact要素を返します:

function Markdown({ text }: { text: string }) {
  return Bun.markdown.react(text)
}

// Markdown要素をカスタムコンポーネントにマッピング
const element = Bun.markdown.react("# Hello", {
  h1: ({ children }) => <h1 className="page-title">{children}</h1>,
})

// サーバーサイドレンダリングでも動作
import { renderToString } from "react-dom/server"
const html = renderToString(Bun.markdown.react("# Hello **world**"))

React 18以前を使用している場合は、互換性オプションを渡すことができます:

Bun.markdown.react(markdownText, undefined, { reactVersion: 18 })

Bun.markdown vs. Remarkの使い分け

シナリオ推奨
基本的なMarkdown-to-HTML変換Bun.markdown.html()
カスタム出力(ANSI、スタイル付きHTML)Bun.markdown.render()
ReactコンポーネントツリーBun.markdown.react()
シンタックスハイライト、脚注、複雑なプラグインunified/remarkを継続使用

まとめ

Bun 1.3.8以降を既に実行している場合、Bun.markdownはグローバルに利用可能です — インストールは不要です。シンプルなコンテンツパイプラインにはBun.markdown.html()から始め、出力をより細かく制御する必要がある場合はrender()またはreact()を使用してください。

このAPIはまだ不安定版とマークされているため、Bunのバージョンを固定し、本番環境にデプロイする前にレンダリング出力を期待されるHTMLと照合してテストしてください。

よくある質問

いいえ。Bun.markdownは標準的なMarkdown-to-HTML変換を処理しますが、組み込みのシンタックスハイライトは含まれていません。コードのハイライトには、ShikiやPrismなどのライブラリでHTML出力を後処理するか、専用のハイライトプラグインを使用したunified/remarkパイプラインを使用する必要があります。

いいえ。Bun.markdownはBunランタイムに組み込まれたネイティブAPIであり、Node.jsでは利用できません。プロジェクトがNode上で実行される場合は、unified、remark、markdown-itなどのライブラリを引き続き使用してMarkdownをパースする必要があります。

Bun.markdownには組み込みのHTMLサニタイゼーションは含まれていません。ユーザーが送信したMarkdownを処理する場合は、クロスサイトスクリプティングの問題を防ぐために、生成されたHTMLをブラウザでレンダリングする前にDOMPurifyやsanitize-htmlなどのサニタイゼーションライブラリを通してください。

いいえ。Bun.markdownはGitHub Flavored Markdown拡張機能を備えたCommonMarkを実装しています。MDX、カスタムディレクティブ、またはunifiedとremarkで利用可能なプラグインエコシステムはサポートしていません。これらのユースケースには、remarkベースのパイプラインが引き続き適切な選択肢です。

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay