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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@jxpeng98/vitepress-pyodide

v1.0.1

Published

VitePress plugin and components to run Python (Pyodide) in Markdown with shared page state.

Downloads

2

Readme

vitepress-pyodide

Run Python (Pyodide) inline in VitePress. This package provides:

  • Markdown-it plugins to turn code into interactive cells:
    • Fenced blocks: ```pyodide → interactive cell
    • HTML blocks: <Pyodide>…</Pyodide> → interactive cell (dedented, newlines preserved)
    • Vue components with a shared in‑browser interpreter per page and a tidy VitePress look

Highlights

  • Per‑page shared state: later cells can reuse variables from earlier cells
  • Fresh state on new pages (SPA navigation): the first run clears globals
  • Editor hidden by default; buttons: Run, Clear, Show/Hide Code
  • Dark mode via VitePress tokens — no hardcoded colors
  • Adaptive heights: editor/output avoid empty space, but can grow

Table of Contents

Installation

pnpm add -D vitepress-pyodide

Setup

VitePress Configuration (.vitepress/config.(ts|mts))

import { createPyodideMarkdownPlugin, createPyodideHtmlBlockPlugin } from 'vitepress-pyodide/markdown'

export default {
  markdown: {
    config(md) {
      // Default layout: vertical (output below). Use 'horizontal' for side‑by‑side.
      md.use(createPyodideMarkdownPlugin({ layout: 'vertical' }))
      md.use(createPyodideHtmlBlockPlugin({ layout: 'vertical' }))
    }
  }
}

VitePress Theme Enhancement (.vitepress/theme/index.(ts|mts))

import { enhanceAppWithPyodide } from 'vitepress-pyodide/client'

export default {
  enhanceApp(ctx) {
    enhanceAppWithPyodide(ctx)
  }
}

Usage

Fenced Blocks

Use ```pyodide to create an interactive Python cell.

data = [3, 3, 6, 9, 12]
print(sum(data), len(data))

Optional Metadata

Metadata can be added in the info string:

  • Title: title="My Cell" or bare words after pyodide (e.g., ```pyodide My Cell)
  • Layout: layout=horizontal | layout=vertical or shorthand tokens: horizontal/right/vertical
  • Locale Override: locale="en" | "zh-CN"

Example:

x = 41
print(f"x = {x}")

HTML Form

Use <Pyodide>…</Pyodide> HTML blocks for interactive cells.

<Pyodide title="中文示例" locale="zh-CN" layout="vertical">
print("你好,Pyodide!")
</Pyodide>

Loading Python Packages

This plugin can load packages before a cell runs.

Pyodide Package Repository

For most packages in the Pyodide distribution (e.g., numpy, pandas, matplotlib), use the packages attribute:

Fenced Block:

import pandas as pd
import matplotlib.pyplot as plt

HTML Form:

<Pyodide packages="pandas, matplotlib">
import pandas as pd
import matplotlib.pyplot as plt
</Pyodide>

PyPI Wheels (micropip)

For pure-Python packages compatible with Pyodide (PyPI wheels), use the # micropip: directive at the top of the cell:

# micropip: XlsxWriter openpyxl
import micropip
# After the directive runs, your imports work as usual
import XlsxWriter, openpyxl

Notes:

  • The directive # micropip: ... (or # pip: ...) triggers an installation phase before your code executes. It accepts space- or comma‑separated names.
  • Not all PyPI packages have WebAssembly‑compatible wheels; consult https://pyodide.org.
  • The plugin can still auto‑detect and load matplotlib when it sees import matplotlib.

Plots (matplotlib)

Matplotlib needs a browser‑friendly output path. This plugin auto‑embeds figures after your code runs:

import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show()  # optional — figures are auto‑exported as SVG even without explicit show()

How it works:

  • Before your code runs, the plugin patches plt.show() to export existing figures.
  • After your code finishes, it exports any remaining figures.
  • Figures are saved as SVG and embedded below the text output — no changes to your code required.
  • If you prefer explicit control, you can still save and print a data URL yourself:
import io, base64
import matplotlib.pyplot as plt
plt.plot([1,2,3])
buf = io.BytesIO(); plt.savefig(buf, format='svg', bbox_inches='tight'); buf.seek(0)
print('data:image/svg+xml;base64,' + base64.b64encode(buf.read()).decode())

Component API

  • <Pyodide ...> (wrapper) forwards to <PyodideCell ...> ensuring identical UI to fenced blocks
  • Props:
    • layout?: 'vertical' | 'horizontal'
    • locale?: string (e.g., 'en', 'zh-CN')
    • title?: string
    • code?: string (optional initial code)
    • code64?: string (base64 initial code; used by plugins)

Behavior Notes

  • Script semantics: Only printed output appears. Bare expressions won’t display unless printed.
  • First run: Downloads Pyodide (~10MB). Subsequent runs reuse the same instance.
  • State persistence: Variables persist within the same page; navigating to another page starts fresh state.

Styling

  • Adapts to VitePress theme via CSS variables (no hardcoded colors)
  • Editor/output heights auto‑fit content; users can drag the editor bigger

Customize

  • Default layout per site: Pass { layout: 'horizontal' } to the plugins in config
  • Pyodide version/CDN: Update packages/vitepress-pyodide/src/runtime.ts