Weave Code
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

Use Shiki syntax highlighting from PHP. Highlight code snippets with editor-quality themes and 100+ languages, plus Antlers and Blade. Works great with Laravel via spatie/laravel-markdown and CommonMark through a companion extension.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require spatie/shiki-php
    
  2. Install Node.js dependencies (Node 20+ required):

    npm install shiki
    

    or with Yarn:

    yarn add shiki
    
  3. First usage (highlight PHP code):

    use Spatie\ShikiPhp\Shiki;
    
    echo Shiki::highlight(
        code: '<?php echo "Hello World"; ?>',
        language: 'php',
        theme: 'github-light'
    );
    

Key First Use Cases

  • Markdown rendering: Integrate with spatie/laravel-markdown for syntax-highlighted Markdown.
  • Code blocks in documentation: Use in Blade templates or API responses for consistent syntax highlighting.
  • IDE-like previews: Highlight code snippets in admin panels or user-facing dashboards.

Implementation Patterns

Core Workflow

  1. Basic Highlighting:

    $highlighted = Shiki::highlight(
        code: $codeString,
        language: 'php', // or 'javascript', 'blade', etc.
        theme: 'github-dark'
    );
    
    • Output: Returns HTML-ready <pre><code> block with Shiki’s styling.
  2. Line-Specific Styling:

    Shiki::highlight(
        code: $code,
        language: 'php',
        highlightLines: [3, '5-7'], // Highlight lines 3, 5-7
        addLines: [1],               // Mark line 1 as "added"
        deleteLines: [4],            // Mark line 4 as "deleted"
        focusLines: [2]              // Focus line 2
    );
    
    • CSS Targeting: Use classes like .shiki-line-highlighted, .shiki-line-added, etc.
  3. Dynamic Language/Themes:

    $languages = Shiki::getAvailableLanguages(); // Array of supported languages
    $themes = Shiki::getAvailableThemes();       // Array of supported themes
    
    if (Shiki::languageIsAvailable('rust')) {
        $highlighted = Shiki::highlight(code: $code, language: 'rust');
    }
    

Integration Tips

  • Laravel Blade:

    @php
        $highlighted = \Spatie\ShikiPhp\Shiki::highlight(
            code: '{{ $code }}',
            language: 'blade',
            theme: 'vscode-dark-plus'
        );
    @endphp
    {!! $highlighted !!}
    
  • Markdown Parsing (via spatie/laravel-markdown):

    use Spatie\Markdown\MarkdownRenderer;
    
    $renderer = new MarkdownRenderer();
    $renderer->useShikiHighlighter(); // Auto-highlights code blocks
    echo $renderer->toHtml($markdownContent);
    
  • API Responses:

    return response()->json([
        'code' => $highlightedHtml,
        'language' => 'php',
        'theme' => 'github-light'
    ]);
    
  • Caching: Cache highlighted output for static content (e.g., documentation):

    $cacheKey = "shiki_{$language}_{$theme}_{md5($code)}";
    $highlighted = Cache::remember($cacheKey, now()->addHours(1), function() use ($code, $language, $theme) {
        return Shiki::highlight(code: $code, language: $language, theme: $theme);
    });
    

Advanced Patterns

  • Custom Themes:

    Shiki::highlight(
        code: $code,
        theme: __DIR__ . '/path/to/custom-theme.json'
    );
    
  • Dual Themes (Shiki v4+):

    Shiki::highlight(
        code: $code,
        theme: ['github-dark', 'dracula'] // Fallback themes
    );
    
  • Large Code Blocks: Avoid proc_open() errors by passing code via stdin (handled automatically in v2.3.3+).


Gotchas and Tips

Pitfalls

  1. Node.js Path Issues:

    • If using NVM, create a symlink to resolve path conflicts:
      sudo ln -s ~/.nvm/versions/node/v20.x.x/bin/node /usr/local/bin/node
      
    • Debug: Check Node path with:
      \Spatie\ShikiPhp\Shiki::getNodePath();
      
  2. Language/Theme Availability:

    • Always validate before highlighting:
      if (!Shiki::languageIsAvailable('custom-lang')) {
          throw new \InvalidArgumentException("Language not supported");
      }
      
  3. Large Code Blocks:

    • Error: proc_open(): posix_spawn() failed: Argument list too long
    • Fix: Upgrade to spatie/shiki-php v2.3.3+ (uses stdin for large inputs).
  4. Blade/Antlers Syntax:

    • Ensure the package is updated (some versions had missing grammar files; see #31).
  5. CSS Conflicts:

    • Shiki’s output includes inline styles. Override with:
      .shiki pre {
          background: transparent !important;
      }
      

Debugging Tips

  • Verbose Output: Enable debug mode to see Node command execution:

    \Spatie\ShikiPhp\Shiki::setDebug(true);
    
  • Check Node Version:

    $nodeVersion = \Spatie\ShikiPhp\Shiki::getNodeVersion();
    if (version_compare($nodeVersion, '20.0.0', '<')) {
        throw new \RuntimeException("Node 20+ required");
    }
    

Performance

  • Avoid Re-highlighting: Cache results for static content (e.g., documentation).
  • Lazy Loading: Shiki lazy-loads languages/themes, so getAvailableLanguages() is lightweight.

Extension Points

  1. Custom Renderer Scripts: Override the default Node script (advanced):

    \Spatie\ShikiPhp\Shiki::setRendererScript(__DIR__ . '/custom-renderer.js');
    
  2. Post-Processing: Modify output HTML with a closure:

    $highlighted = Shiki::highlight($code, $language, $theme)
        ->replace('<pre', '<pre class="custom-class"');
    
  3. Event Hooks (via Service Provider):

    Shiki::macro('afterHighlight', function ($html, $code, $options) {
        // Modify $html before returning
        return $html;
    });
    

Common Issues

Issue Solution
Blank output Ensure shiki is installed via npm/yarn.
Unsupported language/theme Check getAvailableLanguages()/getAvailableThemes().
Slow rendering Cache results or upgrade Node version.
CSS not applying Inspect inline styles or override with !important.
Argument list too long error Upgrade to v2.3.3+ or split code into chunks.

Pro Tips

  • Dark/Light Mode: Use github-dark/github-light for consistency with GitHub.
  • Line Numbers: Add via CSS:
    .shiki pre {
        counter-reset: line;
    }
    .shiki .line {
        counter-increment: line;
    }
    .shiki .line::before {
        content: counter(line);
        display: inline-block;
        width: 2em;
        margin-right: 1em;
        text-align: right;
    }
    
  • Copy Button: Integrate with clipboard.js to add copy-to-clipboard functionality to code blocks.
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.
calliostro/spotify-bundle
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle