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

convex-supermemory

v0.0.5

Published

Give your Convex app long-term, semantically searchable memory with Supermemory. Reactive local memory and document state, direct REST integration.

Readme

convex-supermemory

Give your Convex app long-term, semantically searchable memory with Supermemory. Reactive local memory and document state, direct REST integration.

npm version Convex Component npm downloads License

convex-supermemory demo

const supermemory = new Supermemory(components.convexSupermemory, {
  apiKey: process.env.SUPERMEMORY_API_KEY!,
});

// Store a fact about a user
const { memoryId } = await supermemory.addMemory(ctx, {
  containerTag: userId,
  content: "Prefers dark mode and terse responses",
});

// Recall it later with semantic search
const { results } = await supermemory.search({
  containerTag: userId,
  query: "how does this user like responses formatted?",
});

What this does

An AI agent is only as good as what it remembers between calls. Supermemory is a memory API purpose-built for this: you write facts and documents into a containerTag (typically one per user or agent), and it handles embedding, chunking, and semantic search so you can recall the right context later — without you running your own vector database.

This component wraps Supermemory's REST API directly (no SDK dependency) and mirrors everything you write into Convex tables, so you get:

  • Fast-path memoryaddMemory() stores a single fact immediately, no processing pipeline
  • Document ingestionaddDocument() sends larger content through Supermemory's extraction/chunking pipeline, with refreshDocument() to poll status
  • Semantic searchsearch() proxies Supermemory's hybrid RAG + memory search live
  • Reactive local state — every memory and document is queryable from Convex without an extra API call
  • ForgettingforgetMemory() / deleteDocument() keep local state in sync with what Supermemory actually removes

Table of Contents

Install

npm install convex-supermemory

Requirements: Convex v1.33.1 or later, Node.js 18+, a Supermemory API key

Quick Start

Three steps to add memory to your Convex app.

1. Add the component

In convex/convex.config.ts:

import { defineApp } from "convex/server";
import convexSupermemory from "convex-supermemory/convex.config";

const app = defineApp();
app.use(convexSupermemory);

export default app;

2. Set environment variables

npx convex env set SUPERMEMORY_API_KEY sm_xxxxxxxxxxxx

3. Initialize the client

In convex/memory.ts:

import { components } from "./_generated/api";
import { Supermemory } from "convex-supermemory";

export const supermemory = new Supermemory(components.convexSupermemory, {
  apiKey: process.env.SUPERMEMORY_API_KEY!,
});

Import supermemory from this file in any Convex action that needs to read or write memory.

Usage

Remember a fact

export const remember = action({
  args: { userId: v.string(), fact: v.string() },
  handler: async (ctx, args) => {
    return await supermemory.addMemory(ctx, {
      containerTag: args.userId,
      content: args.fact,
      isStatic: true, // long-term fact, not a fading conversational detail
    });
  },
});
// Returns: { memoryId }

Recall with semantic search

export const recall = action({
  args: { userId: v.string(), query: v.string() },
  handler: async (ctx, args) => {
    return await supermemory.search({
      containerTag: args.userId,
      query: args.query,
      limit: 5,
    });
  },
});
// Returns: { results: [{ documentId, score, summary, chunks, ... }], total }

Forget a memory

containerTag is required here too — Supermemory scopes the delete by it, not just by memoryId.

export const forget = action({
  args: { userId: v.string(), memoryId: v.string() },
  handler: async (ctx, args) => {
    return await supermemory.forgetMemory(ctx, {
      containerTag: args.userId,
      memoryId: args.memoryId,
    });
  },
});
// Returns: { forgotten: boolean }

List a user's memories reactively

export const getMemories = query({
  args: { userId: v.string() },
  handler: async (ctx, args) => {
    return await supermemory.listMemories(ctx, { containerTag: args.userId });
  },
});

Memories vs. Documents

Supermemory exposes two ways to write content, and this component exposes both:

  • addMemory() — for short, discrete facts ("the user is on the Pro plan", "prefers metric units"). No processing delay; usable in search immediately.
  • addDocument() — for longer content (a support transcript, a page of documentation, a whole conversation) that needs to be chunked and embedded. Processing is asynchronous — call refreshDocument() to check on status (queuedextractingchunkingembeddingindexingdone).

API Reference

| Method | Kind | Description | | --- | --- | --- | | addMemory(ctx, args) | action | Stores a single fact immediately | | forgetMemory(ctx, args) | action | Requests Supermemory forget a memory (scoped by containerTag) | | addDocument(ctx, args) | action | Ingests larger content through the chunking pipeline | | refreshDocument(ctx, args) | action | Pulls the latest status/title/summary for a document | | deleteDocument(ctx, args) | action | Deletes a document from Supermemory and locally | | search(args) | plain async | Live semantic search — not cached locally | | getMemory(ctx, args) | query | Fetch one memory by id | | listMemories(ctx, args) | query | List a container's memories, newest first | | getDocument(ctx, args) | query | Fetch one document by id | | listDocuments(ctx, args) | query | List a container's documents, newest first | | getStats(ctx) | query | Aggregate memory/document counts for a small dashboard | | listRecentMemories(ctx, args?) | query | Every memory, newest first, regardless of containerTag | | listRecentDocuments(ctx, args?) | query | Every document, newest first, regardless of containerTag |

Type Reference

type AddMemoryArgs = {
  containerTag: string;
  content: string;
  isStatic?: boolean;
  metadata?: Record<string, unknown>;
  forgetAfter?: number;   // ms epoch
  forgetReason?: string;
};

type AddDocumentArgs = {
  containerTag: string;
  content: string;
  customId?: string;
  metadata?: Record<string, unknown>;
};

type SearchArgs = {
  containerTag: string;
  query: string;
  limit?: number;
  rerank?: boolean;
  includeFullDocs?: boolean;
};

type SearchResponse = {
  results: Array<{
    documentId: string;
    title: string | null;
    score: number;
    summary: string | null;
    content: string | null;
    chunks: Array<{ content: string; score: number; position: number; isRelevant: boolean }>;
  }>;
  total: number;
  timing?: number; // ms, when Supermemory reports it
};

Database Schema

memories: {
  memoryId, containerTag, content, isStatic, metadata?,
  forgetAfter?, forgetReason?, forgotten,
  createdAt, updatedAt,
}

documents: {
  documentId, containerTag, content?, customId?, metadata?, status,
  title?, summary?,
  createdAt, updatedAt,
}

getStats(), listRecentMemories(), and listRecentDocuments() read across these tables directly with a full scan — fine for a dashboard or history view, not intended as a high-volume production query path.

Container Tags

Supermemory scopes everything — writes, search, and profiles — by containerTag. Use one per user for personal memory, or one per agent/workspace for shared memory. Search only ever looks within the container tag you pass, so pick a convention early (this component doesn't enforce one).

Testing

npm run test

Component logic is tested with convex-test in src/component/lib.test.ts. Import convex-supermemory/test in your own app to register this component's schema against your test instance.

Example App

example/ is a full Vite + React demo that exercises the entire component end to end against your own Supermemory account:

  • Memories — add a fact with addMemory() (with suggestion chips to try), forget it with forgetMemory(), all reactive.
  • Documents — ingest longer content with addDocument(), poll status with refreshDocument(), remove it with deleteDocument().
  • Search — run search() against whichever containerTag is selected, showing result score, matching chunks, and Supermemory's own reported total/timing.
  • containerTag switcher — a row of chips lets you flip between a few demo users live, so you can see the exact same actions land in completely separate memory spaces.
  • History — every memory and document ever written in the deployment, newest first, across every containerTag. Expand a row for full detail, or hit Recreate live to replay it as a brand-new memory/document.
  • Activity console — a side-docked live log of every call this app makes into the Supermemory client, including real API errors (e.g. Supermemory returns 409 if you try to delete a document that's still processing).

Run it from the repo root:

npm install --legacy-peer-deps
npx convex env set SUPERMEMORY_API_KEY sm_xxxxxxxxxxxx
npm run dev

npm run dev starts the Convex backend and the Vite frontend together — there's no need to cd example or run either one separately.

Limitations

  • search() always calls Supermemory live — results are not cached or mirrored into Convex tables, since they're a ranked view over the underlying memories/documents rather than durable records themselves.
  • Document processing is asynchronous; this component does not poll for you. Call refreshDocument() on a schedule (e.g. a Convex cron or scheduled function) if you need status without a user-triggered refresh.
  • forgetMemory() reflects whatever forgotten value Supermemory returns — if Supermemory forgets asynchronously, the local record may briefly still show forgotten: false.
  • deleteDocument() throws if Supermemory reports the document is still processing (409) — retry after the document reaches a terminal status (done/failed).

Troubleshooting

401/403 from Supermemory — confirm SUPERMEMORY_API_KEY is set and starts with sm_.

Search returns nothing — confirm you're searching the same containerTag you wrote memories/documents into; container tags are exact-match scopes, not fuzzy. If the document was ingested moments ago, give it a few seconds to finish indexing even after refreshDocument() reports done.

Document stuck in queued/extracting — large documents can take longer to process; call refreshDocument() again after a short delay.

Deleting a document fails with a "still processing" error — Supermemory returns 409 for a document that hasn't reached a terminal status yet; wait for refreshDocument() to report done or failed, then delete.

Contributing

See CONTRIBUTING.md.

Changelog

See CHANGELOG.md.