Browser-only syntax highlighting for code blocks using Shiki.
This repo contains two pieces:
shiki-loader: a standalone browser script that findspre codeblocks on the page and highlights them with Shiki- A small Next.js demo app that showcases the loader and available themes
- Build the loader (if you're working from this repo):
bun run build:libThis produces public/shiki-loader.js.
- Include the script at the end of your HTML
body:
<script src="/shiki-loader.js" defer></script>All pre code blocks with a language class (for example language-ts, lang-js) will be highlighted automatically on page load.
The loader is configured entirely via URL query parameters on the script src.
| Parameter | Values | Default | Description |
|---|---|---|---|
theme |
Any bundled Shiki theme name | material-theme |
Base theme used in light and dark mode |
dark-theme |
Any bundled Shiki theme name | (none) | Optional dark theme, used if system is in dark |
The script automatically detects dark mode using prefers-color-scheme: dark. If dark-theme is provided and the system is in dark mode, that theme is used; otherwise theme is used.
Use the same theme in both light and dark mode:
<script src="/shiki-loader.js?theme=github-dark" defer></script>Use different themes for light and dark mode:
<script src="/shiki-loader.js?theme=github-light&dark-theme=github-dark" defer></script>The loader ships with all Shiki bundled languages. A block is highlighted when:
- It is inside a
preelement - The
codeelement has a class starting withlanguage-orlang-(for examplelanguage-ts,lang-js) - The language is part of Shiki's
bundledLanguages
If the language is not supported, a warning is logged and the block is left unchanged.
The loader exposes all Shiki bundled themes; common examples include:
github-dark,github-lightone-dark-pro,one-lightnord,night-owl,draculamaterial-theme,material-theme-darker,material-theme-lightercatppuccin-mocha,catppuccin-latte,rose-pine,rose-pine-dawn
The full list is maintained in src/shiki-loader/themes.ts.
The loader wraps each highlighted block with a small UI shell (see src/shiki-loader/transformer.ts):
- Language label in the top-left corner
- Copy-to-clipboard button with tooltip state ("Copy" → "Copied")
- All styling is injected at runtime from
loader.cssinto a<style>tag
This repository is a Next.js app using Bun.
- Bun
bun run dev– Start the Next.js dev serverbun run build– Build the Next.js appbun run start– Start the production serverbun run build:lib– Buildpublic/shiki-loader.jsfromsrc/shiki-loader/index.tsbun run lint– Run Biome checksbun run format– Format with Biomebun run type-check– Type-check the project
MIT – see LICENSE