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

@rizalibnu/sandpack-embedder

v1.6.4

Published

A universal HTML-based Sandpack runtime — dynamically inject interactive code editors and previews into any HTML document.

Readme

Sandpack Embedder

Turn code snippets generated by a CMS editor into live Sandpack playgrounds.

Sandpack Embedder

Want to see Sandpack Embedder in action?

👉 Live Demo

What Sandpack Embedder Does

Sandpack Embedder parses these code snippets and converts them into live Sandpack playgrounds, without needing to modify your CMS core.

It:

  1. Finds elements containing <sandpack>-like markup.
  2. Extracts and decodes escaped HTML.
  3. Parses props like template="react" and options="{'editorHeight':400}".
  4. Creates a live Sandpack React playground inside your CMS-rendered page.

Example

Input (Code snippets from CMS)

<sandpack
  template="react"
  custom-setup='{
    "dependencies": {
      "react": "19.2.0",
      "react-dom": "19.2.0"
    }
  }'
>
```js /App.js
export default function App() {
  return <h1>Hello world</h1>
}
```
```js /hidden-file.js hidden
console.log("I'm  hidden");
```
</sandpack>

Output (after running SandpackEmbedder)

💡 Turns into a live playground!

<Sandpack
  files={{
    "/index.js": `
      import "./styles.css";

      document.getElementById("app").innerHTML = `
      <h1>Hello Sandpack</h1>
      `;
    `,
    "/hidden-file.js": {
      code: `console.log("I'm  hidden");`,
      hidden: true
    }
  }}
  template="react"
  customSetup={{
    dependencies: {
      react: "19.2.0",
      "react-dom": "19.2.0"
    }
  }}
/>

Usage

You can use SandpackEmbedder on any web page that includes HTML code blocks.

Simple HTML Integration

<pre><code>// code snippets</code></pre>
<script type="module">
  import { SandpackEmbedder } from "https://esm.sh/@rizalibnu/sandpack-embedder";

  const sandpack = new SandpackEmbedder({
    codeSelector: "pre > code",
    playgroundClass: "sandpack-playground",
  });

  sandpack.load();
</script>

Using Import Maps

<script type="importmap">
  {
    "imports": {
      "@rizalibnu/sandpack-embedder": "https://esm.sh/@rizalibnu/sandpack-embedder"
    }
  }
</script>
<script type="module">
  import { SandpackEmbedder } from "@rizalibnu/sandpack-embedder";
</script>

Options

You can customize selectors, theme, or even replace the Sandpack component.

export interface SandpackEmbedderOptions {
  /** CSS selector used to find code elements containing escaped <Sandpack> markup. Default: 'pre > code' */
  codeSelector?: string;

  /** CSS class name applied to the mount container created for each playground embed. Default: 'sandpack' */
  playgroundClass?: string;

  /** Custom Sandpack React components (keyed by name, e.g. "Sandpack"). */
  customComponents?: Record<string, Component>;

  /** Sandpack initial theme. Default theme by Sandpack Component used when not specified by props. */
  theme?: string | SandpackProps['theme'];

  /** Custom Sandpack Theme (keyed by name, e.g. "amethyst").  */
  customThemes?: Record<string, DeepPartial<SandpackTheme>>;

  /**
   * Selector or callback that determines where to inject the Sandpack playground.
   * - If string → resolved via `closest(selector)` from code block
   * - If function → return a DOM element relative to the code block
   *
   * Default: codeSelector's parentElement
   */
  injectTarget?: string | ((codeEl: HTMLElement) => HTMLElement | null);

  /** Controls where the mount node is injected relative to injectTarget. Default: 'after' */
  injectPosition?: 'before' | 'after' | 'replace' | 'inside';

  /** Controls visibility of the original code snippet. Default: 'false' */
  showOriginalCode?: boolean;
}

Updating Embedder

You can change the Sandpack theme dynamically via:

sandpack.updateTheme("light");

Later when DOM updates or navigation changes:

sandpack.refresh();

Completely clean up:

sandpack.destroy();

Preset Components

Sandpack Embedder includes two built-in presets that let you display only the preview or only the code viewer—perfect for documentation.

These presets wrap your code fences and render a specific Sandpack layout:

<preview> → Preview-only (no editor)

<code-viewer> → Code Viewer only (readonly, no preview)

Use them exactly like your <sandpack> tag, but simplified.

<preview template="react">
// markdown code blocks...
<preview>

<code-viewer template="react" options='{"viewerHeight": 500}'>
// markdown code blocks...
<code-viewer>

Advanced

Control where playground is injected

You can let users decide where the live playground is inserted relative to the <code> element:

new SandpackEmbedder({
  codeSelector: ".language-sandpack",
  injectTarget: ".code-wrapper",
  injectPosition: "after", // "after" | "before" | "replace" | "inside"
}).load();

Use a function for full control

new SandpackEmbedder({
  codeSelector: ".language-sandpack",
  injectTarget: (el) => el.closest(".code-wrapper")?.querySelector("pre"),
  injectPosition: "inside"
});

Custom Theme Mapping

You can override the theme or add your own:

import { amethyst, aquaBlue } from "@codesandbox/sandpack-themes";
const sandpack = new SandpackEmbedder({
    customThemes: { amethyst, aquaBlue, neoCyan },
    theme: "amethyst"
}).load();

sandpack.updateTheme("aquaBlue");
<sandpack theme="neoCyan">
  // markdown code blocks...
</sandpack>

Custom Component Mapping

You can override the <sandpack> component or add your own:

<script type="importmap">
  {
    "imports": {
      "@codesandbox/sandpack-react": "https://esm.sh/@codesandbox/[email protected]",
      "@rizalibnu/sandpack-embedder": "https://esm.sh/@rizalibnu/sandpack-embedder"
    }
  }
</script>
<script type="module" src="https://esm.sh/tsx"></script>
<script type="text/babel">
  import { SandpackEmbedder } from "@rizalibnu/sandpack-embedder";
  import { 
    SandpackProvider, 
    SandpackLayout, 
    SandpackPreview, 
    SandpackCodeEditor 
  } from "@codesandbox/sandpack-react";

  function CustomSandpack(props) {
    return (
      <SandpackProvider>
        <SandpackLayout>
          <SandpackCodeEditor />
          <SandpackPreview />
        </SandpackLayout>
      </SandpackProvider>
    )
  };

  function VuePack(props) {
    return <Sandpack {...props} template="vue" />;
  }

  new SandpackEmbedder({
    customComponents: { sandpack: CustomSandpack, vuepack: VuePack },
  }).load();
</script>

This allows you to use any custom tag like <vuepack> or <playground> as long as it’s mapped in customComponents.

<vuepack>
  // markdown code blocks...
</vuepack>

Installation

pnpm add @rizalibnu/sandpack-embedder
# or
yarn add @rizalibnu/sandpack-embedder
# or
npm install @rizalibnu/sandpack-embedder

Storybook

To explore and test UI behaviors interactively:

pnpm storybook

Testing

Run unit tests with Vitest:

pnpm test

License

MIT © Rizal Ibnu