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

dynamic-data-view

v0.0.0

Published

A library for generating reusable, dynamic data visualizations using LLMs. Create a design once with natural language, then execute it deterministically with new data.

Readme

Dynamic Data View

Dynamic Data View is a library that leverages LLMs (specifically Google's Gemini) to generate reusable, dynamic data visualization workflows. It separates the design phase (creative, LLM-driven) from the execution phase (deterministic, fast).

One-Shot Design, Reusable Workflow

Traditional data visualization requires manually writing code to fetch data, transform it, and render it. This is time-consuming and rigid.

Dynamic Data View changes this paradigm:

  1. Design with Natural Language: You provide a reference data object, a set of tools (data fetchers), and a natural language description of the desired visualization (e.g., "A dark-themed card showing IP location and ISP info").
  2. LLM-Driven Workflow Generation: The library uses Gemini to explore your tools, figure out how to fetch the necessary data, and generate a visualization template (SVG, ECharts, etc.) that binds to this data.
  3. Deterministic Execution: The result is a Workflow—a JSON-serializable plan containing the data fetching steps and the rendering template.
  4. Infinite Re-use: You can now execute this workflow on new data inputs without calling the LLM again. This makes production deployment fast, cheap, and consistent.

Features

  • 🤖 AI-Powered Design: Automatically discovers how to use your tools to satisfy the visualization requirements.
  • ⚡️ Deterministic Execution: Generated workflows are static JSON objects. Running them is as fast as running a standard function.
  • 🔌 Backend Agnostic: Includes built-in support for SVG and ECharts, but can be extended to support any rendering format (HTML, Canvas, etc.).
  • 🛠️ Powerful Data Transformation: Uses JSONata for flexible, logic-free data binding in templates.
  • 📦 Type-Safe: Built with TypeScript for a great developer experience.

Installation

pnpm add dynamic-data-view @google/genai

If you plan to use the ECharts backend:

pnpm add echarts

Usage

1. Initialize

import { GoogleGenAI, Type } from '@google/genai';
import { DynamicDataView, SVGRenderBackend, EChartsRenderBackend } from 'dynamic-data-view';

const genai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const backend = new SVGRenderBackend(); // Or EChartsRenderBackend()
const ddv = new DynamicDataView(genai, backend);

2. Define Tools

Define the tools the model can use to fetch data. These are standard function definitions.

const tools = [
    {
        definition: {
            name: 'getIPInfo',
            description: 'Get information about an IP address.',
            parameters: {
                type: Type.OBJECT,
                properties: {
                    ip: { type: Type.STRING, description: 'The IP address.' },
                },
                required: ['ip'],
            },
        },
        callback: async ({ ip }) => {
            const res = await fetch(`https://ipinfo.io/${ip}/json`);
            return await res.text();
        },
    },
];

3. Design a Workflow (Design Phase)

Call designWorkflow with a reference data item and your design prompt. This calls the LLM.

const { rendered, workflow } = await ddv.designWorkflow({
    reference: { ip: '1.1.1.1' }, // Initial data to start the flow
    tools,
    designPrompt: 'A modern, dark-themed card showing the IP, City, and Region.',
});

// 'rendered' is the final SVG string (for this reference data)
// 'workflow' is the reusable JSON object

4. Execute a Workflow (Production Phase)

Save the workflow JSON. In production, load it and run it with new data. No LLM required!

const newRendered = await ddv.executeWorkflow(workflow, {
    reference: { ip: '8.8.8.8' }, // New data
    tools,
});

Showcase

SVG Output

Dynamic Data View can generate pure SVG visualizations. This is perfect for embedding in GitHub READMEs, emails, or static sites.

import { DynamicDataView, SVGRenderBackend } from 'dynamic-data-view';

const ddv = new DynamicDataView(genai, new SVGRenderBackend());

const { rendered } = await ddv.designWorkflow({
    reference: { ip: '1.1.1.1' },
    tools: [getIPInfoTool],
    designPrompt: 'A modern card showing IP location info.',
});

// 'rendered' is an SVG string
await fs.writeFile('card.svg', rendered);

ECharts with HTML Output

For interactive charts, you can generate ECharts configuration and render it in an HTML page.

import { DynamicDataView, EChartsRenderBackend } from 'dynamic-data-view';

const ddv = new DynamicDataView(genai, new EChartsRenderBackend());

const { rendered } = await ddv.designWorkflow({
    reference: { year: 2025 },
    tools: [getSalesDataTool],
    designPrompt: 'A dual-axis chart showing Sales and Profit.',
});

// 'rendered' is a JSON string of ECharts option
const html = `
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<div id="chart" style="width: 600px; height: 400px;"></div>
<script>
    echarts.init(document.getElementById('chart')).setOption(${rendered});
</script>
`;

ECharts with SVG Output

You can also render ECharts as static SVGs using server-side rendering (SSR). This is useful when you want the power of ECharts but need a static image.

import * as echarts from 'echarts';

// ... (Generate workflow as above with EChartsRenderBackend) ...

// Use ECharts SSR to render the option to SVG
const chart = echarts.init(null, null, {
    renderer: 'svg',
    ssr: true,
    width: 800,
    height: 600,
});

chart.setOption(JSON.parse(rendered));
const svg = chart.renderToSVGString();
echarts.dispose(chart);

Image Embed Example

Some platforms (like GitHub) don't allow remote images in SVGs for security reasons. Dynamic Data View provides an embedImageTool to fetch and embed images as Data URIs.

import { DynamicDataView, SVGRenderBackend, embedImageTool } from 'dynamic-data-view';

const ddv = new DynamicDataView(genai, new SVGRenderBackend());

const { rendered } = await ddv.designWorkflow({
    reference: { username: 'jacoblincool' },
    tools: [
        getGitHubUserTool, // Returns user info including avatar_url
        embedImageTool, // Built-in tool to convert URL to Data URI
    ],
    designPrompt: 'A GitHub user card. Embed the avatar image.',
});

API

DynamicDataView

The main class.

  • constructor(genai: GoogleGenAI, backend: RenderBackend)

designWorkflow(options)

Generates a new workflow and visualization.

  • options.reference: The initial data object.
  • options.tools: Array of tools (definition + callback).
  • options.designPrompt: Natural language description of the visualization.
  • options.modelName: (Optional) Gemini model to use (default: gemini-2.5-pro).
  • options.maxTurns: (Optional) Max tool use turns (default: 10).

Returns: Promise<{ rendered: string, workflow: Workflow, usageMetadata: UsageMetadata }>

executeWorkflow(workflow, options)

Executes an existing workflow with new data.

  • workflow: The workflow object returned by designWorkflow.
  • options.reference: New reference data.
  • options.tools: The tools array (must match the tools used in the workflow).

Returns: Promise<string> (The rendered output).

Built-in Tools

embedImageTool

A tool that fetches an image from a URL and converts it to a Data URI. This is useful for embedding images directly into SVGs.

  • Parameters:
    • url: The URL of the image to fetch.
  • Returns: A Data URI string (e.g., data:image/png;base64,...).

License

MIT