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

@danieledep/code-sandbox

v1.0.1

Published

A dependency-free <code-sandbox> web component for interactive, editable HTML/CSS/JS demos.

Downloads

297

Readme

code-sandbox web component

This is a fork of code-sandbox web component from Chris Ferdinandi for displaying an interactive code sandbox for HTML, CSS and javascript, similar to what CodePen does.

Having a code sandbox web component can be useful for showing code snippets in a more interactive way, and it doesn't require any external third-party services like CodePen or JSFiddle.

Also being a web component, it means it can be used in any framework or vanilla JavaScript and it will always work, since it doesn't depend on any framework. It has no hard dependencies: syntax highlighting is optional and pluggable — drop in PrismJS and it's used automatically, or wire up another highlighter such as Shiki (see Syntax highlighting). Without one, the editors simply show plain text. This fork adds a few useful features to the original code too.

Installation

The component is a single self-registering custom element with no build step and no required dependencies (syntax highlighting is optional — see Syntax highlighting). Use it via npm or straight from a CDN.

npm

npm install @danieledep/code-sandbox

Import it once to register the <code-sandbox> element, and include the stylesheet:

import "@danieledep/code-sandbox";
import "@danieledep/code-sandbox/code-sandbox.css";

If your bundler doesn't handle CSS imports, link the stylesheet in your HTML instead (as in the CDN snippet below, pointed at your local copy).

CDN

No install, no build — drop two tags into the page. Pin a version (@1) so it can't shift under you:

<link
	rel="stylesheet"
	href="https://cdn.jsdelivr.net/npm/@danieledep/code-sandbox@1/src/code-sandbox.css"
/>
<script
	type="module"
	src="https://cdn.jsdelivr.net/npm/@danieledep/code-sandbox@1/src/code-sandbox.js"
></script>

unpkg works the same way — swap the host for https://unpkg.com/.

Usage

Either way, author a sandbox declaratively, with one <textarea> per language:

<code-sandbox>
	<textarea for="html"><!-- markup --></textarea>
	<textarea for="css">/* styles */</textarea>
	<textarea for="js">// script</textarea>
</code-sandbox>

Attributes

| Attribute | Description | | --------- | --------------------------------------------------------------------------------------------------------------- | | console | If present displays the console (Optional) | | hidden | Used to prevent flashes of unstyled content | | name | The name attribute to be attached to the <details> elements, which makes only one open at the time (Optional) | | result | Controls what is displayed on the right side panel, can either be iframe or console. Defaults to iframe | | src | The URL of the file to fetch and run in the sandbox. Can be on the same origin or a remote file (Optional) | | title | The title of the code block, defaults to Code sandbox. (Optional) |

Syntax highlighting

Highlighting is optional and pluggable. Each editor is a transparent <textarea> layered over a highlighted mirror, so a highlighter only has to colour the mirror's text — the component keeps it aligned with the textarea.

  • Prism (zero config) — include PrismJS and a Prism theme on the page and the component detects window.Prism and uses it automatically.
  • None — with no highlighter present, the editors show readable plain text (coloured via --csb-editor-bg / --csb-editor-color).
  • Custom (e.g. Shiki) — assign a function to the element's static highlight property:
customElements.get("code-sandbox").highlight = (code, lang, element) => {
	/* ... */
};

| Argument | Description | | --------- | ------------------------------------------------------------------- | | code | The editor's current source text | | lang | The language — "html", "css" or "js" | | element | The mirror <code> element, already holding the plain text |

The function may be async and may return an HTML string, which the component sets as the mirror's markup (and discards if the editor changed while an async highlighter was still running). Return nothing if you mutate element yourself, as Prism does.

Example: Shiki

import { createHighlighter } from "https://esm.sh/shiki";

const highlighter = await createHighlighter({
	langs: ["html", "css", "js"],
	themes: ["github-dark"],
});

customElements.get("code-sandbox").highlight = (code, lang) =>
	highlighter.codeToHtml(code, {
		lang: lang || "txt",
		theme: "github-dark",
		structure: "inline", // colour spans only — keeps the component's own <pre>/<code> and metrics
	});

// editors that rendered while Shiki was loading need a nudge
document.querySelectorAll("code-sandbox").forEach((el) => el.rehighlight());

Use structure: "inline" so Shiki emits only the coloured token spans; the component's own element and CSS keep the mirror aligned with the textarea.

Theming

The component exposes a set of CSS custom properties so you can match it to your own design without overriding selectors. Set them on code-sandbox (or any ancestor, e.g. :root):

code-sandbox {
	--csb-radius: 0;
	--csb-min-height: 24em;
	--csb-preview-bg: #faf8f5;
}

| Property | Description | Default | | --------------------- | -------------------------------------------- | ------------------------------------ | | --csb-color | Text colour of the chrome (labels, summaries) | light-dark(#272727, #f7f7f7) | | --csb-bg-color | Background of the frame (header and chrome) | Canvas | | --csb-border-color | Borders and dividers | light-dark(#ddd, #6b6b6b) | | --csb-radius | Corner radius of the frame, buttons and panels | 0.25em | | --csb-min-height | Minimum height of the editors, preview and console panels | 15em | | --csb-max-height | Maximum height of an open editor before it scrolls internally (desktop ≥768px only; on mobile editors grow with the stacked layout) | 20em | | --csb-resize | How the frame can be drag-resized (vertical, horizontal, both, none) | both | | --csb-layout-mobile | Mobile (<768px) layout as a grid-template of named areas — see Layout | stacked | | --csb-layout | Desktop (≥768px) layout as a grid-template of named areas — see Layout | editors left, result right | | --csb-preview-bg | Background of the iframe preview | #ffffff | | --csb-font-family | Font for the code editors and console | ui-monospace, Menlo, Monaco, "Courier New", monospace | | --csb-font-size | Font size for the code editors and console | 0.875em | | --csb-tab-size | Tab width in the editors and console | 2 | | --csb-editor-bg | Editor background (base colour, also used when Prism isn't loaded) | #282c34 | | --csb-editor-color | Editor base text colour (un-highlighted text) | #abb2bf | | --csb-console-bg | Console panel background | #282c34 | | --csb-console-color | Console base text colour | #abb2bf | | --csb-warning-color | Colour of console.warn output | #f9d767 | | --csb-error-color | Colour of console.error output | #f9c8c8 |

Layout

The whole sandbox is a single CSS grid, so each arrangement is controlled with one property, written as a grid-template of named areas: --csb-layout-mobile below the 768px breakpoint and --csb-layout at or above it. The areas are:

  • header — the title bar and controls
  • html, css, js — the three editors
  • result — the preview iframe (or the console, when result="console")
  • console — the console drawer, when the console attribute is used

By default mobile is a vertical stack and desktop puts the editors on the left with the result on the right. To get a CodePen-style desktop layout — editors across the top, preview below — redefine the desktop areas:

code-sandbox {
	--csb-layout:
		"header header header"    auto
		"html   css    js"        1fr
		"result result result"    1fr
		"console console console" auto / 1fr 1fr 1fr;
}

Any area you omit simply isn't rendered into. Because the editors are collapsible, prefer auto rows where you want a pane to shrink to its summary when closed, and 1fr where it should fill.

Resources