neon-realtime
Neon Realtime makes any SQL query live.
Skill by neondatabaseOfficial
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/neondatabase-neon-realtime
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design, backend, ml, agent-building
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/neon-realtime
What's inside
- Skill name
neon-realtime- Description
- Neon Realtime makes any SQL query live. Build realtime, reactive apps and agents on Lakebase Postgres with live SQL queries and reactivity primitives. Use when app UI or agent state must update live from database rows (dashboards, feeds, collaboration, multi-user or multi-device sync), for optimistic mutations, or to replace polling or other realtime sync systems. Triggers include "live query", "subscribe", "sync engine", "useLiveQuery", "TanStack DB", "optimistic updates", "@neon/realtime". For push that doesn't come from database rows (presence, typing, LLM streams), use neon-functions.
- License
- Apache-2.0
- Metadata
- parent: neon · source: https://github.com/neondatabase/agent-skills/tree/main/skills/neon-realtime
- Instructions
- 199 lines in SKILL.md · view on GitHub
Files (6)
- SKILL.md
- mutations.md · references/
- queries.md · references/
- reactivity.md · references/
- ssr.md · references/
- subscribing.md · references/
SKILL.md (first lines)
**FIRST**: Use the parent `neon` skill for a Neon overview, getting started with Neon, Neon development best practices, and more.
If the `neon` skill is not installed, fetch it from https://neon.com/docs/ai/skills/neon/SKILL.md or install it with:
```bash
neon skills -s neon -y
```
# Neon Realtime
Neon's Realtime makes any SQL query live. Subscribe in realtime to your Lakebase Postgres database. Develop apps and agents with end-to-end reactivity using type-safe live queries and optimistic mutations.
Realtime is new and in beta, so its APIs aren't in your training data. Start from the core pattern below, and read each section's reference file before writing that code.
## How It Works
Realtime's layers compose: a live query engine inside Postgres, the Live SQL API (a WebSocket API), lower-level client SDKs (`seal()`, `subscribe()`), and reactivity primitives such as `useLiveQuery`.
1. In trusted backend code, **define** a live query (any read-only SQL, including joins, aggregates, ordering and limits), **seal** it with `NEON_REALTIME_SECRET` and **expose** it from an authenticated endpoint or server function. The client can't read or change a sealed query's SQL or parameters.
2. The client **subscribes** with the sealed query. It receives the full initial result, then each committed transaction's changes as one batch. Results stay consistent, but delivery of every change event isn't guaranteed.
3. **Writes** go through your own API, which returns each write's `txid` for `awaitTxId()`.
## Core Pattern
The guides' chat app, with `messages` authorized through `channel_members`. The backend seals the query and returns each write's `txid`:
```ts
import { createRealtime, rawSql } from "@neon/realtime/server"
import { drizzleAdapter } from "@neon/realtime-drizzle"
import { and, desc, eq, getTableColumns, sql } from "drizzle-orm"
import { Hono } from "hono"
import { HTTPException } from "hono/http-exception"
import { requireUser } from "./auth"
import { db } from "./db"
import { channelMembers, messages, type Message } from "./schema"
export const realtime = createRealtime({ secret: process.env.NEON_REALTIME_SECRET!, db: "neondb", adapter: drizzleAdapter() })
// Each selected key must match its column name
export function messagesQuery(userId: string, channelId: number) {
return db
.select(getTableColumns(messages)).from(messages)
.innerJoin(channelMembers, eq(channelMembers.channel_id, messages.channel_id))
.where(and(eq(channelMembers.user_id, userId), eq(messages.channel_id, channelId)))
.orderBy(desc(messages.created_at))
.limit(50)
}
// Or raw SQL
const rawMessagesQuery = (userId: string, channelId: number) => rawSql<Message>(
`SELECT messages.author_id, messages.body, messages.channel_id, messages.created_at, messages.id FROM messages
INNER JOIN channel_members ON channel_members.channel_id = messages.channel_id WHERE channel_members.user_id = $1 AND messages.channel_id = $2 ORDER BY messages.created_at DESC LIMIT 50`,
[userId, channelId]
)
// The id of the transaction that made the change, read in the write's own RETURNING
const txid = sql<string>`pg_current_xact_id()::text`
const app = new Hono()
.post("/api/v1/messages/live", async (c) => {
const user = await requireUser(c)
const { channelId } = await c.req.json<{ channelId: number }>() // validate input
return c.json(await realtime.seal({ query: messagesQuery(user.id, channelId) }))
})
.post("/api/v1/messages", async (c) => {
const user = await requireUser(c)
const { id, channelId, body } = await c.req.json<{ id: string; channelId: number; body: string }>() // validate input
// One statement. The membership row supplies channel_id and author_id, so only a member's message is inserted.
// List every column in table order, alias each sql field, and cast untyped params (they resolve to text)
const [sent] = await db.insert(messages).select(
db.select({
id: sql`${id}::uuid`.as("id"), channel_id: channelMembers.channel_id, author_id: channelMembers.user_id,
body: sql`${body}`.as("body"), created_at: sql`now()`.as("created_at"),
})
.from(channelMembers)
.where(and(eq(channelMembers.channel_id, channelId), eq(channelMembers.user_id, user.id)))
).returning({ txid })
if (!sent) throw new HTTPException(403, { message: "Not a member of this channel" })
return c.json({ kind: "committed", txid: sent.txid })
})
```
The React frontend subscribes and sends optimistic messages:
```tsx
import { createRealtimeClient, type SealedLiveQuery } from "@neon/realtime/client"
import { drizzleParsers } from "@neon/realtime-drizzle/client"
import { useLiveQuery } from "@neon/realtime-react"
import { startTransition, useCallback, useOptimistic } from "react"
import type { Message } from "../backend/schema"
import { fetchSealedMessages, sendMessage } from "./api"
// One client per app, because subscriptions share its connection. Wrap the app in <RealtimeProvider client={client}>
export const client = createRealtimeClient({ url: import.meta.env.VITE_NEON_REALTIME_URL, parsers: { ...drizzleParsers } })
const NO_MESSAGES: readonly Message[] = []
type Props = { sealedQuery: SealedLiveQuery<Message>; channelId: number; userId: string }
export function Messages({ sealedQuery, channelId, userId }: Props) {
const refreshQuery = useCallback(() => fetchSealedMessages(channelId), [channelId])
const { data, status, error, utils } = useLiveQuery(sealedQuery, { refreshQuery })
// Once the sent message syncs, show only the synced row
const [messages, addOptimistic] = useOptimistic(data ?? NO_MESSAGES, (current, message: Message) =>
current.some(({ id }) => id === message.id) ? current : [message, ...current]
)
function send(body: string) {
// The server sets author and timestamp but keeps this id
const message = { id: crypto.randomUUID(), channel_id: channelId, author_id: userId, body, created_at: new Date() }
startTransition(async () => {
addOptimistic(message)
try {
const result = await sendMessage(message) // maps channel_id to channelId
if (result.kind === "committed") await utils.awaitTxId(result.txid, 10_000)
} catch { /* show "Couldn't confirm the change" */ }
})
}
if (status === "error") return <p role="alert">Live updates stopped: {error.message}</p>From neondatabase/agent-skills, Apache-2.0.
More from neondatabase/agent-skills
- 0.782score
neon-postgres
neondatabaseOfficial
Guides and best practices for working with Lakebase Postgres on Neon: connections, pooled vs direct, schema migrations, branching, autoscaling, scale-to-zero…
SkillAFreshness: A★ 105Claude Code +9 - 0.782score
neon
neondatabaseOfficial
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime.
SkillAFreshness: A★ 105Claude Code +9 - 0.776score
neon-object-storage
neondatabaseOfficial
S3-compatible object storage that branches with your database, so each branch gets its own copy of the files and the rows that point at them.
SkillAFreshness: A★ 105Claude Code +9 - 0.776score
neon-ai-gateway
neondatabaseOfficial
One API and one credential for frontier and open-source LLMs and embedding models, built into your Neon branch and powered by Databricks.
SkillAFreshness: A★ 105Claude Code +9 - 0.772score
neon-functions
neondatabaseOfficial
Long-running, serverless Node.js HTTP functions deployed onto your Neon branch, with DATABASE_URL injected automatically and compute that runs next to your…
SkillAFreshness: A★ 105Claude Code +9 - 0.736score
neon-auth
neondatabaseOfficial
Add authentication to a new app.
SkillBFreshness: B★ 105Claude Code +9 - 0.730score
neon-postgres-branches
neondatabaseOfficial
Choose and create the right Neon branch type for testing and development.
SkillBFreshness: B★ 105Claude Code +9 - 0.730score
neon-postgres-egress-optimizer
neondatabaseOfficial
Diagnose and fix excessive Postgres egress (network data transfer) in a codebase.
SkillBFreshness: B★ 105Claude Code +9 - 0.536score
score-eval
neondatabaseOfficial
No description from the publisher yet.
SkillDFreshness: D★ 105Claude Code +9
Compare and alternatives
Featured in
Signals
- Stars
- 105
- Forks
- 23
- Open issues
- 17
- Last commit (this folder)
- Oct 20, 2026 (7 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- Apache-2.0
- Repository
- github.com/neondatabase/agent-skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
Same skill elsewhere
Copies of this SKILL.md published by others; search shows only one of them.
More from neondatabase
- 0.782score
neon
neondatabaseOfficial
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime.
SkillAFreshness: A★ 105Claude Code +9 - 0.782score
neon-postgres
neondatabaseOfficial
Guides and best practices for working with Lakebase Postgres on Neon: connections, pooled vs direct, schema migrations, branching, autoscaling, scale-to-zero…
SkillAFreshness: A★ 105Claude Code +9 - 0.776score
neon-ai-gateway
neondatabaseOfficial
One API and one credential for frontier and open-source LLMs and embedding models, built into your Neon branch and powered by Databricks.
SkillAFreshness: A★ 105Claude Code +9 - 0.776score
neon-object-storage
neondatabaseOfficial
S3-compatible object storage that branches with your database, so each branch gets its own copy of the files and the rows that point at them.
SkillAFreshness: A★ 105Claude Code +9 - 0.772score
neon-functions
neondatabaseOfficial
Long-running, serverless Node.js HTTP functions deployed onto your Neon branch, with DATABASE_URL injected automatically and compute that runs next to your…
SkillAFreshness: A★ 105Claude Code +9 - 0.766score
claimable-postgres
neondatabaseOfficial
Provision instant temporary Postgres databases via Claimable Postgres by Neon (neon.new) with no login, signup, or credit card.
SkillBFreshness: B★ 655Claude Code +9
Cite this page
neon-realtime skill. Agent Mart. https://agentmart.dev/skills/neondatabase-neon-realtime (last updated 2026-10-24)