Skip to content

Convert HTML to Markdown - Native Node.js bindings for Rust implementation

License

Notifications You must be signed in to change notification settings

sebastian-software/turndown-node

Repository files navigation

turndown-node

CI npm version npm downloads crates.io License: MIT Node.js

Convert HTML to Markdown. Native Node.js bindings powered by Rust for maximum performance.

Packages

This monorepo provides two ways to use turndown:

Package Platform Description
turndown-node npm Node.js bindings with HTML parsing
turndown-cdp crates.io Rust crate for CDP-style DOM trees

Node.js Usage

npm install turndown-node
const TurndownService = require("turndown-node");

const turndownService = new TurndownService();
const markdown = turndownService.turndown("<h1>Hello World</h1>");
// => "Hello World\n==========="

100% compatible with turndown v7.2.0 - drop-in replacement with identical output.

Full Node.js documentation →

Performance

turndown-node is significantly faster than the JavaScript implementation thanks to native Rust code:

Fixture Size turndown-node turndown (JS) Speedup
small 2 KB 59,146 ops/s 3,276 ops/s 18.1x
medium 16 KB 7,061 ops/s 433 ops/s 16.3x
large 141 KB 774 ops/s 47 ops/s 16.6x
huge 1.4 MB 64 ops/s 3 ops/s 19.9x

Average speedup: ~18x faster

Benchmarks run on Apple M-Series, Node.js v24. Run node benchmarks/benchmark.js to reproduce.

Rust Usage

cargo add turndown-cdp
use turndown_cdp::{TurndownService, Node};

let service = TurndownService::new();

// Build a DOM tree
let mut h1 = Node::element("h1");
h1.add_child(Node::text("Hello World"));

let markdown = service.turndown(&h1).unwrap();

The Rust crate uses a CDP-style Node structure (Chrome DevTools Protocol), making it ideal for:

  • Browser automation with chromiumoxide
  • Readability/content extraction pipelines
  • Any scenario where DOM is already parsed

Full Rust documentation →

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        turndown-core                            │
│              Markdown AST types + Serialization                 │
└─────────────────────────────────────────────────────────────────┘
                            ▲
                            │
              ┌─────────────┴─────────────┐
              │                           │
   ┌──────────┴──────────┐     ┌──────────┴──────────┐
   │   turndown-napi     │     │    turndown-cdp     │
   │   HTML → AST        │     │   CDP Node → AST    │
   │   (tl parser)       │     │   (for Rust apps)   │
   └──────────┬──────────┘     └─────────────────────┘
              │
   ┌──────────┴──────────┐
   │   turndown-node     │
   │   (npm package)     │
   └─────────────────────┘

See Architecture Decision Records for design rationale.

Supported Platforms

Platform Architecture npm Rust
macOS ARM64 (Apple Silicon)
Linux x64 (glibc)
Linux ARM64 (glibc)
Windows x64

Development

Prerequisites

  • Node.js >= 22
  • Rust >= 1.70
  • pnpm >= 10

Setup

# Install dependencies
pnpm install

# Build native module
pnpm build

# Run tests
pnpm test

# Run Rust tests
cargo test --workspace

# Run benchmarks
node benchmarks/benchmark.js

Project Structure

turndown-node/
├── crates/
│   ├── turndown-core/     # Shared Markdown AST + serialization
│   ├── turndown-cdp/      # CDP Node → AST (crates.io)
│   └── turndown-napi/     # HTML → AST with NAPI-RS bindings
├── packages/
│   ├── turndown-node/     # Main npm package
│   ├── darwin-arm64/      # Platform-specific bindings
│   ├── linux-x64-gnu/
│   ├── linux-arm64-gnu/
│   └── win32-x64-msvc/
├── benchmarks/            # Performance benchmarks
├── tests/                 # Jest parity tests
└── docs/adr/              # Architecture Decision Records

License

MIT


Copyright 2026 Sebastian Software GmbH, Mainz

About

Convert HTML to Markdown - Native Node.js bindings for Rust implementation

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •