Skip to content

Find a component

Loading the directory…

↑ ↓ to select · Enter to open · Esc to closeBrowse all →
Contributor login

Comments Vllnt

Threaded comments / annotations on any resource — post, reply, edit, resolve, and soft-delete as a Bijection component

Bijection source
git clone https://github.com/bijectionhq/comments-vllnt.git
cd comments-vllnt
git checkout c6348ee5d866861822d637ccfbd023d0cd8f4ad4

Bijection repository access is required. Request access.

Description

Threaded comments / annotations on any resource — post, reply, edit, resolve, and soft-delete as a Bijection component

Explore the package README for API concepts, configuration, and examples. Check the Bijection source for adaptation-specific setup.

Available as a reference

Review the source and its dependencies before adopting this package. Source availability does not establish npm publication or runtime qualification.

Getting started

  1. Get the source at the revision above and read its package documentation.
  2. Check the required Bijection SDK version, dependencies, and external service credentials.
  3. Follow the package setup instructions and the guide to using components.
  4. Exercise the component in your deployment according to your project’s verification rules.

Open source

Maintained source: bijectionhq/comments-vllnt. Based on vllnt/convex-comments. License: MIT. Consult the repository for license terms, notices, and contributor attribution.

From the upstream publisher

Threaded comments / annotations on any resource — post, reply, edit, resolve, and soft-delete as a Convex component

Explore the demo ↗

Upstream overview

From the upstream package documentation.

@vllnt/convex-comments attaches discussions to any resource your application identifies. The host supplies resource and author references plus a typed body, keeping the component independent of a specific content model.

post creates a comment or a same-resource reply. list paginates threads, count reports visible comments, and edit, remove, and resolve support author operations. Soft deletion clears the body while retaining the thread structure until retention cleanup. Host Convex queries can expose reactive updates.

Your backend authenticates the author, controls resource access, and supplies trusted author references. It also owns moderation and safe rendering of text or rich content. Authorship checks compare supplied references; they do not authenticate a caller on their own.

Maintained by bntvllnt at VLLNT. Find the author on GitHub and X.

Use cases

From the upstream package documentation.

  • Document tools: attach comments and replies to a document or host-defined annotation target.
  • Learning platforms: add questions and discussions to lessons.
  • Communities: build threaded replies under posts or user creations.
  • Games: collect discussion around shared results, maps, or guides.

How it works

From the upstream package documentation.

post creates a comment or a same-resource reply. list paginates threads, count reports visible comments, and edit, remove, and resolve support author operations. Soft deletion clears the body while retaining the thread structure until retention cleanup. Host Convex queries can expose reactive updates.

Your backend authenticates the author, controls resource access, and supplies trusted author references. It also owns moderation and safe rendering of text or rich content. Authorship checks compare supplied references; they do not authenticate a caller on their own.

Upstream package FAQ

Does @vllnt/convex-comments come with a React UI component?

@vllnt/convex-comments is a backend-only Convex component and does not ship a React entry point. You build the UI by calling your own re-exported host query and mutation functions, for example using useQuery or usePaginatedQuery over your list and count wrappers.

How does @vllnt/convex-comments handle authentication?

@vllnt/convex-comments is auth-agnostic for access control. The host application resolves the user identity using its own auth system and passes an opaque authorRef string to each mutation. The component only enforces that edit, remove, and resolve are called by the original author; broader access rules such as who may post or moderate are entirely the host's responsibility.

Can I use @vllnt/convex-comments for both comments and annotations in the same app?

Yes. Because @vllnt/convex-comments is mount-safe, you can register it twice under different names using app.use, for example once as comments and once as annotations. Each mount gets its own isolated table sandbox and a separate Comments instance, so the two contexts never share data.

What version of Convex does @vllnt/convex-comments require?

@vllnt/convex-comments requires convex@^1.41.0 as a peer dependency. Install the package with npm install @vllnt/convex-comments or pnpm add @vllnt/convex-comments, then register the component in convex/convex.config.ts using app.use(comments).

How does pagination work in @vllnt/convex-comments?

The list method on @vllnt/convex-comments accepts a standard Convex paginationOptsValidator argument and returns a PaginationResult<CommentView> ordered oldest-first. You can scope pagination to direct replies of a specific parent by passing opts.parentId. The query is reactive, so clients subscribed via usePaginatedQuery receive live updates when new comments are posted.

Use with agents and CLI

Give your coding agent the component’s source identity and setup guidance.

agent-prompt.md
Help me integrate Comments Vllnt with Bijection.

Read: https://bijection.com/components/comments-vllnt/SKILL.md

Check SDK compatibility and dependency availability.
Follow this project's execution and verification rules.

Upstream README.md

