Kalian akan belajar mengimpor grammar dan theme lokal, mendaftarkan hanya bahasa yang benar-benar dipakai, serta menekan ukuran bundle dengan pemilihan langs dan themes yang selektif dan lazy loading.

Shiki mengemas ratusan bahasa dan puluhan theme. Memuat semuanya akan membebani bundle, padahal kebanyakan proyek hanya memakai segelintir bahasa. Di episode ini kalian belajar mengelola langs dan themes agar bundle tetap ringan tanpa kehilangan kemampuan.
Episode 12 membahas cara mengimpor grammar dan theme lokal, mendaftarkan bahasa secara selektif, memakai alias bahasa, serta strategi lazy loading. Dengan pengelolaan yang tepat, build-time Shiki tetap cepat dan bundle statis kalian tidak membengkak.
Setiap grammar adalah file TextMate yang berisi ratusan aturan regex. Memuat semua grammar sekaligus memperlambat startup dan menambah ukuran bundle. Shiki menyadari hal ini dan menyediakan beberapa titik kontrol: dari bundle penuh, bundle web, hingga impor per-bahasa.
Sejak v4, bahasa dan theme dipisah menjadi package @shikijs/langs dan @shikijs/themes. Ini memungkinkan bundler memecah file per bahasa sehingga hanya yang dibutuhkan yang diunduh.
shiki/bundle/full memuat semua bahasa dan theme, cocok untuk tooling generik.shiki/bundle/web memuat bahasa web populer seperti HTML, CSS, JavaScript, TypeScript, dan JSON.shiki/core tidak memuat apa pun, semua harus diimpor manual.Untuk blog atau dokumentasi, shiki/bundle/web biasanya sudah cukup. Pilih shiki/core hanya jika ukuran bundle sangat kritis.
Grammar bukan hanya dari bundle; kalian bisa memuat .tmLanguage.json sendiri. Baca file lalu masukkan objek grammar ke array langs:
import { createHighlighter } from "shiki";
import { readFileSync } from "node:fs";
const grammar = JSON.parse(
readFileSync("./grammars/my-lang.tmLanguage.json", "utf8"),
);
const highlighter = await createHighlighter({
langs: [grammar],
themes: ["github-dark-default"],
});Objek grammar boleh membawa name, scopeName, dan embeddedLangs. Setelah terdaftar, kalian bisa memakai nama grammar sebagai bahasa di codeToHtml.
Theme adalah objek TextMate dengan properti name, type, dan settings. Kalian bisa menulisnya langsung atau membaca dari file JSON:
const myTheme = {
name: "my-theme",
type: "dark",
settings: [
{
scope: ["comment"],
settings: { foreground: "#8b949e" },
},
],
};
const highlighter = await createHighlighter({
langs: ["typescript"],
themes: [myTheme],
});Theme kustom berguna ketika brand kalian punya palet sendiri. Strukturnya standar TextMate, sehingga tool seperti VSCode bisa menghasilkan file ini.
Di rehype-pretty-code, kalian mendaftarkan bahasa dan theme lewat opsi langs dan themes:
const options = {
theme: "github-dark-default",
langs: ["ts", "tsx", "js", "css", "json", "bash"],
themes: ["github-dark-default", "github-light-default"],
};Opsi langs menerima daftar id bahasa yang akan di-highlight di seluruh konten. Bahasa di luar daftar ini akan dirender tanpa warna, jadi pastikan daftarnya mencakup semua bahasa yang muncul di artikel kalian.
Beberapa penulis memakai alias singkat seperti js atau py. Shiki sudah mengenal alias umum, tetapi untuk nama kustom kalian bisa mendaftarkan langAlias:
const highlighter = await createHighlighter({
langs: ["javascript", "typescript"],
langAlias: {
mylang: "typescript",
},
themes: ["github-dark-default"],
});Dengan langAlias, kalian bisa menulis fenced code block dengan meta bahasa mylang dan Shiki memetakannya ke TypeScript. Fitur ini membuat penulis tetap nyaman dengan istilah internal proyek.
Gunakan fungsi impor dinamis agar bundler memecah bahasa menjadi chunk terpisah yang hanya dimuat saat dibutuhkan:
import { createHighlighterCore } from "shiki/core";
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
const highlighter = await createHighlighterCore({
themes: [
import("@shikijs/themes/github-dark-default"),
],
langs: [
import("@shikijs/langs/typescript"),
() => import("@shikijs/langs/javascript"),
],
engine: createOnigurumaEngine(import("shiki/wasm")),
});Perhatikan shiki/core di sini tidak memuat bahasa atau theme apa pun. Setiap import dinamis menjadi chunk terpisah, sehingga hanya grammar yang benar-benar dipakai yang diunduh.
Bandingkan ukuran bundle sebelum dan sesudah seleksi. Perintah bun run build akan menampilkan laporan size di terminal. Setelah selektif, ukuran chunk grammar biasanya turun drastis dibanding bundle penuh yang bisa mencapai megabyte dalam bentuk tidak terkompresi.
Inti yang harus dibawa pulang:
shiki/bundle/full dan shiki/bundle/web menyediakan preset yang siap pakai.langs dan themes.langAlias memetakan nama bahasa kustom ke grammar yang sudah terdaftar.shiki/core plus impor dinamis membuat tiap bahasa menjadi chunk terpisah.Di episode 13 kalian akan belajar performa dan bundle optimization: mekanisme loading WASM Oniguruma, memilih engine seperti @shikijs/engine-oniguruma, perbedaan highlight di build-time dan client-side, serta caching grammar untuk menghindari render ulang yang mahal.