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

diagram-title-generator

v0.0.1

Published

Zero-dependency AI title generator for generic diagram data

Readme

📊 Diagram Title Generator

A lightweight, zero-dependency TypeScript library that generates intelligent titles for diagram data using AI (Gemini or OpenRouter APIs).

Architecture Diagram

✨ Features

  • 🪶 Zero Runtime Dependencies - Uses only native fetch and Promise
  • 🌍 Universal Compatibility - Works in Node.js, Edge Runtime, and browsers
  • 🤖 Dual Provider Support - Gemini and OpenRouter APIs
  • 🧠 Intelligent Extraction - Semantic crawling with field prioritization
  • 📦 Multiple Formats - CommonJS, ESM, and TypeScript declarations
  • ⚡ Tiny Bundle - Minified builds under 3KB

⚠️ Privacy & Security Notice

Data Sovereignty

IMPORTANT: This package sends your diagram content to external AI services (Google Gemini or OpenRouter). By using this library, diagram data leaves your infrastructure.

Implications:

  • Public/Non-Sensitive Data: Safe to use for public diagrams, demos, or non-confidential workflows
  • Enterprise/Regulated Data: If your diagrams contain PII, trade secrets, or data subject to GDPR/HIPAA/other regulations, do NOT use this package without:
    1. Legal review of the AI provider's data processing agreements
    2. Implementing data anonymization/redaction before sending
    3. Ensuring compliance with your organization's data governance policies

For Regulated Environments: Consider running a self-hosted AI model or using this package only in isolated, non-production environments.

Browser Usage Security

WARNING: This package works in browsers via native fetch, but NEVER hardcode API keys in frontend code:

// ❌ NEVER DO THIS (exposes your API key to all users)
const title = await generateTitle(data, {
  apiKey: 'sk-your-key-here' // Visible in browser DevTools!
});

// ✅ ALWAYS use a backend proxy
const response = await fetch('/api/generate-title', {
  method: 'POST',
  body: JSON.stringify({ diagramData })
});
const { title } = await response.json();

The package will log a console warning if it detects API key usage in a browser environment.

📥 Installation

npm install diagram-title-generator

🚀 Quick Start

Using Google Gemini API

import { generateTitle } from 'diagram-title-generator';

const diagramData = {
  nodes: [
    { id: '1', text: 'User Login', type: 'Input' },
    { id: '2', text: 'Authenticate', type: 'Process' },
    { id: '3', text: 'Database', type: 'Storage' }
  ],
  edges: []
};

const title = await generateTitle(diagramData, {
  apiKey: process.env.GEMINI_API_KEY,
  provider: 'google',
  model: 'gemini-2.5-flash' // optional, this is the default
});

console.log(title); // e.g., "User Authentication Flow"

Using OpenRouter API

import { generateTitle } from 'diagram-title-generator';

const title = await generateTitle(diagramData, {
  apiKey: process.env.OPENROUTER_API_KEY,
  provider: 'openrouter',
  model: 'google/gemini-2.0-flash-lite-preview' // optional, this is the default
});

🔑 API Key Setup

Getting a Gemini API Key

  1. Visit Google AI Studio
  2. Click "Get API Key"
  3. Copy your key and add to your project:
# .env file
GEMINI_API_KEY=your_api_key_here

Getting an OpenRouter API Key

  1. Visit OpenRouter
  2. Sign up and navigate to "Keys"
  3. Create a new API key
  4. Add to your project:
# .env file
OPENROUTER_API_KEY=your_api_key_here

🧪 Local Testing

1. Clone and Install

git clone <your-repo-url>
cd diagram-title-generator
npm install

2. Build the Package

npm run build

This generates files in dist/:

  • index.js (CommonJS)
  • index.mjs (ESM)
  • index.d.ts (TypeScript types)

3. Create a Test File

Create local-test.js in the project root:

// local-test.js
require('dotenv').config(); // if using dotenv
const { generateTitle } = require('./dist/index.js');

const mockDiagram = {
  nodes: [
    { text: 'Start', type: 'StartEvent' },
    { text: 'Process Order', type: 'Task' },
    { text: 'Payment Gateway', type: 'Service' },
    { text: 'End', type: 'EndEvent' }
  ]
};

