Comments Vllnt
Threaded comments / annotations on any resource — post, reply, edit, resolve, and soft-delete as a Bijection component
git clone https://github.com/bijectionhq/comments-vllnt.git
cd comments-vllnt
git checkout c6348ee5d866861822d637ccfbd023d0cd8f4ad4Bijection 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.
Review the source and its dependencies before adopting this package. Source availability does not establish npm publication or runtime qualification.
Getting started
- Get the source at the revision above and read its package documentation.
- Check the required Bijection SDK version, dependencies, and external service credentials.
- Follow the package setup instructions and the guide to using components.
- 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.
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 anopencomment;parentIdthreads it as a reply. - Author-gated edits —
edit,remove(soft-delete), andresolverequire the originalauthorRef, elseNOT_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 —
removekeeps the row and replies but marks itdeletedand clears the body; a daily cron prunes deleted rows past retention. - Page or subscribe —
listpages oldest-first (deleted excluded by default),counttallies visible ones. Reactive in a Convex query. - Server-sourced time —
createdAt/updatedAt/editedAtare stamped from the server clock; a caller can't supply a timestamp. - Typed, opaque body —
Comments<TBody>types the storedbody;bodyValidatornarrows plain text vs rich blocks at the boundary. - Mount-safe — correct under multiple named
app.usemounts (e.g. acommentsmount + anannotationsmount); 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
| Method | Kind | Result |
|---|---|---|
post(ctx, resourceRef, authorRef, body, parentId?) | mutation | { commentId } |
edit(ctx, commentId, authorRef, body) | mutation | null (author-gated) |
remove(ctx, commentId, authorRef) | mutation | null (soft-delete, author-gated) |
resolve(ctx, commentId, authorRef, resolved?) | mutation | null (toggle, author-gated; resolved defaults true) |
get(ctx, commentId) | query | CommentView | null |
list(ctx, resourceRef, paginationOpts, opts?) | query | PaginationResult<CommentView> (opts: { parentId?; includeDeleted? }) |
count(ctx, resourceRef) | query | number (visible comments) |
prune(ctx, opts?) | mutation | number (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/resolverequire the originalauthorRef). 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/bodystay 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.