# Code Highlighting in 30 Seconds of Code: Prism vs Shiki Implementation

> Discover how 30 seconds of code implements code highlighting using Prism for client-side and Shiki for server-side rendering. Learn about their architecture and advantages.

- Repository: [Angelos Chalaris/30-seconds-of-code](https://github.com/Chalarangelo/30-seconds-of-code)
- Tags: deep-dive
- Published: 2026-02-25

---

**The 30 seconds of code website uses two interchangeable syntax-highlighting engines—Prism for classic client-side rendering and Shiki for modern server-side transformation with advanced visual features—wired together through a unified highlight-code plugin architecture.**

The "30 seconds of code" repository by Chalarangelo is a popular collection of short JavaScript snippets that relies on a sophisticated code highlighting system. Understanding the technologies behind code highlighting in 30 seconds of code reveals a flexible dual-engine architecture that supports both legacy Prism rendering and modern Shiki transformations.

## The Dual-Engine Architecture

The platform implements two distinct syntax-highlighting engines that can be swapped via configuration:

| Engine | Package | Role |
|--------|---------|------|
| **Prism** | `prismjs` | Classic client-side highlighter using `class="language-*"` conventions |
| **Shiki** | `@shikijs/core` | Modern highlighter converting code to HTML with bundled grammars, themes, and transformers |

## How the Highlighting Pipeline Works

### The Core Plugin (highlightCode.js)

The [`highlightCode.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/highlightCode.js) plugin in [`src/lib/contentUtils/markdownParser/plugins/ast/highlightCode.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/plugins/ast/highlightCode.js) serves as the central dispatcher. It receives a `codeHighlighter` instance (either `PrismHighlighter` or `ShikiHighlighter`) and delegates rendering:

```javascript
// highlightCode.js – creates the wrapper around highlighted code
const promise = codeHighlighter
  .highlightCode(node.value, languageName, metadata)
  .then(highlightedCode => {
    node.type = `html`;
    node.value = wrapHighlightedCode(highlightedCode, attributes);
  });

```

### The Extractor Logic (extractor.js)

The [`extractor.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/extractor.js) file in [`src/lib/contentUtils/extractor.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/extractor.js) determines which engine to use based on build configuration:

```javascript
// extractor.js – selects and wires the highlighter
import PrismHighlighter from '#src/lib/contentUtils/markdownParser/codeHighlighters/prism.js';
import ShikiHighlighter from '#src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js';

const codeHighlighter = highlighter === 'shiki' ? ShikiHighlighter : PrismHighlighter;
codeHighlighter.setup(grammars);
MarkdownParser.setupProcessors({ languages, grammars, codeHighlighter });

```

## Prism Implementation Details

The Prism highlighter in [`src/lib/contentUtils/markdownParser/codeHighlighters/prism.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/codeHighlighters/prism.js) provides lightweight client-side rendering.

**Setup** loads only required languages:

```javascript
// prism.js – setup method
static setup(grammars) {
  loadLanguages(Object.keys(grammars));
}

```

**Highlighting** uses `Prism.highlight` to generate HTML:

```javascript
// prism.js – highlightCode method
static highlightCode(code, language) {
  const grammar = Prism.languages[language];
  return Promise.resolve(Prism.highlight(code, grammar, language));
}

```

## Shiki Implementation Details

The Shiki highlighter in [`src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js) offers advanced server-side transformation with visual enhancements.

**Setup** creates a bundled highlighter with the custom "cosmos" theme:

```javascript
// shiki.js – setup method
static setup(grammars) { … }

```

**Highlighting** applies multiple transformers for advanced styling:

```javascript
// shiki.js – highlightCode method
static async highlightCode(code, language, metadata) {
  const highlightedCode = await this.codeToHtml(code, {
    lang: language,
    theme: 'cosmos',
    transformers: [
      transformerColorSwatches(),
      transformerLineHighlights(metadata),
      transformerSectionFolding(metadata),
      transformerColorizedBrackets({ … })
    ],
  });
  …
}

```

## Key Files and Their Roles

| File | Purpose |
|------|---------|
| [`src/lib/contentUtils/markdownParser/plugins/ast/highlightCode.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/plugins/ast/highlightCode.js) | Core plugin that delegates to the selected highlighter and wraps output in `<pre>/<code>` tags |
| [`src/lib/contentUtils/markdownParser/codeHighlighters/prism.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/codeHighlighters/prism.js) | Thin wrapper around `prismjs`; loads languages and calls `Prism.highlight` |
| [`src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js) | Sets up Shiki's bundled highlighter, loads themes, and runs transformers for advanced styling |
| [`src/lib/contentUtils/extractor.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/extractor.js) | Chooses between Prism and Shiki based on config and wires the selected engine into the Markdown parser |
| [`src/lib/contentUtils/markdownParser/markdownParser.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/markdownParser.js) | Overall Markdown-to-HTML pipeline where the `highlightCode` plugin is integrated |

## Summary

- **30 seconds of code** uses a dual-engine syntax highlighting system supporting both **Prism** and **Shiki**.
- The **highlightCode plugin** in [`src/lib/contentUtils/markdownParser/plugins/ast/highlightCode.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/plugins/ast/highlightCode.js) acts as the abstraction layer between the Markdown parser and the highlighting engines.
- **Prism** (`prismjs`) provides classic client-side highlighting with on-demand language loading via [`src/lib/contentUtils/markdownParser/codeHighlighters/prism.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/codeHighlighters/prism.js).
- **Shiki** (`@shikijs/core`) delivers modern server-side transformation with advanced features like line highlighting, section folding, and colorized brackets through [`src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js).
- The **extractor** ([`src/lib/contentUtils/extractor.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/extractor.js)) determines which engine to use based on build configuration and initializes the pipeline accordingly.

## Frequently Asked Questions

### What is the default code highlighting engine in 30 seconds of code?

The default engine depends on the build configuration specified in the extractor. While both Prism and Shiki are available, the system defaults to Prism unless explicitly configured to use Shiki via the `highlighter` parameter passed to the extraction utilities in [`src/lib/contentUtils/extractor.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/extractor.js).

### How does Shiki provide better performance than Prism in 30 seconds of code?

Shiki performs syntax highlighting at build time using bundled grammars and themes, generating static HTML that requires no client-side JavaScript to render. This reduces runtime overhead compared to Prism, which relies on client-side execution and dynamic language loading, though Prism offers faster initial page loads for small snippets.

### Can I switch between Prism and Shiki without modifying the source code?

Switching requires configuration changes in the extraction pipeline, typically by modifying the `highlighter` option passed to `extractContent` or related functions in [`src/lib/contentUtils/extractor.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/extractor.js). There is no runtime toggle for end-users viewing the website; the choice is made at build time by the content extraction system.

### What advanced features does Shiki offer that Prism does not support?

Shiki supports several advanced transformations unavailable in Prism, including line highlighting via `transformerLineHighlights`, section folding through `transformerSectionFolding`, colorized brackets using `transformerColorizedBrackets`, and color swatch rendering with `transformerColorSwatches`. These features generate additional HTML data-attributes and markup during the build process in [`src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/contentUtils/markdownParser/codeHighlighters/shiki.js).