Kalian akan menginstal shiki dan rehype-pretty-code, lalu menyusun pipeline minimal unified yang mengubah Markdown menjadi HTML dengan syntax highlighting. Di akhir episode ada code block pertama yang siap dipakai di proyek kalian.

Teori arsitektur di episode 2 sudah cukup. Sekarang kalian akan mengotori tangan dengan kode nyata. Episode 3 adalah setup dan hello world: menginstal dependency, menyusun pipeline minimal, dan melihat HTML highlight pertama yang dihasilkan dari Markdown biasa.
Target akhir episode ini sederhana tapi penting: sebuah script Node.js yang mengubah string Markdown berisi code block menjadi HTML lengkap dengan syntax highlighting. Dari titik ini kalian bisa menguji setiap opsi yang dibahas di episode-episode berikutnya.
Mulai dari folder kosong. Inisialisasi proyek dengan npm atau bun, lalu instal dua package utama. Keduanya ESM-only, jadi pastikan nilai "type": "module" ada di package.json.
mkdir learn-shiki
cd learn-shiki
npm init -y
npm i shiki rehype-pretty-codePackage rehype-pretty-code menarik shiki sebagai dependency, tetapi memasangnya secara eksplisit memudahkan kalian mengatur versi dan memakai API Shiki langsung bila diperlukan. Sebaiknya selalu pasang keduanya supaya versi yang dipakai jelas.
Selain dua package utama, pipeline unified butuh plugin-plugin resmi dari ekosistem unified:
npm i unified remark-parse remark-rehype rehype-stringifyunified adalah inti pipeline, remark-parse mengubah Markdown menjadi pohon MDAST, remark-rehype mengubahnya ke HAST, dan rehype-stringify menghasilkan string HTML akhir. Tanpa keempatnya, rehype-pretty-code tidak punya panggung untuk bekerja.
Buat file highlight.mjs dengan isi berikut. Pipeline ini menerima teks Markdown dan mengembalikan HTML yang sudah di-highlight.
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypePrettyCode from "rehype-pretty-code";
import rehypeStringify from "rehype-stringify";
const md = [
"```ts",
'const pesan: string = "Halo Shiki";',
"console.log(pesan);",
"```",
].join("\n");
const html = await unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypePrettyCode, { theme: "github-dark-default" })
.use(rehypeStringify)
.process(md);
console.log(html.toString());Perhatikan urutan .use() yang harus pas: parse, lalu konversi ke HAST, lalu rehype-pretty-code, terakhir stringify. rehypePrettyCode(options) dipasang tepat sebelum rehypeStringify.
Jalankan script untuk melihat HTML yang dihasilkan:
node highlight.mjsOutput akan berisi <pre> dan <code> dengan banyak <span> ber-style warna. Di sinilah keajaiban terjadi: kode TypeScript sudah ditokenisasi dan diberi warna tanpa satu pun JavaScript yang berjalan di browser.
Untuk melihat hasil visualnya, ubah script agar menulis output ke file output.html lalu buka di browser:
import { writeFile } from "node:fs/promises";
const hasil = await unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypePrettyCode, { theme: "github-dark-default" })
.use(rehypeStringify)
.process(md);
await writeFile("output.html", hasil.toString());node highlight.mjs
xdg-open output.htmlDi browser, kalian akan melihat kode berwarna sesuai theme github-dark-default. Buka DevTools dan periksa struktur elemen: setiap token dibungkus <span> dengan warna inline. Struktur ini nanti akan berubah sedikit setelah rehype-pretty-code menambahkan data attributes di episode 4.
Jika kalian melihat teks tanpa warna, kemungkinan besar pipeline tidak menjalankan rehype-pretty-code sama sekali, atau nama theme yang dipakai salah. Periksa kembali urutan plugin dan ejaan nama theme.
Inti yang harus dibawa pulang:
rehypePrettyCode dipasang setelah remarkRehype dan sebelum rehypeStringify.Di episode 4 kalian akan membedah options dasar rehype-pretty-code: theme, keepBackground, defaultLang, grid, dan bypassInlineCode, plus memahami struktur <figure>, <pre>, dan <code> beserta data attributes yang dihasilkan. Semua opsi itu nanti akan membentuk cara kalian menyajikan kode.