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

@sudodevstudio/genkitx-supabase

v0.2.1

Published

Genkit plugin for Supabase pgvector vector-store indexing, semantic search, and retrieval in TypeScript RAG apps.

Downloads

272

Readme

@sudodevstudio/genkitx-supabase

@sudodevstudio/genkitx-supabase is a Genkit community plugin that turns a Supabase Postgres + pgvector table into a Genkit indexer and retriever pair for RAG workflows.

If you want the short version first, see HOW_IT_WORKS.md.

It lets you keep embeddings, content, and JSONB metadata in Supabase while using the familiar Genkit flow:

  • configure a plugin with an indexName and embedder
  • index documents with ai.index()
  • retrieve relevant documents with ai.retrieve()
  • filter retrievals with JSONB metadata

Why Supabase + Genkit

Supabase gives you managed Postgres, pgvector, and JSONB in one place. Genkit gives you a clean retrieval/indexing abstraction inside AI flows. Together, they make it easy to build RAG pipelines that stay close to your application data and use standard Postgres tooling.

Features

  • Genkit plugin UX modeled after existing vector-store integrations
  • supabaseVectorStore(configs)
  • supabaseIndexerRef(indexName)
  • supabaseRetrieverRef(indexName)
  • batch embedding and upsert indexing
  • delete by id through ai.index()
  • top-k semantic retrieval through a Supabase RPC function
  • JSONB metadata filtering
  • configurable schema, table, RPC, and column names
  • useful validation and runtime errors

Install

npm install @sudodevstudio/genkitx-supabase @supabase/supabase-js genkit

If you want to use the Google AI quickstart below:

npm install @genkit-ai/google-genai

Quickstart

import { googleAI } from '@genkit-ai/google-genai';
import { Document, genkit } from 'genkit';
import {
  supabaseIndexerRef,
  supabaseRetrieverRef,
  supabaseVectorStore,
} from '@sudodevstudio/genkitx-supabase';

const ai = genkit({
  plugins: [
    googleAI(),
    supabaseVectorStore([
      {
        indexName: 'docs',
        embedder: googleAI.embedder('gemini-embedding-001'),
        connection: {
          url: process.env.SUPABASE_URL!,
          key: process.env.SUPABASE_SERVICE_ROLE_KEY!,
        },
        embeddingDimension: 3072,
      },
    ]),
  ],
});

const docsIndexer = supabaseIndexerRef('docs');
const docsRetriever = supabaseRetrieverRef('docs');

await ai.index({
  indexer: docsIndexer,
  documents: [
    Document.fromText('Supabase stores embeddings in Postgres.', {
      id: 'doc-1',
      topic: 'supabase',
    }),
  ],
});

const docs = await ai.retrieve({
  retriever: docsRetriever,
  query: 'Where are the embeddings stored?',
  options: { k: 3 },
});

SQL Setup

The package expects:

  • a pgvector-enabled table for documents
  • an RPC function that accepts query_embedding, match_count, and filter
  • rows containing your configured id, content, and metadata fields

SQL examples are included in:

Default schema:

  • id text primary key
  • content text not null
  • metadata jsonb not null default '{}'::jsonb
  • embedding extensions.vector(3072) not null
  • created_at timestamptz
  • updated_at timestamptz

If your embedder uses a different dimension, update both the table definition and the RPC function signature to match.

Usage

Configure the plugin

import { googleAI } from '@genkit-ai/google-genai';
import { genkit } from 'genkit';
import { supabaseVectorStore } from '@sudodevstudio/genkitx-supabase';

const ai = genkit({
  plugins: [
    googleAI(),
    supabaseVectorStore([
      {
        indexName: 'products',
        embedder: googleAI.embedder('gemini-embedding-001'),
        connection: {
          url: process.env.SUPABASE_URL!,
          key: process.env.SUPABASE_SERVICE_ROLE_KEY!,
        },
        schema: 'public',
        table: 'rag_documents',
        queryRpcName: 'match_rag_documents',
        idColumn: 'id',
        contentColumn: 'content',
        metadataColumn: 'metadata',
        embeddingColumn: 'embedding',
        defaultK: 5,
        embeddingDimension: 3072,
      },
    ]),
  ],
});

Index documents

Document ids are read from document.metadata.id. If a document already exists with the same id, it is updated.

import { Document } from 'genkit';
import { supabaseIndexerRef } from '@sudodevstudio/genkitx-supabase';

const productsIndexer = supabaseIndexerRef('products');

await ai.index({
  indexer: productsIndexer,
  documents: [
    Document.fromText('The red backpack fits a 16-inch laptop.', {
      id: 'sku-red-backpack',
      category: 'bags',
      inventoryStatus: 'in_stock',
    }),
    Document.fromText('The trail bottle keeps drinks cold for 18 hours.', {
      id: 'sku-trail-bottle',
      category: 'drinkware',
      inventoryStatus: 'in_stock',
    }),
  ],
});

Delete documents by id

Use the same ai.index() call with delete options:

await ai.index({
  indexer: productsIndexer,
  documents: [],
  options: {
    operation: 'delete',
    ids: ['sku-trail-bottle'],
  },
});

You can also omit options.ids and pass documents that contain metadata.id.

Retrieve documents

import { supabaseRetrieverRef } from '@sudodevstudio/genkitx-supabase';

const productsRetriever = supabaseRetrieverRef('products');

const docs = await ai.retrieve({
  retriever: productsRetriever,
  query: 'Which bag fits a laptop?',
  options: { k: 3 },
});

Metadata filter example

Metadata filters are passed to the RPC function as JSONB and work well with metadata @> filter.

const docs = await ai.retrieve({
  retriever: productsRetriever,
  query: 'Show me in-stock bags',
  options: {
    k: 5,
    filter: {
      category: 'bags',
      inventoryStatus: 'in_stock',
    },
  },
});

Public API

supabaseVectorStore(configs)

Registers one or more Supabase-backed vector stores by indexName.

Config fields:

  • indexName
  • embedder
  • connection: { url, key }
  • table?
  • queryRpcName?
  • idColumn?
  • contentColumn?
  • metadataColumn?
  • embeddingColumn?
  • schema?
  • defaultK?
  • embeddingDimension?
  • embedderOptions?

Defaults:

  • schema: 'public'
  • table: 'rag_documents'
  • queryRpcName: 'match_rag_documents'
  • idColumn: 'id'
  • contentColumn: 'content'
  • metadataColumn: 'metadata'
  • embeddingColumn: 'embedding'
  • defaultK: 3

supabaseIndexerRef(indexName)

Returns the Genkit indexer reference for ai.index().

Supported indexer options:

  • operation?: 'upsert' | 'delete'
  • ids?: Array<string | number>
  • batchSize?: number

supabaseRetrieverRef(indexName)

Returns the Genkit retriever reference for ai.retrieve().

Supported retriever options:

  • k?: number
  • filter?: Record<string, unknown>

Production Notes

  • Use a service role key on trusted servers only. Do not expose it in browser bundles.
  • Keep retrieval and indexing on the server side, especially when your table or RPC requires elevated database permissions.
  • Make sure the RPC function lives in an exposed schema and that Row Level Security policies allow the operations you need.
  • Keep your embeddingDimension aligned with the actual vector column dimension to catch mistakes before they hit Postgres.

Repository Contents

License

See LICENSE for the full terms.