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

py-viz

v1.0.1

Published

Local data visualization studio — Python rendering, Node.js UI

Readme

py-viz Studio

A local data visualization studio — Python does the rendering, Node.js serves the UI.
Pick a chart type, edit the JSON spec in a Monaco editor, hit Render, and see the result instantly via WebSocket.
Ask the AI Sidekick to generate a chart from plain English, raw CSV, or JSON data.

Screenshots

py-viz-0

py-viz-1

py-viz-2

py-viz-3

Features

  • 25+ chart types across Plotly, Matplotlib, Seaborn, Altair, and Bokeh
  • Monaco editor for the JSON spec (syntax highlighting, auto-format, bracket matching)
  • Live WebSocket preview — no page reloads
  • Animated splitter — drag to resize the left panel
  • Context-sensitive help drawer — field reference and annotated example per chart type
  • Python source viewer — read-only Monaco panel showing the exact handler code for the selected chart
  • AI Sidekick — LLM-powered chart generator with clickable example pills; supports Ollama, Claude, OpenAI, xAI, Gemini; API keys stored in localStorage via the built-in Settings panel; remembers last-used model per provider
  • Guided tour — step-by-step walkthrough of the UI (click Tour in the header)
  • Splash screen on startup
  • Graceful shutdown on Ctrl+C — Python subprocess exits cleanly

Prerequisites

| Requirement | Version | |-------------|---------| | Node.js | ≥ 18 | | Python | ≥ 3.9 |

Python dependencies are installed automatically into a local .py-viz-venv/ on first run.

Install

npm install -g py-viz

Usage

# Start the studio (opens browser automatically)
py-viz serve

# Custom port
py-viz serve --port 3567

# Custom port, no auto-open
py-viz serve --port 3567 --no-open

# Enable the AI Sidekick panel
py-viz serve --enable-ai

# All options together
py-viz serve --port 3567 --enable-ai

# Open the browser manually (server already running)
py-viz open --port 3567

On first run, py-viz creates .py-viz-venv/ in the current directory and installs all Python dependencies (~1 min).
Subsequent starts are instant.

Guided Tour

Click the Tour button in the header for a step-by-step walkthrough of:

  1. Chart type selector
  2. Monaco JSON spec editor
  3. Render button
  4. Animated splitter
  5. Chart preview area
  6. Help drawer (Fields + Python source tabs)
  7. AI Sidekick (when enabled)

The tour highlights each UI element with an animated overlay and explains what it does.

AI Sidekick

The AI Sidekick lets you describe a chart in plain English — or paste raw CSV or JSON data — and have an LLM generate the py-viz spec automatically.

Enable

py-viz serve --enable-ai

The gold AI Sidekick button appears in the header only when the flag is set.

Supported providers

| Provider | Key source | |----------|-----------| | Ollama | No key needed — models auto-discovered via /api/tags | | Claude (Anthropic) | AI Settings panel or ANTHROPIC_API_KEY env var | | OpenAI | AI Settings panel or OPENAI_API_KEY env var | | xAI (Grok) | AI Settings panel or XAI_API_KEY env var | | Google Gemini | AI Settings panel or GEMINI_API_KEY env var |

A key entered in the Settings panel takes precedence over the environment variable.

# Env vars still work if preferred
ANTHROPIC_API_KEY=sk-ant-... py-viz serve --enable-ai

AI Settings panel

Click the gear icon in the AI Sidekick header to open the Settings panel.

  • Enter API keys for Claude, OpenAI, xAI, and Gemini
  • Keys are stored in localStorage — they never leave your browser; they are sent only during a chat request over your local loopback connection
  • Each field has a show/hide (👁) toggle and a clear (✕) button
  • Save keys commits to localStorage, then reloads the provider list
  • Clear all keys removes every saved key after confirmation
  • Green border on a key field = key is present

Provider + model selections are also remembered per provider. The Ollama base URL is persisted too.

Workflow

  1. Open the AI Sidekick drawer (gold button, slides in from the left)
  2. Select provider and model
  3. Click a pill to use a pre-built example, or type your own request
  4. Paste CSV or JSON inline if needed
  5. Click Send or press Cmd/Ctrl+Enter
  6. Review the generated spec
  7. Click Use this spec ▶ — spec loads into Monaco, chart type is set, rendering starts automatically