View repository ↗

Documentation from vllnt/convex-comments, recorded October 23, 2026. APIs and setup may differ in the Bijection adaptation.

@vllnt/convex-comments

Threaded comments / annotations on any resource, as a Convex component.

const comments = new Comments(components.comments);
await comments.post(ctx, resourceRef, authorRef, body, parentId); // parentId threads a reply
await comments.list(ctx, resourceRef, paginationOpts);            // reactive thread
await comments.resolve(ctx, commentId, authorRef);               // author-gated

A host attaches a comment to an opaque resourceRef (an article, a doc, a clip — anything); replies thread under a parent; the author edits, resolves, and soft-deletes their own comments; clients page a resource's thread or subscribe reactively.

Features

  • Post on any resource — post(resourceRef, authorRef, body, parentId?) inserts an open comment; parentId threads it as a reply.
  • Author-gated edits — edit, remove (soft-delete), and resolve require the original authorRef, else NOT_AUTHOR.
  • Threaded — a reply links to a parent on the same resource (cross-resource or deleted parent rejected); list(..., { parentId }) pages direct replies.
  • Soft-delete + retention — remove keeps the row and replies but marks it deleted and clears the body; a daily cron prunes deleted rows past retention.
  • Page or subscribe — list pages oldest-first (deleted excluded by default), count tallies visible ones. Reactive in a Convex query.
  • Server-sourced time — createdAt/updatedAt/editedAt are stamped from the server clock; a caller can't supply a timestamp.
  • Typed, opaque body — Comments<TBody> types the stored body; bodyValidator narrows plain text vs rich blocks at the boundary.
  • Mount-safe — correct under multiple named app.use mounts (e.g. a comments mount + an annotations mount); each is an isolated sandbox.

Installation

pnpm add @vllnt/convex-comments

Peer dependency: convex@^1.41.0.

Usage

// convex/convex.config.ts
import { defineApp } from "convex/server";
import comments from "@vllnt/convex-comments/convex.config";

const app = defineApp();
app.use(comments);
export default app;
// convex/comments.ts — host owns auth; resolve identity, pass opaque refs in.
import { components } from "./_generated/api";
import { mutation, query } from "./_generated/server";
import { paginationOptsValidator } from "convex/server";
import { v } from "convex/values";
import { Comments } from "@vllnt/convex-comments";

const comments = new Comments<string>(components.comments, {
  bodyValidator: v.string().parse, // narrow at the boundary (plain text here)
});

export const postComment = mutation({
  args: { resourceRef: v.string(), body: v.string(), parentId: v.optional(v.string()) },
  handler: async (ctx, { resourceRef, body, parentId }) => {
    const authorRef = await requireUser(ctx); // host auth
    return comments.post(ctx, resourceRef, authorRef, body, parentId);
  },
});

export const listComments = query({
  args: { resourceRef: v.string(), paginationOpts: paginationOptsValidator },
  handler: (ctx, { resourceRef, paginationOpts }) =>
    comments.list(ctx, resourceRef, paginationOpts),
});

API Reference

MethodKindResult
post(ctx, resourceRef, authorRef, body, parentId?)mutation{ commentId }
edit(ctx, commentId, authorRef, body)mutationnull (author-gated)
remove(ctx, commentId, authorRef)mutationnull (soft-delete, author-gated)
resolve(ctx, commentId, authorRef, resolved?)mutationnull (toggle, author-gated; resolved defaults true)
get(ctx, commentId)queryCommentView | null
list(ctx, resourceRef, paginationOpts, opts?)queryPaginationResult<CommentView> (opts: { parentId?; includeDeleted? })
count(ctx, resourceRef)querynumber (visible comments)
prune(ctx, opts?)mutationnumber (deleted comments removed in the first bounded pass)

Full reference: docs/API.md.

React

Backend-only — no ./react entry. A comment thread is an ordinary reactive useQuery / usePaginatedQuery over the host's own re-exported list / count refs.

Security

  • Auth-agnostic for access; the component enforces only authorship (edit/remove/resolve require the original authorRef). The host owns who may post or moderate.
  • Tables sandboxed — reached only through the exported functions; never touches host or sibling tables.
  • Server-sourced time; resourceRef / authorRef / body stay opaque to the component.

See docs/API.md.

Testing

pnpm test           # single run
pnpm test:coverage  # enforced 100% on covered files

Tests run against the real component runtime via convex-test (@edge-runtime/vm), not mocks.

Contributing

See CONTRIBUTING.md.

Author

Built by bntvllnt · bntvllnt.com · X @bntvllnt

Part of the @vllnt Convex component fleet — vllnt.com

If this is useful, sponsor the work.

License

MIT — see LICENSE.

Keywords