async function test() {
  try {
    // Test with Gemini
    const title = await generateTitle(mockDiagram, {
      apiKey: process.env.GEMINI_API_KEY,
      provider: 'google'
    });
    
    console.log('Generated Title:', title);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

test();

4. Run the Test

# Set your API key inline (macOS/Linux)
GEMINI_API_KEY=your_key_here node local-test.js

# Or use dotenv
npm install dotenv
node local-test.js

🧪 Testing

The package includes a comprehensive test suite with 97%+ code coverage.

Run Tests

# Run all unit tests
npm test

# Watch mode (re-runs on file changes)
npm run test:watch

# Generate coverage report
npm run test:coverage

# Interactive UI
npm run test:ui

Test Structure

  • Unit Tests (extractor.test.ts) - 22 tests covering semantic extraction, circular references, depth limiting, and edge cases
  • Generator Tests (generator.test.ts) - 22 tests with mocked API calls for both providers
  • Integration Tests (integration.test.ts) - Optional real API tests (requires API keys)

Integration Tests (Optional)

To run tests with real API calls:

# 1. Copy environment template
cp .env.example .env

# 2. Add your API keys to .env
# GEMINI_API_KEY=your_real_key
# OPENROUTER_API_KEY=your_real_key

# 3. Run integration tests
npm run test:integration

Note: Integration tests are automatically skipped if API keys are not available.

🔧 Configuration Options

interface TitleOptions {
  /** API Key for the selected provider (required) */
  apiKey: string;
  
  /** Provider to use (optional, defaults to 'google') */
  provider?: 'google' | 'openrouter';
  
  /** Model to use (optional) */
  model?: string;
  
  /** Custom base URL for proxy/self-hosted APIs (optional) */
  baseUrl?: string;
  
  /** If true, throws errors instead of returning fallback title (optional, defaults to false) */
  throwOnError?: boolean;
}

Error Handling

By default, the package returns "Untitled Diagram" if generation fails (network errors, invalid API keys, etc.). This ensures your application doesn't crash.

For stricter error handling, use throwOnError:

try {
  const title = await generateTitle(diagramData, {
    apiKey: process.env.GEMINI_API_KEY,
    provider: 'google',
    throwOnError: true  // Throws on any error
  });
  console.log(title);
} catch (error) {
  // Handle the error explicitly
  console.error('Title generation failed:', error.message);
  // Implement your own fallback logic
}

Default Models

  • Gemini: gemini-2.5-flash
  • OpenRouter: google/gemini-2.0-flash-lite-preview

Custom Models

// Use GPT-4 via OpenRouter
const title = await generateTitle(diagramData, {
  apiKey: process.env.OPENROUTER_API_KEY,
  provider: 'openrouter',
  model: 'openai/gpt-4-turbo'
});

// Use a different Gemini model
const title = await generateTitle(diagramData, {
  apiKey: process.env.GEMINI_API_KEY,
  provider: 'google',
  model: 'gemini-1.5-pro'
});

📚 Usage in Existing Projects

React / Next.js

// components/DiagramTitleGenerator.tsx
import { generateTitle } from 'diagram-title-generator';
import { useState } from 'react';

export function DiagramTitleGenerator({ diagramData }) {
  const [title, setTitle] = useState('');

  async function handleGenerate() {
    const result = await generateTitle(diagramData, {
      apiKey: process.env.NEXT_PUBLIC_GEMINI_API_KEY,
      provider: 'google'
    });
    setTitle(result);
  }

  return (
    <div>
      <button onClick={handleGenerate}>Generate Title</button>
      <h2>{title}</h2>
    </div>
  );
}

Node.js / Express API

// routes/diagram.ts
import { generateTitle } from 'diagram-title-generator';

app.post('/api/diagram/title', async (req, res) => {
  try {
    const { diagramData } = req.body;
    
    const title = await generateTitle(diagramData, {
      apiKey: process.env.GEMINI_API_KEY,
      provider: 'google'
    });
    
    res.json({ title });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

Edge Runtime (Vercel, Cloudflare Workers)

// api/generate-title.ts
import { generateTitle } from 'diagram-title-generator';

export const config = { runtime: 'edge' };

export default async function handler(req: Request) {
  const { diagramData } = await req.json();
  
  const title = await generateTitle(diagramData, {
    apiKey: process.env.OPENROUTER_API_KEY,
    provider: 'openrouter'
  });
  
  return new Response(JSON.stringify({ title }), {
    headers: { 'content-type': 'application/json' }
  });
}

🧩 Supported Diagram Structures

The library intelligently extracts context from any JSON structure. It works with:

Flowcharts

{
  nodes: [{ text: 'Step 1', type: 'Process' }],
  edges: []
}

Mind Maps

{
  central: 'Main Idea',
  branches: [
    { label: 'Branch 1', children: [] }
  ]
}

Entity Relationships

{
  entities: [
    { name: 'User', type: 'Person' },
    { name: 'Order', type: 'Transaction' }
  ]
}

Custom Formats

The extractor prioritizes these fields:

  • text, label, content, title, name, header
  • type (for semantic info like "Process", "Database")

⚠️ Important Notes

API Key Security

Never commit API keys to version control!

Good Practices:

# .env (add to .gitignore)
GEMINI_API_KEY=your_key_here

# Use environment variables
const title = await generateTitle(data, {
  apiKey: process.env.GEMINI_API_KEY
});

Bad Practice:

// NEVER do this
const title = await generateTitle(data, {
  apiKey: 'hardcoded-key-here' // ❌ Security risk!
});

Client-Side Usage

For browser usage, use a backend proxy to protect your API key:

// ❌ Don't expose API keys in client code
// ✅ Instead, call your own API endpoint

async function getTitle(diagramData) {
  const response = await fetch('/api/generate-title', {
    method: 'POST',
    body: JSON.stringify({ diagramData })
  });
  return response.json();
}

🛠️ Development

# Install dependencies
npm install

# Build the package
npm run build

# Watch mode for development
npm run dev

# Run basic test
npm test

📄 License

MIT

🤝 Contributing

Contributions are welcome! Please open an issue or submit a pull request.

🔗 Resources


Built with ❤️ for developers who need smart diagram titles