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

rehype-script-to-code

v1.1.0

Published

A [rehype](https://github.com/rehypejs/rehype) plugin that transforms `<script>` tags in HTML to `<pre><code>` blocks with syntax highlighting support. Perfect for documentation sites, tutorials, and blog posts where you want to display script content as

Readme

rehype-script-to-code

A rehype plugin that transforms <script> tags in HTML to <pre><code> blocks with syntax highlighting support. Perfect for documentation sites, tutorials, and blog posts where you want to display script content as highlighted code blocks instead of executing them.

Features

  • 🔄 Automatically converts <script> tags to <pre><code> blocks
  • 🎨 Preserves language information for syntax highlighting
  • 🗺️ Customizable language mapping for different script types
  • 🎯 Selective transformation with custom filter functions
  • 📦 Preserves original attributes (id, class, data-, aria-)
  • ✂️ Configurable content trimming
  • 🚫 Skip external scripts and empty scripts options
  • 🔧 Full TypeScript support with type definitions

Installation

npm install rehype-script-to-code
yarn add rehype-script-to-code
pnpm add rehype-script-to-code

Usage

Basic Usage

import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';

const processor = rehype()
  .use(rehypeScriptToCode);

const html = `
<html>
  <body>
    <script type="text/javascript">
      console.log('Hello, World!');
    </script>
  </body>
</html>
`;

const result = await processor.process(html);

Output:

<html>
  <body>
    <pre><code class="language-javascript">console.log('Hello, World!');</code></pre>
  </body>
</html>

With Options

import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';

const processor = rehype()
  .use(rehypeScriptToCode, {
    defaultLanguage: 'javascript',
    preserveAttributes: true,
    additionalClasses: ['highlight', 'script-block'],
    langMap: {
      'custom-script': 'javascript',
      'shader': 'glsl'
    },
    shouldTransform: (node) => {
      // Skip scripts with data-no-transform attribute
      return !node.properties?.['data-no-transform'];
    }
  });

Integration with unified

import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';
import { rehypeScriptToCode } from 'rehype-script-to-code';

const processor = unified()
  .use(rehypeParse)
  .use(rehypeScriptToCode, {
    skipExternal: true,
    trimContent: true
  })
  .use(rehypeStringify);

const result = await processor.process(htmlString);

Options

defaultLanguage

  • Type: string
  • Default: 'javascript'
  • Description: Default language for code blocks when the script type cannot be determined

langMap

  • Type: Record<string, string>
  • Default: See default language mappings
  • Description: Custom mapping from script type/lang attributes to code language identifiers

preserveAttributes

  • Type: boolean
  • Default: false
  • Description: Preserve original script tag attributes (id, class, data-, aria-) on the pre element

additionalClasses

  • Type: string[]
  • Default: []
  • Description: Additional CSS classes to add to the pre element

trimContent

  • Type: boolean
  • Default: true
  • Description: Trim whitespace from script content

shouldTransform

  • Type: (node: Element) => boolean
  • Default: null
  • Description: Custom function to determine if a script should be transformed

skipExternal

  • Type: boolean
  • Default: true
  • Description: Skip script tags with src attribute (external scripts)

skipEmpty

  • Type: boolean
  • Default: true
  • Description: Skip empty script tags

codeBlockClass

  • Type: string
  • Default: ''
  • Description: Additional class for the code element

Default Language Mappings

The plugin includes default mappings for common script types:

{
  // MIME types
  'text/javascript': 'javascript',
  'application/javascript': 'javascript',
  'text/ecmascript': 'javascript',
  'application/ecmascript': 'javascript',
  'text/typescript': 'typescript',
  'application/typescript': 'typescript',
  'text/jsx': 'jsx',
  'text/tsx': 'tsx',
  'application/json': 'json',
  'application/ld+json': 'json',

  // Module types
  'module': 'javascript',
  'importmap': 'json',

  // Common shorthand
  'js': 'javascript',
  'ts': 'typescript',
  'jsx': 'jsx',
  'tsx': 'tsx',
  'json': 'json',

  // Template languages
  'text/html': 'html',
  'text/x-template': 'html',
  'text/x-handlebars-template': 'handlebars',
}

Advanced Examples

Preserve Attributes and Custom Classes

const processor = rehype()
  .use(rehypeScriptToCode, {
    preserveAttributes: true,
    additionalClasses: ['code-example', 'syntax-highlight'],
    codeBlockClass: 'formatted-code'
  });

// Input:
// <script id="example" class="demo" data-example="true">
//   const x = 10;
// </script>

// Output:
// <pre id="example" class="demo code-example syntax-highlight" data-example="true">
//   <code class="language-javascript formatted-code">const x = 10;</code>
// </pre>

Custom Language Detection

const processor = rehype()
  .use(rehypeScriptToCode, {
    langMap: {
      'vertex-shader': 'glsl',
      'fragment-shader': 'glsl',
      'compute-shader': 'wgsl',
      'custom-lang': 'javascript'
    }
  });

// Input:
// <script type="vertex-shader">
//   attribute vec3 position;
//   void main() {
//     gl_Position = vec4(position, 1.0);
//   }
// </script>

// Output:
// <pre><code class="language-glsl">attribute vec3 position;
// void main() {
//   gl_Position = vec4(position, 1.0);
// }</code></pre>

Selective Transformation

const processor = rehype()
  .use(rehypeScriptToCode, {
    shouldTransform: (node) => {
      // Only transform scripts with specific attributes
      const properties = node.properties || {};

      // Transform only if has data-highlight attribute
      if (properties['data-highlight']) {
        return true;
      }

      // Or if it's a template script
      if (properties.type === 'text/x-template') {
        return true;
      }

      return false;
    }
  });

Working with Syntax Highlighters

The plugin works seamlessly with popular syntax highlighting libraries:

With Prism.js

import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';
import rehypePrism from 'rehype-prism';

const processor = rehype()
  .use(rehypeScriptToCode)
  .use(rehypePrism);

With Shiki

import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';
import rehypeShiki from '@shikijs/rehype';

const processor = rehype()
  .use(rehypeScriptToCode)
  .use(rehypeShiki, {
    theme: 'github-dark'
  });

Use Cases

Documentation Sites

Transform inline script examples into highlighted code blocks for better readability:

// Perfect for MDX documentation
const processor = rehype()
  .use(rehypeScriptToCode, {
    preserveAttributes: true,
    additionalClasses: ['example-code']
  });

Blog Posts

Display script content without execution:

// Prevent script execution while showing the code
const processor = rehype()
  .use(rehypeScriptToCode, {
    skipExternal: true,
    trimContent: true
  });

Educational Content

Create interactive tutorials with visible code:

// Show both the code and allow selective execution
const processor = rehype()
  .use(rehypeScriptToCode, {
    shouldTransform: (node) => {
      // Only transform scripts marked for display
      return node.properties?.['data-display'] === 'true';
    }
  });

TypeScript Support

The plugin includes full TypeScript definitions:

import { rehypeScriptToCode, RehypeScriptToCodeOptions } from 'rehype-script-to-code';

const options: RehypeScriptToCodeOptions = {
  defaultLanguage: 'typescript',
  preserveAttributes: true,
  additionalClasses: ['code-block'],
  shouldTransform: (node) => !node.properties?.['data-skip']
};

const processor = rehype()
  .use(rehypeScriptToCode, options);

API

rehypeScriptToCode(options?)

Transform <script> tags to <pre><code> blocks.

Parameters

  • options (optional): Configuration options object

Returns

A unified transformer function.

defaultLangMap

Export of the default language mappings used by the plugin.

import { defaultLangMap } from 'rehype-script-to-code';

console.log(defaultLangMap['text/javascript']); // 'javascript'

Compatibility

  • Node.js 14+
  • ES Modules
  • Works with rehype 12+ and unified 10+

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

MIT © wan-kong

Related

  • rehype - HTML processor powered by plugins
  • unified - Interface for processing text with syntax trees
  • hast - Hypertext Abstract Syntax Tree format

Acknowledgments

Built with the unified collective ecosystem.