Satteri 2026: Pipeline Markdown Rust Kalahkan unified/remark
Pada 25 Juni 2026, sebuah posting solo di HN berjudul "Satteri: a Rust-forged Markdown pipeline for JavaScript" masuk halaman pertama Show HN dan bertahan di sana selama 18 jam. Tawarannya singkat: pengganti drop-in untuk stack populer unified + remark-parse yang berjalan 5 sampai 10 kali lebih cepat, punya nol dependensi npm, dikemas sebagai satu file WASM, dan memaparkan bentuk AST yang sama sehingga plugin Anda yang sudah ada tetap bekerja. Untuk proyek JavaScript mana pun yang mem-parse volume Markdown yang tidak sepele, itu tawaran yang serius.
Proyek ini tidak ditujukan untuk situs dokumentasi. Ini ditujukan untuk pipeline — jenis sistem yang mengambil 10.000 posting sosial per hari dari X, Bluesky, dan LinkedIn, menormalkannya ke Markdown bersih, dan mengindeksnya untuk pencarian. Itulah persis beban kerja di balik backend tangkapan ThreadGrab dan pipeline paste md2rich. Benchmark di bawah adalah yang saya jalankan di arsip kami sendiri berisi 1,4 juta posting sosial.
TL;DR: Satteri adalah parser Markdown Rust yang dikompilasi ke WebAssembly dan memaparkan API JavaScript. Pada beban kerja konten sosial nyata (thread X panjang, feed Bluesky dengan media ter-embed, edisi LinkedIn newsletter) ia 5 sampai 10x lebih cepat dari unified + remark-parse, menghasilkan AST yang patuh CommonMark, dan merupakan satu file 480 KB dengan nol dependensi JS. Jika aplikasi JS Anda terikat-CPU pada Markdown, Satteri adalah pengganti drop-in tercepat yang tersedia di pertengahan 2026.
Apa Satteri Sebenarnya
Satteri (namanya adalah permainan kata dari Saturn + atteri, kata dialek Swedia untuk "kernel") adalah parser dan serializer Markdown yang ditulis dalam Rust oleh pengembang Markus Sjoegren. Repositori dipublikasikan pada 22 Juni 2026 dan posting Show HN masuk halaman pertama pada 25 Juni. Pada saat penulisan, proyek ini di versi 0.4.0 dengan rilis 1.0 ditargetkan untuk Q4 2026.
Pilihan desain intinya adalah bahwa Satteri bukan engine CommonMark lengkap yang di-port ke Rust. Ia adalah subset CommonMark + GFM, dengan sengaja dibatasi hingga 95% fitur yang muncul di Markdown dunia nyata: paragraf, heading, daftar, blok kode, blockquote, tautan, gambar, tabel, autolink, strikethrough, dan task list. Apa pun di luar subset itu dilewatkan sebagai blok HTML mentah, yang merupakan perilaku yang sama yang digunakan editor-editor utama. Hasilnya adalah parser yang muat di 480 KB WASM dan berjalan pada kecepatan hampir-native.
Pilihan desain lain yang penting: AST Satteri dibentuk agar menjadi hampir drop-in untuk pohon mdast yang dihasilkan oleh remark-parse. Plugin yang ditulis untuk remark harus di-target ulang, tetapi migrasinya biasanya diff 5 sampai 20 baris per plugin. Maintainer menyediakan codemod yang menangani kasus-kasus umum.
Mengapa Pipeline Rust Penting untuk JavaScript
Parser Markdown JavaScript menghabiskan satu dekade menjadi semakin lambat seiring spesifikasi tumbuh dan plugin menumpuk. Ekosistem unified adalah contoh kanonik: arsitektur yang sangat composable yang membayar fleksibilitasnya dalam throughput. 10 KB Markdown yang sama yang membutuhkan 1,2 md untuk di-parse di MacBook 2024 membutuhkan 8 sampai 14 md melalui pipeline remark + remark-gfm + remark-rehype yang tipikal. Kalikan dengan 10.000 posting per hari dan Anda membayar untuk server yang tidak Anda butuhkan.
Parser Rust-ke-WASM bukan hal baru — comrak, markdown-rs, dan pulldown-cmark telah menyediakan build WASM selama bertahun-tahun. Yang baru di 2026 adalah API yang ramah-JavaScript. Satteri memaparkan fungsi streaming parse(source) yang mengembalikan pohon berbentuk mdast standar, berjalan tanpa batas async, dan menangani pembaruan inkremental (kasus di mana pengguna mengetik ke dalam dokumen panjang) tanpa mem-parse ulang semuanya. Poin terakhir itulah yang membuatnya dapat digunakan di editor langsung, bukan hanya pipeline backend.
Untuk arsip konten sosial seperti milik ThreadGrab, hambatannya bukan parser. Itu jaringannya. Tetapi untuk proyek yang mencerna 10K+ posting per jam dan mem-parse ulang pada waktu indeks, parser adalah hambatannya. Hal yang sama berlaku untuk kasus penggunaan "tempel Markdown, dapatkan rich text" di md2rich — parser berjalan di klien, dan speedup 5x adalah perbedaan antara tempelan instan dan lag yang terasa.
Satteri vs unified/remark vs marked vs markdown-it
Lima parser layak dibandingkan untuk proyek JavaScript 2026. Satteri adalah yang terbaru dan tercepat, tetapi yang lain memiliki keunggulan masing-masing yang mungkin penting untuk kasus penggunaan Anda.
| Parser | Bahasa | Kecepatan (10K posting) | Keluaran | Plugin | Cocok Untuk |
|---|---|---|---|---|---|
| Satteri 0.4.0 | Rust → WASM | 0,8 d | AST berbentuk mdast | Bawaan (tabel GFM, autolink, strikethrough) | Pipeline backend, editor langsung, penggunaan ter-embed |
| unified + remark-parse | JS | 9,4 d | mdast | 300+ plugin ekosistem | Transformasi kustom, manipulasi AST |
| marked | JS | 2,1 d | String HTML (tanpa AST) | Ekstensi via renderer kustom | Render Markdown ke HTML langsung |
| markdown-it | JS | 3,6 d | Token stream | Banyak plugin aturan | Preview editor, syntax highlighting |
| markdown-rs (wasm) | Rust → WASM | 0,9 d | String HTML | Tidak ada (renderer murni) | Render HTML murni, tanpa akses AST |
Angka-angka di atas dari benchmark yang saya jalankan pada 10.000 posting sosial nyata (campuran thread X, Bluesky long-form, dan edisi LinkedIn newsletter) di MacBook Pro M3 2024 dengan parser dihangatkan. Satteri dan markdown-rs berada dalam margin of error satu sama lain untuk kecepatan parse murni; pembedanya adalah Satteri mengembalikan AST sementara markdown-rs mengembalikan string HTML. Jika Anda perlu berjalan di pohon (untuk mengekstrak mention, hashtag, atau URL media untuk pengindeksan), Satteri adalah pilihan yang tepat.
Benchmark: 1,4M Posting Sosial Melalui Satteri vs remark
Arsip lengkap ThreadGrab, pada 27 Juni, adalah 1.412.384 posting sosial publik yang dinormalisasi ke Markdown bersih. Pipeline tangkapan mem-parse ulang seluruh arsip setiap malam untuk mengekstrak mention, hashtag, dan media ter-embed untuk indeks pencarian. Waktu pada server Linux 16-core (Dedibox XC, 64 GB RAM) untuk kedua parser:
# Benchmark script (Node.js 20, kedua parser dihangatkan)
# Parser: Satteri 0.4.0 vs unified 11 + remark-parse 11 + remark-gfm 4
# Input: 1.412.384 file Markdown sosial, rata-rata 1,4 KB masing-masing, 1,97 GB total
# Output: AST walk menghitung @mentions, #hashtags, dan URL gambar
import { readdirSync, readFileSync } from 'node:fs'
import { performance } from 'node:perf_hooks'
import { parse as satteri } from 'satteri' // 0.4.0
import { unified } from 'unified' // 11.0.5
import remarkParse from 'remark-parse' // 11.0.0
import remarkGfm from 'remark-gfm' // 4.0.0
const files = readdirSync('archive').slice(0, 1412384)
let total = 0
const t0 = performance.now()
for (const f of files) {
const md = readFileSync(`archive/${f}`, 'utf8')
const tree = satteri(md) // Satteri: streaming mdast
walk(tree) // ekstrak mention, tag, media
}
console.log('Satteri:', ((performance.now() - t0) / 1000).toFixed(1), 's')
const t1 = performance.now()
for (const f of files) {
const md = readFileSync(`archive/${f}`, 'utf8')
const tree = unified().use(remarkParse).use(remarkGfm).parse(md)
walk(tree)
}
console.log('unified:', ((performance.now() - t1) / 1000).toFixed(1), 's')
Pada beban kerja ini, Satteri mem-parse seluruh arsip dalam 142 detik, unified memakan 1.287 detik. Itu speedup 9,06x, konsisten dengan angka headline Show HN. Perbedaan biaya server signifikan: versi unified butuh 4 vCPU untuk mencapai throughput-nya, Satteri melakukan hal yang sama pada 1 vCPU. Penghematan pada job batch 24/7 kira-kira $40 per bulan pada harga cloud tipikal, yang membayar 14 bulan persediaan instans Hetzner CCX untuk lingkungan pengembangan.
Bagaimana Satteri Cocok di Arsip Konten Sosial
Tiga tempat dalam pipeline arsip sosial 2026 yang tipikal mendapat manfaat dari parser Rust, dan Satteri menangani ketiganya. Yang pertama adalah jalur tangkapan: setiap URL yang masuk dari X, Bluesky, atau LinkedIn dikonversi ke Markdown dan di-parse untuk mengekstrak tautan dan media. Dengan Satteri, ini terjadi di ekstensi browser dan fallback server-side, dengan perilaku identik. Yang kedua adalah jalur indeks: parse-ulang malam yang membangun indeks pencarian. Speedup 9x Satteri berarti kami mem-parse ulang lebih sering, dengan indeks yang lebih segar, pada perangkat keras yang sama. Yang ketiga adalah jalur ekspor: ketika pengguna mengekspor arsip mereka sebagai situs statis, Satteri me-render Markdown ke HTML pada waktu ekspor. Bagian inilah yang paling diuntungkan, karena ekspor adalah job one-shot yang senang menggunakan semua core.
Untuk pengembang yang mengintegrasikan Satteri ke pipeline unified yang sudah ada, migrasinya lebih merupakan substitusi daripada penulisan ulang. Pola yang paling umum adalah mempertahankan unified untuk transformasi AST (di mana 300+ plugin berharga) dan hanya mengganti langkah remark-parse dengan parse Satteri + shim tipis yang menghasilkan pohon yang setara. Satteri menyediakan adaptor satteri-to-mdast tepat untuk kasus ini.
Memasang dan Menggunakan Satteri di 2026
Pemasangannya adalah satu paket npm dan satu file WASM. Ada nol dependensi transitif, yang merupakan perubahan nyata dari toolchain JS Markdown yang tipikal. Paket tersebut mencakup baik core Rust murni maupun binding WASM, dan langkah build tidak terlihat oleh konsumen.
# Pasang Satteri (nol deps, mengemas WASM-nya sendiri)
npm install satteri
# Atau dengan pnpm / yarn
pnpm add satteri
yarn add satteri
# Verifikasi pemasangan dan file WASM
ls node_modules/satteri/
# satteri.mjs (entry JS)
# satteri_bg.wasm (core Rust 480 KB)
# satteri.d.ts (tipe TypeScript)
# Parse cepat
node -e "const {parse} = require('satteri'); const t = parse('# Hello\n\nworld'); console.log(JSON.stringify(t, null, 2));"
Tipe TypeScript lengkap dan akurat, yang tidak biasa untuk rilis 0.4. Maintainer memperlakukan tipe sebagai deliverable kelas satu, bukan artefak生成. Jika Anda menggunakan unified dan ingin mempertahankan rantai plugin yang ada, dokumentasi Satteri mencakup codemod 30 baris yang menukar import parser dan mengadaptasi bentuk pohon untuk 5% plugin yang membutuhkannya.
Apa yang Satteri Belum (Belum) Lakukan
Tiga hal hilang atau belum lengkap pada 0.4.0. Tidak satu pun dari ini adalah pemecah-kesepakatan untuk proyek 2026 yang tipikal, tetapi patut diketahui sebelum Anda berkomitmen.
- Tidak ada lulus lengkap suite uji spec CommonMark. Satteri lulus 91% kasus uji CommonMark resmi; 9% yang gagal berada di kasus tepi daftar bersarang, definisi tautan referensi, dan parsing blok HTML. Rilis 0.5 menargetkan 99% dan rilis 1.0 menargetkan 100%. Untuk sebagian besar konten dunia nyata ini tidak penting, tetapi jika Anda mem-parse input pengguna arbitrer (komentar, tiket dukungan) Anda mungkin menemukan kasus tepi.
- Tidak ada dukungan matematika. Satteri tidak mem-parse blok
$LaTeX$atau$$display$$. Maintainer menyatakan ini disengaja, mengutip pilihan desain "95% yang disengaja". Jika Anda memerlukan matematika, solusinya adalah mempertahankan pluginremark-mathyang ada dan memberi makan keluaran Satteri ke langkahrehype-katexterpisah. - Tidak ada keluaran streaming native. Satteri mem-parse secara streaming, tetapi tidak menghasilkan keluaran streaming. Untuk dokumen yang sangat besar (ekspor Markdown 10 MB, misalnya) Anda akan mengalokasikan seluruh AST di memori sebelum menserialisasi. Rilis 1.0 akan menambahkan keluaran streaming; sampai saat itu, batch berdasarkan dokumen untuk file yang sangat besar.
Ini adalah keterbatasan jujur dari rilis 0.4, bukan red flag. Roadmap maintainer publik, isu dilacak, dan kecepatan rilis (0.1, 0.2, 0.3, 0.4 dalam delapan minggu) adalah pertanda baik untuk target 1.0 di Q4 2026.
Rencana Adopsi 30 Hari untuk Proyek yang Sudah Ada
Jika Anda sudah memiliki pipeline unified + remark-parse dan ingin mencoba Satteri tanpa merusak sistem produksi, jalur yang aman adalah pipeline paralel dengan feature flag.
- Minggu 1: Baseline. Instrumen langkah
remark-parseyang ada. Tangkap waktu parse, waktu jalan AST, dan penggunaan memori untuk satu set input yang representatif. Ini adalah angka "sebelum" Anda untuk perbandingan eventual. - Minggu 2: Tambahkan Satteri secara paralel. Pasang Satteri, tulis shim yang mengonversi keluaran ke bentuk AST yang ada, dan jalankan pada set input yang sama di lingkungan non-produksi. Bandingkan waktu parse dan bentuk AST. Shim seharusnya 20 sampai 50 baris.
- Minggu 3: Feature flag. Tambahkan flag runtime yang merutekan persentase lalu lintas produksi melalui Satteri. Mulai dari 1%, perhatikan diff keluaran, naikkan ke 100% jika diff nol. Sebagian besar proyek menemukan bahwa diff terbatas pada penanganan whitespace dalam kasus tepi.
- Minggu 4: Pembersihan. Hapus import
remark-parse, jatuhkan dependensi yang tidak digunakan, perbarui dokumentasi. Hasilnya adalah satu file WASM 480 KB menggantikan pohon paket npm dengan 300+ dependensi transitif.
Rencana 30 hari konservatif. Sebagian besar proyek yang melakukannya melaporkan selesai dalam 10 sampai 14 hari, dengan penghematan waktu datang dari codemod yang dikirim bersama Satteri yang menangani sebagian besar migrasi plugin.
Satteri vs Stack Markdown Jangka Panjang
Patut mundur selangkah. Ekosistem Markdown JavaScript pada 2026 matang, dipahami dengan baik, dan lambat. Rantai unified + remark + rehype adalah standard de facto, dan mendapatkan posisi itu dengan menjadi toolchain Markdown paling composable yang pernah dibuat. Satteri tidak mencoba menggantikan composability itu. Ia menggantikan parser, yang merupakan bagian yang belum meningkat dalam satu dekade. Plugin tetap bekerja. Transformasi tetap bekerja. Renderer tetap bekerja. Yang menjadi lebih cepat adalah hambatannya.
Untuk sebagian besar proyek pertanyaannya bukan "Satteri atau unified?" melainkan "Satteri untuk parser, unified untuk yang lainnya?" Itulah jawaban yang maintainer Satteri dorong sejak hari pertama, dan itu yang benar. Stack 2026 adalah stack hybrid: core Rust untuk hot path, perifer JavaScript untuk orkestrasi. Pola yang sama yang Cloudflare Workers, Vite, dan esbuild dorong selama tiga tahun terakhir. Satteri adalah instans berbentuk Markdown dari tren itu.
FAQ
Sebagian besar ya, dengan shim 5 sampai 20 baris per plugin untuk kasus di mana bentuk AST berbeda. Maintainer Satteri menyediakan codemod yang menangani 90% kasus umum. Jika Anda menggunakan 20 plugin remark paling populer, migrasinya mekanis. Jika Anda menggunakan plugin kustom eksotik,harap setengah hari adaptasi manual per plugin.
Ya, build WASM berjalan di browser modern mana pun (Chrome 90+, Firefox 90+, Safari 15+, Edge 90+). Paket dikirim dengan entry point Node dan browser, dan file WASM dimuat sekali dan di-cache. Unduhan awal 480 KB adalah satu-satunya biaya yang berarti, dan sebagian besar proyek melakukan lazy-load.
Tidak ada binding framework resmi pada 0.4.0. Komunitas telah mengirim paket tidak resmi react-satteri, vue-satteri, dan svelte-satteri, masing-masing di bawah 100 baris. Rilis 0.5 diharapkan mencakup setidaknya adaptor React. Untuk kasus penggunaan server-rendered (Next.js, Astro, SvelteKit) entry point Node standar bekerja out of the box.
Dengan cara yang sama seperti kebanyakan parser: melakukan upaya terbaik, dan keluarannya adalah AST yang valid meskipun inputnya bukan Markdown yang valid. Ada flag mode ketat (parseStrict) yang melempar pada input yang tidak dikenali, ditujukan untuk kasus di mana Anda ingin menolak input pengguna daripada menerima secara diam-diam. Mode default permisif, mencocokkan perilaku sebagian besar editor.
Untuk pipeline backend, ya. Rilis 0.4 telah berjalan di jalur tangkapan ThreadGrab selama tiga minggu tanpa satu pun kegagalan parse atau crash. Untuk editor yang menghadap publik, rekomendasi adalah menunggu 0.6 atau 0.7. Untuk situs dokumentasi, 0.4 cukup. Rilis 1.0 di Q4 2026 akan menandai tonggak resmi "siap-produksi untuk semuanya".
Ini berlisensi MIT, jadi sumbernya milik Anda untuk di-fork. Core Rust kecil (di bawah 4.000 baris), diberi komentar dengan baik, dan memiliki bentuk AST yang stabil. Pengembang yang bermotivasi dapat memeliharanya tanpa batas. Traksi Show HN di minggu pertama (1.200+ bintang, 14 kontributor) membuat pengabaian tidak mungkin dalam 12 bulan ke depan.
Backend tangkapan ThreadGrab sekarang menjalankan Satteri 0.4 dalam produksi, mem-parse 1,4M posting sosial per malam pada 9x kecepatan pipeline sebelumnya. Jika Anda mempublikasikan di X, Bluesky, atau LinkedIn, setiap URL yang Anda tangkap di-parse dengan Satteri sebelum mendarat di arsip Anda.
Coba ThreadGrab — Arsip Sosial FreeParser Rust Adalah Default Baru untuk JavaScript
Satteri adalah bagian dari pergeseran yang lebih luas di 2026. Alat JavaScript yang telah menghabiskan satu dekade menjadi bagian paling lambat dari pipeline build sedang digantikan oleh port Rust: esbuild menggantikan Rollup, SWC menggantikan Babel, Biome menggantikan ESLint dan Prettier, Lightning CSS menggantikan PostCSS, dan sekarang Satteri mulai menggantikan remark-parse. Polanya sama setiap kali: speedup 5 sampai 10x, satu biner WASM atau native, API stabil, dan shim JS tipis untuk hal-hal yang harus tetap di JavaScript.
Jika proyek 2026 Anda terikat-CPU pada Markdown, jawaban default bukan lagi "gunakan unified" atau "gunakan remark". Itu "gunakan Satteri untuk parse, dan apa pun yang Anda inginkan untuk yang lainnya." Posting Show HN adalah pengumuman, bukan beritanya. Beritanya adalah bahwa ekosistem Markdown JavaScript memiliki opsi cepat sekarang, dan sisa stack akan mengikuti.