Example prompts

Bar chart of monthly sales: Jan 120, Feb 95, Mar 140, Apr 160, May 200

Scatter plot from this CSV:
name,height,weight
Alice,165,60
Bob,180,80
Carol,170,65

Choropleth world map of GDP: USA 25000, China 18000, Germany 4200

Seaborn violin plot of salaries by department:
dept,salary
Eng,120
Eng,130
Sales,90
Sales,95

Line chart from this JSON:
[{"month":"Jan","revenue":100},{"month":"Feb","revenue":120}]

Supported Chart Types

Plotly (interactive HTML)

| Type | Key | |------|-----| | Bar | plotly/bar | | Line | plotly/line | | Scatter | plotly/scatter | | Bubble | plotly/bubble | | Pie | plotly/pie | | Histogram | plotly/histogram | | Area | plotly/area | | Box | plotly/box | | Violin | plotly/violin | | Heatmap | plotly/heatmap | | Sunburst | plotly/sunburst | | Treemap | plotly/treemap | | Funnel | plotly/funnel | | Waterfall | plotly/waterfall | | Candlestick | plotly/candlestick | | Choropleth | plotly/choropleth | | 3D Scatter | plotly/scatter3d | | 3D Surface | plotly/surface |

Matplotlib (SVG)

mpl/bar · mpl/line · mpl/scatter · mpl/histogram · mpl/pie · mpl/area

Seaborn (SVG)

sns/heatmap · sns/pairplot · sns/boxplot · sns/violin · sns/distribution · sns/regression

Altair / Vega-Lite (interactive HTML)

altair/bar · altair/line · altair/scatter · altair/area · altair/heatmap

Bokeh (interactive HTML)

bokeh/line · bokeh/bar · bokeh/scatter

JSON Spec Format

Every chart is driven by a JSON spec sent over WebSocket:

{
  "type": "plotly/bar",
  "title": "Sales by Region",
  "x": "region",
  "y": "sales",
  "data": {
    "region": ["North", "South", "East", "West"],
    "sales": [420, 380, 510, 290]
  }
}

The data field is always column-oriented: each key is a column name, value is an array.
Click ? Help in the header for a full field reference for the selected chart type.

REST API

curl -X POST http://localhost:3000/api/render \
  -H 'Content-Type: application/json' \
  -d '{"type":"plotly/bar","x":"k","y":"v","data":{"k":["A","B"],"v":[10,20]}}'

Returns { "output": "<html…>", "format": "html" }.

Build (obfuscated dist)

npm run build

Obfuscates all JS into dist/ via obfuscli.
The postbuild script removes .py-viz-venv and node_modules from the output automatically.

Architecture

Browser  ──WS──►  Node.js (Express + ws)  ──stdin──►  Python subprocess
                  ├── /api/render  (REST)  ◄──stdout──  (renderer.py)
                  ├── /api/ai/*    (LLM proxy)
                  │    ├── Ollama  (local, no key)
                  │    ├── Claude  (ANTHROPIC_API_KEY)
                  │    ├── OpenAI  (OPENAI_API_KEY)
                  │    ├── xAI     (XAI_API_KEY)
                  │    └── Gemini  (GEMINI_API_KEY)
                  └── /api/config  (feature flags)

See ARCH.md and STACK.md for full details.

Project Structure

py-viz/
├── bin/cli.js              Commander CLI  (serve, open, --enable-ai)
├── server/
│   ├── app.js              Express + SIGINT handler + feature flags
│   ├── ws.js               WebSocket bridge
│   ├── python.js           Subprocess manager + venv setup
│   └── ai.js               LLM proxy (Ollama / Claude / OpenAI / xAI / Gemini)
├── public/
│   ├── index.html          Studio UI (splash, guided tour, drawers, splitter, pills)
│   └── app.js              Monaco editors, WS client, AI Sidekick, localStorage
└── python/
    ├── renderer.py         stdin/stdout JSON loop
    ├── requirements.txt
    └── charts/
        ├── plotly_charts.py
        ├── mpl_charts.py
        ├── sns_charts.py
        ├── altair_charts.py
        └── bokeh_charts.py

License

MIT © Mohan Chinnappan