npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aero-js/highlight

v0.3.3

Published

Shared Shiki syntax highlighting utility for the Aero framework.

Downloads

85

Readme

@aero-js/highlight

Shared Shiki syntax highlighting utility for the Aero framework.

Provides composable, reusable Shiki integration across the Aero ecosystem:

  • Markdown code blocks via @aero-js/content (opt-in)
  • Custom usage in templates or CLI tools (direct import)

Installation

pnpm add @aero-js/highlight

Usage

With @aero-js/content (Markdown Highlighting)

When using @aero-js/content, enable Shiki highlighting by adding @shikijs/rehype to markdown.rehypePlugins in your content.config.ts. Use @aero-js/highlight for preDataLangTransformer() (adds data-lang on <pre>) and for shared config types:

// content.config.ts
import { defineCollection, defineConfig } from '@aero-js/content'
import { preDataLangTransformer } from '@aero-js/highlight'
import rehypeShiki from '@shikijs/rehype'
import {
	transformerNotationHighlight,
	transformerNotationFocus,
} from '@shikijs/transformers'
import { z } from 'zod'

const docs = defineCollection({
	name: 'docs',
	directory: 'content/docs',
	schema: z.object({
		title: z.string(),
		published: z.boolean().default(false),
	}),
})

export default defineConfig({
	collections: [docs],
	markdown: {
		rehypePlugins: [
			[
				rehypeShiki,
				{
					themes: { light: 'github-light', dark: 'github-dark' },
					transformers: [
						preDataLangTransformer(), // Adds data-lang="..." on <pre>
						transformerNotationHighlight(), // Highlight lines: ```js {1-3}
						transformerNotationFocus(), // Focus lines: ```js /focus/
					],
				},
			],
		],
	},
})

All fenced code blocks in your markdown files will be highlighted. The content pipeline is always remarkremark-rehype[rehypePlugins]rehype-stringify; without any rehype plugins, code blocks render as plain <pre><code>.

```js
const greeting = 'Hello, Shiki!'
console.log(greeting)
```

Becomes:

<pre class="shiki shiki-themes github-light github-dark" style="...">
  <code>
    <span class="line"><span style="...">const</span> <span style="...">greeting</span> ...</span>
    <!-- highlighted tokens -->
  </code>
</pre>

Standalone Usage (Direct Import)

Use @aero-js/highlight directly for one-off highlighting in any context:

import { highlight, preDataLangTransformer } from '@aero-js/highlight'

const html = await highlight('const x = 1', 'js', {
	themes: { light: 'github-light', dark: 'github-dark' },
	transformers: [preDataLangTransformer()],
})

console.log(html)
// => <pre class="shiki ..." data-lang="js"><code>...</code></pre>

Single Theme Mode

Use theme instead of themes for single-theme output:

const html = await highlight('const x = 1', 'js', {
	theme: 'nord',
})

Caching & Performance

The highlighter is cached at the module level and reused across renders for performance:

import { getHighlighter } from '@aero-js/highlight'

const config = {
	theme: 'github-light',
	langs: ['js', 'ts'],
}

// First call initializes and caches the highlighter
const h1 = await getHighlighter(config)

// Subsequent calls with same config return the cached instance
const h2 = await getHighlighter(config)
console.log(h1 === h2) // true — same instance

API

highlight(code, language, config): Promise<string>

Highlight a code string and return highlighted HTML.

Parameters:

  • code - Source code to highlight
  • language - Language ID (e.g., 'js', 'python')
  • config - Shiki configuration object

Returns: Promise resolving to highlighted HTML string

getHighlighter(config): Promise<Highlighter>

Get or create a cached Shiki highlighter instance. The highlighter is cached at the module level and reused across calls with the same config.

Parameters:

  • config - Shiki configuration object

Returns: Promise resolving to a Shiki highlighter instance

resetHighlighter(): void

Clear the cached highlighter. Useful for testing to ensure a fresh instance between tests.

Configuration

