Kamiby Typo Monster
Docs

Installation

Install @kami/html-to-md and convert your first Notion HTML export.

Install

Basic usage

One-shot conversion

The simplest way to convert a file:

typescript
import { notionHtmlToMarkdown } from "@kami/html-to-md";
import { readFileSync } from "fs";
 
const html = readFileSync("notion-export.html", "utf-8");
const markdown = notionHtmlToMarkdown(html);
 
console.log(markdown);

Full result with metadata

Use the class-based API to access page metadata alongside the Markdown:

typescript
import { NotionHtmlConverter } from "@kami/html-to-md";
import { readFileSync, writeFileSync } from "fs";
 
const converter = new NotionHtmlConverter();
const html = readFileSync("notion-export.html", "utf-8");
const result = converter.convert(html);
 
// Write Markdown to file
writeFileSync("output.md", result.markdown);
 
// Access metadata
console.log("Title:", result.title);
console.log("Icon:", result.icon);
console.log("Images:", result.images.length);
console.log("Child pages:", result.childPageLinks.length);

Omit the page title

By default, the page title is included as an H1 heading. To skip it:

typescript
const converter = new NotionHtmlConverter({ includeTitle: false });
const result = converter.convert(html);
// result.markdown starts with the first content block, no H1

Edge runtime usage

The library uses a SAX parser with no DOM dependency, so it works in edge runtimes:

Cloudflare Workers

typescript
import { notionHtmlToMarkdown } from "@kami/html-to-md";
 
export default {
  async fetch(request: Request): Promise<Response> {
    const html = await request.text();
    const markdown = notionHtmlToMarkdown(html);
    return new Response(markdown, {
      headers: { "Content-Type": "text/markdown" },
    });
  },
};

Deno

typescript
import { notionHtmlToMarkdown } from "@kami/html-to-md";
 
const html = await Deno.readTextFile("notion-export.html");
const markdown = notionHtmlToMarkdown(html);
console.log(markdown);

Batch processing

Convert multiple files from a directory:

typescript
import { NotionHtmlConverter } from "@kami/html-to-md";
import { readdirSync, readFileSync, writeFileSync, mkdirSync } from "fs";
import { join, basename } from "path";
 
const converter = new NotionHtmlConverter();
const inputDir = "./notion-exports";
const outputDir = "./markdown";
 
mkdirSync(outputDir, { recursive: true });
 
const htmlFiles = readdirSync(inputDir).filter((f) => f.endsWith(".html"));
 
for (const file of htmlFiles) {
  const html = readFileSync(join(inputDir, file), "utf-8");
  const result = converter.convert(html);
  const outName = basename(file, ".html") + ".md";
  writeFileSync(join(outputDir, outName), result.markdown);
  console.log(`Converted: ${file} → ${outName}`);
}

TypeScript

The package ships with full TypeScript declarations. All types are exported:

typescript
import type {
  ConvertOptions,
  ConvertResult,
  ChildPageLink,
  ImageRef,
} from "@kami/html-to-md";

Next steps