Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Shiki Php Laravel Package

spatie/shiki-php

Bring Shiki's beautiful syntax highlighting to PHP. A simple static call highlights code using the same language engine as popular code editors, with 100+ languages and themes plus bundled Antlers and Blade support.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • spatie/shiki-php is a thin PHP facade over the Shiki JavaScript highlighter: PHP builds arguments/stdin, shells out to a Node renderer script shipped with the package, and returns HTML (<pre class="shiki">...).
  • Framework-agnostic, but the Laravel story is the real product: first-class path through spatie/laravel-markdown and spatie/commonmark-shiki-highlighter, plus bundled Blade and Antlers grammars. If our content pipeline already uses Spatie's markdown stack, this drops into fenced code blocks with near-zero glue code.
  • It is a presentation-layer concern only: no models, no migrations, no service container coupling. Low architectural blast radius.

Integration feasibility

  • Two dependency ecosystems for one capability: composer require spatie/shiki-php and npm install shiki, plus Node 20+ on any host that executes highlighting.
  • Trivial in a containerized Laravel deploy we control; awkward in PHP-only CI, shared hosting, or teams without Node in their image.
  • API surface is a single static call plus line markers (highlightLines, addLines, deleteLines, focusLines) and theme/language introspection. Time-to-first-highlight is hours, not days.

Technical risk

  • Runtime Node dependency. Binary discovery is heuristic (/usr/local/bin, /opt/homebrew/bin, NVM symlinks). NVM users must symlink; this has generated repeated patch releases (1.1.6, 1.1.7). Node version drift is the top recurring failure class.
  • Silent degradation. Per the README, if the npm shiki package is absent the <pre> element is not present in output — a styling regression, not an exception. Requires an explicit CI assertion and deploy smoke test.
  • Version coupling. Package majors track Shiki majors (2.0.0 → Shiki v1, 2.3.0 → v2, 2.4.0 → v4, skipping v3). Our npm pin and composer pin must move together; treat them as one logical dependency.
  • API churn in a small surface. Introspection methods were removed in 2.0.0 and re-added in 2.1.0. Signals willingness to break; low effort to absorb, but budget for it.
  • Subprocess cost. One child process per highlighted block, no built-in cache. Large-block failures (posix_spawn argument-list overflow) were fixed only in 2.3.3 by switching to stdin — pin ≥ 2.3.3.
  • Security surface. The theme parameter accepts an absolute filesystem path (custom VSCode themes). Never pass user-controlled values; constrain to an allowlist. Output is escaped by Shiki, but treat generated HTML as trusted markup, not user input.
  • Ecosystem validation is thin (315 stars, 0 dependents in our data). Mitigated by MIT license, Spatie's maintenance record, and the fact that the wrapper is small enough to vendor if it stalls.

Key questions

  1. Is highlighting computed at authoring time (stored HTML) or per request? This determines whether Node ships in the web runtime at all.
  2. Which Shiki npm major do we pin, and who owns the joint composer+npm upgrade?
  3. Do we need dual light/dark themes (supported since 2.2.0, custom dual themes fixed in 2.4.0)?
  4. What is the mandated fallback when the subprocess fails — escaped <pre><code> or client-side highlighting?
  5. Is proc_open available and permitted on the target host?
  6. Have we evaluated Torchlight (hosted API) as the buy-vs-build alternative for read-time highlighting?

Integration Approach

Stack fit

  • Laravel 10/11/12, PHP ≥ 7.4 (7.4 dropped in 2.3.2 — verify against our floor). CommonMark/league integration is the intended seam; Blade grammar support is directly relevant for a Laravel docs or blog surface.
  • Best fit: content sites, documentation, marketing pages — anywhere code blocks are known at publish time.
  • Weak fit: high-volume user-generated snippets on PHP-only infrastructure.

Migration path

  1. Spike (half day): one route, one Blade partial, measure cold/warm latency per block, container image size delta, and behavior with Node absent.
  2. Precompute (preferred): render during content authoring in a queued job, persist HTML keyed on hash(code, language, theme, line markers). Web runtime never touches Node for published pages.
  3. Read-time path (only if needed): behind a config flag, with a hard timeout, size cap, and raw-HTML fallback.
  4. Retain the incumbent (Prism/highlight.js/Pygments) behind a Highlighter interface until visual and performance parity is validated on a representative sample.

Compatibility

  • Pin spatie/shiki-php: ^2.4 against npm shiki v4; treat as a single joint dependency with a single upgrade ticket.
  • Node 20+ in CI runners and every runtime image that executes highlighting.
  • Dev parity: NVM users require the documented symlink, or ship an explicit node path via the customizable renderer script (available since 1.2.0).
  • Windows/devcontainer path resolution should be validated before committing if any developer runs outside Docker.

Sequencing

  1. Pin both versions; review both lockfiles.
  2. Add a CI test that highlights a PHP and a Blade snippet and asserts <pre class="shiki"> appears — this catches the silent-degradation mode.
  3. Wire into the markdown renderer seam.
  4. Add the content-hash cache and the timeout/fallback wrapper.
  5. Instrument (highlight count, duration, failure rate).
  6. Roll out to one surface (docs or blog), then expand.

Operational Impact

Maintenance

  • Dual-ecosystem upkeep: PHP package releases lag Shiki JS releases, and Shiki majors force wrapper majors. Budget a recurring, low-hours maintenance item.
  • If the wrapper goes stale, vendoring is viable — it is a small amount of PHP around a Node invocation. Abandonment risk is real but cheap to absorb.

Support

  • No official support channel; community GitHub only. Escalation is our own team.
  • Historical support burden concentrates in one area: "code block renders unstyled." Runbook entry: check Node path, Node version, and npm ls shiki in the deployed artifact.
  • No dedicated on-call impact if highlighting is precomputed; read-time rendering shifts failures into the request path.

Scaling

  • CPU-bound child process per block; cost is linear in block count and code size. Do not run on the hot path for high-traffic pages.
  • Precompute + content-hash cache makes read-time cost effectively zero and invalidation trivial (immutable input → immutable output).
  • For user-generated content, cap block size and line count, rate-limit, and queue outside the request cycle. Large blocks now traverse stdin (2.3.3) but still consume memory.

Failure modes

Failure Symptom Mitigation
Node missing / wrong version / bad path No <pre>, unstyled output CI assertion + deploy smoke test
npm shiki not installed Same silent degradation Verify npm ls shiki in artifact
Subprocess timeout or non-zero exit Broken page section Timeout wrapper + escaped <pre><code> fallback
Oversized code block Spawn failure (pre-2.3.3) Pin ≥ 2.3.3; enforce size cap
proc_open disabled Hard failure Host qualification gate
User-controlled theme path Arbitrary file read Allowlist themes
Supply chain (npm + composer) Compromise Lockfiles + SCA on both sides

Ramp-up

  • Application developer: minutes — one static call with named arguments.
  • Platform owner: moderate — Node in images, CI caching of node_modules, deploy verification.
  • Effort estimate: ~0.5 day for the spike and integration in a containerized Laravel app; 2–3 days if read-time rendering plus caching, timeouts, and fallbacks are required; effectively blocked on shared hosting or environments without Node or proc_open.

TPM recommendation Adopt for precomputed content highlighting where we control the container image — low code risk, best-in-class output, and a cheap path through the Spatie markdown stack. Do not adopt as a read-time dependency for untrusted, high-volume code blocks on PHP-only infrastructure; evaluate Torchlight or a PHP-native highlighter first. Gate the decision on answers to the Node-placement and precompute-vs-read-time questions.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table