The ShikiConfig type wraps Shiki's standard options with full BundledTheme and BundledLanguage autocomplete.

import type { ShikiConfig } from '@aero-js/highlight'

// Single theme
const single: ShikiConfig = {
	theme: 'github-light',
	langs: ['js', 'ts', 'html', 'css'],
}

// Multiple themes (light/dark or more)
const dual: ShikiConfig = {
	themes: {
		light: 'github-light',
		dark: 'github-dark',
	},
	// Optional: control which theme gets inline color
	defaultColor: 'light', // 'light' | 'dark' | false | 'light-dark()'
	// Optional: CSS variable prefix for theme colors
	cssVariablePrefix: '--shiki-',
	langs: ['python', 'rust', 'go'],
	transformers: [
		transformerNotationHighlight(), // {1-3}
		transformerNotationFocus(), // /focus/
	],
}

Available Themes

See Shiki Themes for the full list. Popular options:

  • github-light / github-dark
  • nord / nord
  • vitesse-light / vitesse-dark
  • dracula / dracula

Available Languages

See Shiki Languages for the full list. Common IDs:

  • js, ts, jsx, tsx (JavaScript/TypeScript)
  • html, css, json
  • python, rust, go
  • bash, sh, zsh
  • yaml, toml, xml
  • ...and 100+ more

Transformers

Transformers post-process highlighted code to add features like line highlighting, line numbers, and diffs.

import { preDataLangTransformer } from '@aero-js/highlight'
import {
	transformerNotationHighlight,
	transformerNotationFocus,
	transformerRenderWhitespace,
	transformerLineNumbers,
} from '@shikijs/transformers'

const config = {
	theme: 'github-light',
	transformers: [
		preDataLangTransformer(), // Adds data-lang="..." on <pre>
		transformerNotationHighlight(), // Highlight lines: [!code highlight]
		transformerNotationFocus(), // Focus code: [!code focus]
		transformerRenderWhitespace(), // Render whitespace
		transformerLineNumbers(), // Add line numbers
	],
}

preDataLangTransformer() uses the raw requested language token (including aliases), so a fenced block tagged as my-js emits data-lang="my-js".

See Shiki Transformers for all available transformers and usage.

Styling

Shiki generates semantic HTML with inline styles and CSS classes. The framework does not inject CSS — you control styling in your own stylesheets.

Recommended user stylesheet (e.g., src/assets/styles/syntax.css):

/* Light theme (default) */
.shiki {
	background-color: #f6f8fa;
	color: #24292e;
	overflow-x: auto;
	padding: 1rem;
	border-radius: 0.375rem;
	font-family: 'Menlo', 'Monaco', monospace;
	font-size: 0.875rem;
	line-height: 1.5;
	margin: 1rem 0;
}

/* Dark theme (when root has .dark class) */
.dark .shiki {
	background-color: #0d1117;
	color: #c9d1d9;
}

Import in your layout:

<html :class="{ dark: isDarkMode }">
	<head>
		<link rel="stylesheet" href="@styles/syntax.css" />
	</head>
	<!-- ... -->
</html>

Examples

Markdown with Transformers

In your content.config.ts, add rehypeShiki to markdown.rehypePlugins with transformers:

markdown: {
	rehypePlugins: [
		[
			rehypeShiki,
			{
				themes: { light: 'github-light', dark: 'github-dark' },
				transformers: [transformerNotationHighlight()],
			},
		],
	],
},

In your markdown:

```js
const x = 1 // [!code highlight]
const y = 2
```

Custom Component in Templates

<!-- src/components/code-block.html -->
<script is:build>
	import { highlight } from '@aero-js/highlight'

	const { code, language = 'js' } = Aero.props

	const html = await highlight(code, language, {
		themes: { light: 'github-light', dark: 'github-dark' },
	})
</script>

<pre class="code-block">
	{ html }
</pre>

<style>
	.code-block :global(.shiki) {
		padding: 1rem;
		border-radius: 0.375rem;
	}
</style>

License

MIT