turndown adalah library yang paling banyak di-star di antara empat library yang diuji pada snapshot metadata, dengan 11.386 bintang GitHub. Pada empat fixture HTML yang sama, library ini menghasilkan nol tabel Markdown dengan default bawaan, dan memakai 24,6% token lebih banyak daripada markdownify untuk input yang sama.
Keempatnya berhasil mempertahankan semua probe konten. Perbedaannya sepenuhnya ada pada apa yang terjadi pada struktur, dan seberapa besar biaya struktur itu di tahap berikutnya.
Apa yang diukur, dan pada fixture milik siapa
Basis riset ini sebelumnya sudah memiliki paket untuk markitdown dengan lima fixture HTML dan string probe yang sudah didaftarkan sebelumnya — string persis yang dicek keberadaannya, plus string boilerplate untuk mendeteksi chrome halaman. Perbandingan agregat menggunakan empat fixture yang sama untuk keempat converter: katalog toko buku, situs kutipan, tabel statistik hoki, dan artikel Wikipedia tentang web scraping. Fixture kelima, Nothing but tables, hanya dipakai sebagai diagnostik yang sangat tabel-heavy dan tidak dimasukkan ke agregat 24,6%.
Keempatnya adalah: turndown 7.2.4 (Node), markdownify 1.2.3, html2text 2025.4.15, dan markitdown, yang baris-baris terbitannya digunakan apa adanya. Halamannya: katalog toko buku, situs kutipan, tabel statistik hoki, dan artikel Wikipedia tentang web scraping.
Semua nama metrik di bawah ini cocok field demi field dengan artefak milik markitdown, jadi baris-barisnya bisa diletakkan berdampingan tanpa perlu menyamakan dua definisi untuk kata yang sama.
Tabel

| Converter | Body probes | Output chars | Tokens (o200k) | Bytes/token | Markdown table rows | Links |
|---|---|---|---|---|---|---|
| turndown | 16/16 | 95,188 | 26,236 | 3.63 | 0 | 611 |
| markdownify | 16/16 | 76,868 | 21,062 | 3.65 | 36 | 599 |
| html2text | 16/16 | 76,452 | 21,176 | 3.61 | 32 | 545 |
| markitdown | 16/16 | 76,995 | 21,336 | 3.61 | 36 | 598 |
Empat fixture — yang juga dijalankan oleh markitdown. Angka lengkap per fixture ada di fiveway-scores.json. Token dihitung dengan o200k_base; baris tabel markitdown dihitung ulang dari Markdown tersimpan miliknya sendiri dengan penghitung yang sama seperti yang dipakai untuk yang lain.
Keberlangsungan konten seri. Semua enam belas body probe di empat fixture bertahan di setiap converter. Kalau pertanyaannya hanya "apakah teksnya tetap lolos", keempatnya sama-sama menjawab ya.
Struktur bukan seri. Pada empat fixture yang sama, markdownify dan markitdown sama-sama menghasilkan 36 baris tabel Markdown; html2text menghasilkan 32; turndown tidak menghasilkan satu pun. Pada diagnostik terpisah yang hanya berisi tabel, markdownify menghasilkan 62 baris dan html2text 59; baris-baris itu tidak dimasukkan ke agregat di atas.
Biaya token 24,6% lebih tinggi untuk turndown, dan penyebabnya bukan tabel. Saya sempat mengira demikian, tetapi angka per fixture berkata lain — lihat di bawah.
Apa yang dilakukan turndown pada tabel
Berikut fixture statistik hoki, isi barisnya sama, ditampilkan dalam tiga cara.
turndown:

Team Name
Year
Wins
Losses
Boston Bruins
1990
44
24
markdownify:
| Team Name | Year | Wins | Losses | ... |
| --- | --- | --- | --- | --- |
| Boston Bruins | 1990 | 44 | 24 | ... |
html2text:
Team Name | Year | Wins | Losses | ...
---|---|---|---|---
Boston Bruins | 1990 | 44 | 24 | ...
Setiap nilai tetap lolos melalui konversi turndown, itulah sebabnya ia mendapat skor 16/16 pada probe. Yang tidak lolos adalah nilai itu milik kolom yang mana. Baca output turndown, dan 44 hanyalah angka di sebuah baris; Anda tidak bisa tahu bahwa itu adalah jumlah kemenangan Boston tanpa menghitung posisi dan berharap tidak ada sel yang kosong. Di fixture ini ada sel yang memang kosong, jadi menghitung posisi pun tidak bekerja.
Bagi model yang membaca output, itu bedanya antara tabel yang bisa dijawab pertanyaannya dan daftar angka yang hanya bisa ditebak.
Ini bukan cacat, melainkan batas yang memang didokumentasikan — core turndown memang tidak menangani tabel, dan turndown-plugin-gfm ada untuk menambahkannya. Namun instalasi default tidak menyertakannya, dan 11.386 bintang menunjukkan banyak orang kemungkinan memakai default tersebut.
Sumber selisih token yang sebenarnya
Saya menulis paragraf di atas dengan keyakinan bahwa gap 24,6% token terjadi karena tabel yang diratakan muncul sebagai karakter. Lalu saya melihatnya per fixture, dan ternyata bukan itu.
| Fixture | turndown tokens ÷ markdownify tokens |
|---|---|
| Quotes site (no tables) | 0.99× |
| Bookshop catalogue | 1.06× |
| Hockey statistics (one big table) | 1.37× |
| Wikipedia (mostly prose, 9 table rows) | 1.29× |
| Nothing but tables | 0.78× |
Pada fixture yang isinya hanya tabel, turndown justru 22% lebih murah — karena scaffolding pipe juga menghabiskan token, dan turndown tidak menghasilkan itu. Meratakan tabel, sendirian, bukan penalti token.
Fixture Wikipedia menyumbang 74% dari total, dan hanya punya sembilan baris tabel. Selisih 15.378 karakternya jelas bukan berasal dari tabel. Penyebabnya ini:
(function(){var className="client-js vector-feature-language-in-header-enabled…
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}…
(RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgHostname":"mw-web…
turndown tidak menghapus isi <script> dan <style>. markdownify dan html2text sama-sama menghapusnya. Jika dihitung dari penanda yang hanya muncul di dalam elemen-elemen itu: output turndown membawa 10 penanda script dan 84 penanda style di seluruh fixture; dua yang lain membawa nol masing-masing. Pada halaman Wikipedia, delapan baris konfigurasi JavaScript inline dan CSS MediaWiki menyumbang 14.644 karakter — 95% dari seluruh selisih (script-style-stripping.json).
Itulah temuan yang benar-benar layak ditindaklanjuti. Tabel yang diratakan adalah masalah struktur yang bisa Anda lihat. Blob konfigurasi JavaScript di Markdown adalah biaya murni tanpa informasi sama sekali, dan pada halaman dunia nyata itulah yang paling besar dalam perbandingan ini.
html2text menulis tabel yang mungkin tidak Anda kenali
html2text mendapat 32 baris ketika markdownify dan markitdown masing-masing mendapat 36, dan versi pertama penghitung saya hanya memberinya skor 1.
Itu adalah aturan hitung saya, bukan library-nya. html2text mengeluarkan Team Name | Year | Wins tanpa pipe pembuka dan penutup — bentuk tabel Markdown yang umum, tetapi tidak terlihat oleh regex yang mensyaratkan ^\|.*\|$. Saya sempat menulis regex itu, menjalankannya, dan hampir melaporkan bahwa html2text tidak mendukung tabel.
Padahal mendukung. Penghitung yang sudah diperbaiki memakai heuristik: rangkaian baris berturut-turut yang berisi pipe, dengan satu baris pemisah di dalamnya. Dengan aturan itu, html2text naik dari 1 menjadi 32. Ini bukan parser Markdown penuh, jadi total baris harus dibaca sebagai hasil pengukuran berdasarkan penghitung yang terdokumentasi, bukan hasil rendering universal.
Penting untuk diketahui kalau Anda memproses Markdown lebih lanjut dengan regex sendiri: dua dari empat library ini memakai pipe luar, satu tidak.
Lisensi yang hampir tidak pernah disebut
| Converter | Licence | Install | Cold import | Stars | Last release |
|---|---|---|---|---|---|
| turndown | MIT | 3 npm packages, 8.8 MiB | 0.056 s | 11,386 | 2026-04-03 |
| markdownify | MIT | 5 packages, 1.8 MiB | 0.046 s | 2,235 | 2026-06-30 |
| html2text | GPL-3.0-or-later | 1 package, 0.2 MiB | 0.077 s | 2,168 | 2025-04-15 |
| markitdown | See its package metadata | Not measured in this install run | Not measured | — | — |
install-and-import.json. Masing-masing library diinstal ke environment kosongnya sendiri. Lisensi dikonfirmasi dari tiga sumber: metadata registry, repo GitHub, dan file METADATA milik paket terpasang sendiri, yang berbunyi License-Expression: GPL-3.0-or-later.
Library paling ringan dalam perbandingan instalasi ini — satu paket, 0,2 MiB — adalah GPL-3.0-or-later. Apakah itu berdampak pada proyek tergantung pada bagaimana perangkat lunak itu digabungkan dan didistribusikan. Anggap ini sebagai checkpoint seleksi bagi pihak yang bertanggung jawab atas lisensi; artikel ini bukan nasihat hukum. markitdown ditampilkan sebagai belum diukur di sini karena instalasi dan lisensinya tidak tertangkap oleh artefak khusus ini.
Trade-off ini mudah terlewat karena lisensi adalah satu-satunya properti yang tidak muncul di benchmark.
Ketiganya jauh lebih ringan daripada library ekstraksi artikel dalam kategori yang sama — yang ukurannya 21 sampai 70 MiB. Converter adalah sesuatu yang jauh lebih kecil daripada extractor, dan layak dipisahkan dalam anggaran dependensi Anda.
Dua confound yang harus saya perbaiki sebelum tabel ini benar
Angka-angka di atas adalah versi ketiga. Dua yang pertama salah dalam cara yang penting untuk disebutkan, karena keduanya mudah direproduksi.
Lima fixture melawan empat. markitdown menjalankan empat dari lima file ini; tiga yang lain menjalankan kelimanya. Menjumlahkan tiap tool pada set miliknya sendiri membuat markdownify terlihat punya 98 baris tabel dibanding 36 milik markitdown, seolah-olah ada kesenjangan kemampuan. Pada empat fixture yang sama, hasilnya 36 melawan 36 — seri mutlak. Fixture kelima adalah yang paling tabel-heavy, jadi confound-nya bergerak ke arah terburuk, menggelembungkan newcomer dibanding incumbent hampir tiga kali lipat.

Dua penghitung, satu kolom. md_table_rows yang dipublikasikan markitdown berasal dari kode miliknya sendiri, yang belum saya baca. Membandingkan angka itu dengan angka saya bisa jadi berarti membandingkan dua penghitung, bukan dua converter. Output Markdown-nya disimpan di disk, jadi solusinya adalah menjalankan satu penghitung untuk semua empat — dan ketika saya melakukannya, hasil hitung ulang markitdown keluar persis seperti angka yang dipublikasikannya per fixture (0, 0, 27, 9). Definisinya ternyata sama; saya hanya tidak mungkin tahu tanpa memeriksanya.
Tak satu pun dari dua kesalahan itu akan terlihat di output. Keduanya akan menghasilkan tabel yang terlihat meyakinkan tapi salah.
Siapa sebaiknya memakai apa
Untuk memberi model input, atau menyimpan konten terstruktur dari halaman seperti ini? Mulailah dengan markdownify. Ia seri dengan markitdown pada jumlah baris tabel yang dihasilkan menurut penghitung ini, berada di klaster token terendah, berlisensi MIT, dan terpasang dalam 1,8 MiB. Validasi dulu pada bentuk halaman Anda sendiri sebelum menjadikannya standar.
Anggaran dependensi diukur dalam kilobyte, dan Anda tidak mendistribusikan software? html2text. Satu paket, 0,2 MiB, tabel tetap utuh. Cek dulu isu GPL-nya, dan perhatikan rilis terakhir pada April 2025.
Sudah berada di stack Node? turndown, dengan turndown-plugin-gfm dipasang bersamanya — dan hapus <script> serta <style> dari HTML sebelum Anda berikan, karena turndown tidak akan melakukannya. Dua kelalaian itu menambah seperempat token, menghilangkan struktur tabel, dan keduanya tidak akan terlihat kecuali Anda memeriksa output.
Sudah mengonversi format dokumen lain? markitdown menangani PDF, Office, dan lainnya, dan output HTML-nya kompetitif dengan converter khusus. Satu dependensi alih-alih dua tetap punya nilai.
Di mana API terkelola cocok
Keempat alat ini hanya memproses HTML yang sudah Anda miliki. Tidak ada yang mengambil halaman, merender JavaScript, atau menangani lapisan anti-bot — dan untuk banyak target nyata, justru bagian itulah yang lebih sulit.
Developer stack kami sendiri di Thunderbit menangani sisi itu. POST /distill menerima URL dan mengembalikan Markdown bersih siap-LLM dengan rendering dan fetching yang ditangani; POST /extract mengembalikan JSON terstruktur yang sesuai schema AI berdasarkan JSON Schema yang Anda berikan, yang menghasilkan bentuk output berbeda lagi — baris-baris, bukan tabel Markdown yang masih harus Anda parse. Keduanya bisa diakses dari server MCP dan CLI (npx @thunderbit/thunderbit-cli). Harga ada di halaman pricing Thunderbit.
Perbandingan jujur: jika Anda sudah memegang HTML dan ingin Markdown, markdownify gratis dan kerjanya bagus, dan tabel ini menunjukkan mana di antara para rivalnya yang juga bagus. Jika Anda perlu mengambil halaman, atau ingin baris terstruktur alih-alih prosa, itu pembelian yang berbeda.
Untuk gambaran yang lebih luas, ringkasan web scraping API kami membahas opsi hosted dan pilar open-source scraper membahas yang self-hosted. Mengonversi HTML ke Markdown di Python adalah panduan praktiknya, dan apa yang ingin distandardisasi oleh llms.txt membahas ke mana arah kategori ini bergerak.
Coba Thunderbit untuk Ekstraksi Data Web
Kesimpulan
Untuk beban kerja empat fixture ini, markdownify adalah default terkuat: jumlah baris tabel yang dihasilkan sama dengan markitdown di bawah penghitung yang sama, jumlah tokennya hanya 1,3% dari converter efisien lain, berlisensi MIT, dan instalasinya 1,8 MiB.
Kesenjangan antara popularitas dan perilaku terukur itulah temuan utamanya. turndown adalah library yang sangat baik, dan banyak orang memasangnya tanpa plugin yang membuatnya menangani tabel, dan akibatnya terlihat sebagai seperempat token lebih banyak serta struktur tabel yang hilang. Tidak satu pun angka itu terlihat sampai Anda menghitungnya.
Kalau hanya mengambil satu pelajaran: cek dulu apa yang dilakukan converter Anda terhadap tabel sebelum Anda mempercayakan outputnya ke model. Tiga dari empat alat ini melakukan hal yang masuk akal. Yang paling populer tidak, kecuali Anda memintanya.
Coba Thunderbit untuk Ekstraksi Data Web Get Started Free
FAQ
Apakah turndown benar-benar tidak mendukung tabel?
Core-nya memang tidak. Tabel datang dari turndown-plugin-gfm, paket terpisah, dan npm install turndown biasa tidak menyertakannya. Tanpa plugin, setiap sel bertahan sebagai paragrafnya sendiri — semua nilai tetap ada, tetapi hubungan baris dan kolomnya hilang. Di empat fixture, hasilnya nol baris tabel Markdown dan token 24,6% lebih banyak dibanding markdownify untuk konten yang sama.
Kenapa html2text awalnya terlihat seperti tidak punya tabel?
Karena penghitung saya mensyaratkan pipe pembuka dan penutup, sedangkan html2text tidak menampilkannya. Team Name | Year | Wins adalah Markdown yang sah dan dirender dengan benar; hanya gayanya berbeda dari | Team Name | Year |. Penghitung yang sudah diperbaiki mencari rangkaian baris berisi pipe dengan satu baris pemisah, seperti parser, dan html2text naik dari 1 baris menjadi 32. Jika Anda memproses Markdown dengan regex sendiri, inilah bedanya yang akan menjebak Anda.
Apakah GPL pada html2text benar-benar masalah?
Tergantung bagaimana Anda menggabungkan dan mendistribusikan software-nya. GPL-3.0-or-later bisa menimbulkan kewajiban yang tidak dimiliki MIT, jadi libatkan pihak yang mengelola lisensi sebelum memilihnya untuk produk yang didistribusikan. Ini checkpoint kepatuhan, bukan nasihat hukum; identitas lisensinya dikonfirmasi di metadata registry, repository, dan file METADATA paket yang terinstal.
Apakah hitungan token ini relevan untuk halaman lain?
Gap 24,6% itu terutama karena turndown membiarkan isi <script> dan <style> tetap ikut, jadi skalanya tergantung seberapa banyak konten seperti itu di halaman — besar pada halaman CMS modern, hampir nol pada halaman statis. Tabel bekerja ke arah sebaliknya: pada fixture yang isinya hanya tabel, turndown justru 22% lebih murah, karena ia tidak mengeluarkan scaffolding pipe. Bytes per token berada antara 3,61 dan 3,65 untuk semuanya, jadi kepadatan outputnya sama dan perbedaannya ada pada jumlah. Ukur korpus Anda sendiri kalau angka itu penting untuk budget.
Apa yang tidak diuji di sini?
Variasi dunia nyata — empat fixture ya tetap empat fixture. Nested list, definition list, catatan kaki, dan matematika. HTML yang rusak, yang secara historis paling sering membuat converter berbeda perilaku. Round-tripping Markdown kembali ke HTML. docling, yang punya fixture yang sama di disk tetapi run publiknya tidak melaporkan field-field ini, jadi ia tidak dimasukkan, bukan diestimasi. Dan konfigurasi: html2text dijalankan dengan body_width=0 karena default 78 miliknya akan membungkus paksa setiap baris, yang akan mengubah semua karakter dan hitungan token di tabel ini.


