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

winnow-db

v0.1.0

Published

High-performance vector database for JavaScript. Runs in browser & Node.js. No server required.

Readme

WinnowDB

High-performance vector database for JavaScript/TypeScript

Run semantic search, recommendations, and AI applications entirely in the browser or Node.js. No server required.

Quick Install

npm install @winnow-db/winnow-db

30-Second Example

import init, { WinnowCollection } from '@winnow-db/winnow-db';

// Initialize (call once)
await init();

// Create collection
const db = new WinnowCollection("vectors", {
    dim: 128,
    index_type: "HNSW",
    max_elements: 10000
}, null);

// Add vectors
db.add(1, new Float32Array(128).fill(0.5), null, null, '{"name": "doc1"}');
db.add(2, new Float32Array(128).fill(0.3), null, null, '{"name": "doc2"}');

// Search (returns [[id, distance], ...])
const results = db.search(new Float32Array(128).fill(0.5), 5, null, null);
console.log(results); // [[1, 0], [2, 0.04], ...]

// Cleanup
db.free();

API Reference

Create Collection

const collection = new WinnowCollection(name, config, null);

Config options:

| Option | Type | Default | Description | |--------|------|---------|-------------| | dim | number | required | Vector dimension | | index_type | string | "HNSW" | Index type: "HNSW", "IVFPQ", "SQ", "BQ" | | max_elements | number | required | Maximum vectors | | m | number | 16 | HNSW connections per layer | | ef_construction | number | 100 | HNSW build quality |

Add Vector

collection.add(id, vector, null, null, payload);
  • id: number - Unique ID
  • vector: Float32Array - Your embedding
  • payload: string - JSON metadata (optional)

Search

const results = collection.search(queryVector, k, filter, null);
// Returns: [[id, distance], [id, distance], ...]
  • queryVector: Float32Array - Query embedding
  • k: number - How many results
  • filter: object - Filter by payload fields (optional)

Other Methods

collection.delete(id)           // Remove vector
collection.exists(id)           // Check if exists
collection.count()              // Get count
collection.get_payload(id)      // Get metadata
collection.update_payload(id, json) // Update metadata
collection.clear()              // Remove all
collection.snapshot()           // Export as bytes
collection.free()               // Cleanup memory

Examples

Semantic Text Search

import init, { WinnowCollection } from '@winnow-db/winnow-db';

await init();

const db = new WinnowCollection("docs", {
    dim: 384, // all-MiniLM-L6-v2 dimension
    index_type: "HNSW",
    max_elements: 10000
}, null);

// Add documents (use your embedding model)
const docs = [
    { id: 1, text: "JavaScript is a programming language" },
    { id: 2, text: "Python is great for data science" },
    { id: 3, text: "Rust is fast and memory-safe" }
];

for (const doc of docs) {
    const embedding = await getEmbedding(doc.text); // Your embedding function
    db.add(doc.id, embedding, null, null, JSON.stringify(doc));
}

// Search
const query = await getEmbedding("web development language");
const results = db.search(query, 3, null, null);

for (const [id, score] of results) {
    console.log(db.get_payload(id));
}

Filtered Search

// Add with category
db.add(1, vec1, null, null, '{"title": "JS Guide", "category": "web"}');
db.add(2, vec2, null, null, '{"title": "ML Intro", "category": "ai"}');
db.add(3, vec3, null, null, '{"title": "React Tips", "category": "web"}');

// Search only "web" category
const results = db.search(query, 10, { category: "web" }, null);

Save and Load

// Save
const bytes = db.snapshot();
localStorage.setItem('mydb', btoa(String.fromCharCode(...bytes)));

// Load
const saved = localStorage.getItem('mydb');
const bytes = new Uint8Array([...atob(saved)].map(c => c.charCodeAt(0)));
const db = WinnowCollection.load_snapshot(bytes, null);

Browser Usage

<!DOCTYPE html>
<html>
<head>
    <title>WinnowDB Demo</title>
</head>
<body>
    <script type="module">
        import init, { WinnowCollection } from './node_modules/@winnow-db/winnow-db/winnow_db.js';
        
        await init();
        
        const db = new WinnowCollection("search", {
            dim: 128,
            index_type: "HNSW", 
            max_elements: 1000
        }, null);
        
        // Add some vectors
        for (let i = 0; i < 100; i++) {
            const vec = new Float32Array(128).fill(i / 100);
            db.add(i, vec, null, null, JSON.stringify({ id: i }));
        }
        
        // Search
        const query = new Float32Array(128).fill(0.5);
        const results = db.search(query, 5, null, null);
        console.log('Results:', results);
    </script>
</body>
</html>

Performance

| Vectors | Insert | Search | Latency | |---------|--------|--------|---------| | 1,000 | 4,300/s | 20,000 qps | 0.05ms | | 10,000 | 2,000/s | 13,000 qps | 0.08ms | | 100,000 | 1,000/s | 5,000 qps | 0.2ms |

Use Cases

  • RAG: Retrieval for LLM applications
  • Search: Semantic search in documents
  • Recommendations: Similar items/users
  • Image Search: Find similar images
  • Offline: Works without internet

License

MIT