ShikiPHP
Pure PHP syntax highlighter, a port of Shiki. Style code blocks with VS Code themes and TextMate grammars without Node; output matches Shiki 3.23.0 across 214 oracle scenarios.
composer require shikiphp/shikiphpLatest release v0.1.0 MIT PHP 8.2+ with ext-json and ext-mbstring
use Shikiphp\Shikiphp;
echo Shikiphp::codeToHtml("\e[31merror\e[0m: something broke", [
'lang' => 'ansi',
'theme' => 'github-dark',
]);In practice
Highlight a snippet from a PHP template or build script and print the HTML it returns.
One call per code block
Shikiphp::codeToHtml takes the code, a language id and a theme id. It returns a complete pre block with the colours written inline, so it renders without an extra stylesheet.
Pass a themes map instead of theme and the same block carries light and dark colours through CSS variables.
use Shikiphp\Shikiphp;
echo Shikiphp::codeToHtml(<<<'PHP'
<?php
function greet(string $name): string {
return "Hello, {$name}!";
}
PHP, [
'lang' => 'php',
'theme' => 'github-dark',
]);use Shikiphp\Shikiphp;
$code = 'const answer: number = 42';
echo Shikiphp::codeToHtml($code, [
'lang' => 'ts',
'themes' => ['light' => 'github-light', 'dark' => 'github-dark'],
]);Real TextMate Grammars
A faithful port of vscode-textmate: embedded languages, injections, and nested repositories. The same grammars Shiki and VS Code tokenize with.
VS Code Themes
Scope-selector specificity and parent-scope matching, ported from vscode-textmate. Single theme or dual light/dark via CSS variables.
Shiki-Identical Output
214 oracle scenarios, covering 167 of the 253 bundled grammars, ANSI and all 65 themes, match the HTML of Shiki 3.23.0 with its JavaScript regex engine, exact apart from leading and trailing whitespace.
Pure-PHP Regex Engine
A vendored JavaScript RegExp engine from inline0/phasis, fed by an oniguruma-to-es port. Shiki's JavaScript regex engine takes the same Oniguruma to RegExp path.
Transformers
Every Shiki hook (preprocess, tokens, root, pre, code, line, span, postprocess) plus the built-in notation, meta, and whitespace transformers.
The Full Bundle
Every tm-grammars language (235, plus 18 helper grammars) and tm-themes theme (65) ships in the box. ANSI terminal output, decorations, and colorReplacements included.
CLI
Highlight a file to HTML, or list bundled languages and themes, straight from the command line with bin/shikiphp.
No Node
Runs on PHP 8.2+ with only ext-json and ext-mbstring. No Node runtime, no native Oniguruma binding, no shelling out.
Why ShikiPHP
Runs where your PHP runs
Highlighting happens inside the PHP process, without shelling out to Node or calling a hosted API. That suits a Laravel, WordPress or static-site build step.
Output that caches
The same code with the same options always produces the same HTML. Highlight at build time, or cache the HTML keyed by code and options until the source changes.
One block for light and dark
A themes map writes the second theme as CSS variables on the same markup, and a few lines of CSS switch to it. The defaultColor option picks which theme is written inline.
Limits for untrusted input
The regex engine memoizes failures and guards against ReDoS, so a pathological pattern degrades instead of hanging. The tokenizeMaxLineLength option emits overlong lines as one plain token.
Compared with
Other ways to highlight code for a PHP site, and where ShikiPHP differs.
| Tool | Good at | Difference with ShikiPHP |
|---|---|---|
| Shiki | Good atThe reference implementation, in JavaScript. It works in any modern JavaScript runtime without Node.js APIs, loads grammars and themes on demand, and has TypeScript Twoslash integrations. | Difference with ShikiPHPShikiPHP ports that pipeline to PHP for pages rendered on a PHP server. Its oracle harness compares its HTML with Shiki 3.23.0, while Shiki's main branch has moved on to v4. |
| Phiki | Good atA PHP highlighter that also uses TextMate grammars and VS Code themes. It ships a league/commonmark extension that works with Laravel's Str::markdown, terminal output and a command-line binary. | Difference with ShikiPHPPhiki describes its tokenizer as inspired by vscode-textmate but not a 1-1 translation. ShikiPHP ports vscode-textmate and oniguruma-to-es and tests its HTML against Shiki's output in 214 oracle scenarios. |
| highlight.php | Good atA server-side PHP port of highlight.js that supports 185 languages with the original language and style definitions, and can detect the language automatically. | Difference with ShikiPHPShikiPHP tokenizes with TextMate grammars and colours with VS Code themes, the same files Shiki uses, and every call names its language. |
| Torchlight | Good atA VS Code-compatible highlighting service. It is an HTTP API with comment annotations for highlights, focus and diffs, and has first-party clients for Laravel, CommonMark, Statamic and other stacks. | Difference with ShikiPHPShikiPHP runs inside your PHP process with no hosted API. Its built-in notation transformers read comparable comments for highlighted, focused and diff lines. |
Sources, checked
Questions and answers
Short answers from the ShikiPHP documentation.
Pass a themes map with light and dark entries. The light colours are written inline and the dark ones as --shiki-dark variables, which a short CSS rule scoped to html.dark .shiki activates. Set defaultColor to false to emit only variables.
Every grammar from tm-grammars 1.31.15, 235 languages plus 18 helper grammars, and all 65 themes from tm-themes. Run vendor/bin/shikiphp langs or vendor/bin/shikiphp themes to list the ids, or call bundledLanguages() and bundledThemes() on the highlighter.
Yes. Decode the .tmLanguage.json file and register it with loadGrammar, giving an id and optional aliases, or register a VS Code theme with loadTheme. Register any grammar it includes or embeds first.
The regex engine has failure memoization and ReDoS protection, so a pathological pattern degrades rather than hangs. Set tokenizeMaxLineLength to emit a single plain token for any line at or beyond that length.
The docs advise against it. Highlight at build time for static pages, or cache the rendered HTML keyed by code and options. Within a process, reuse one highlighter, which the Shikiphp facade does for you.
The oracle harness compares ShikiPHP's HTML with Shiki 3.23.0 using Shiki's JavaScript regex engine. Its 214 scenarios cover 167 of the 253 bundled grammars, ANSI and all 65 themes, and the options and built-in transformers have their own parity tests.
Start with the getting started guide, then add transformers, custom grammars or ANSI output when your pages need them.