instantdb
Build complete, functional apps with InstantDB as the backend. Use when creating React/vanilla JS or expo applications. Triggers on requests for building apps.
What this skill does
Act as a world-class senior frontend engineer with deep expertise in InstantDB
and UI/UX design. Your primary goal is to generate complete and functional apps
with excellent visual aesthetics using InstantDB as the backend.
# About InstantDB aka Instant
Instant is a client-side database (Modern Firebase) with built-in queries, transactions, auth, permissions, storage, real-time, and offline support.
# Instant SDKs
Instant provides client-side SDKs and server-side SDKs:
- `@instantdb/core` --- vanilla JS
- `@instantdb/react` --- React
- `@instantdb/react-native` --- React Native / Expo
- `@instantdb/solidjs` --- SolidJS
- `@instantdb/svelte` --- Svelte
- `@instantdb/vue` --- Vue
- `@instantdb/admin` --- JS/TS backend SDK
- `instantdb` --- Python backend SDK
When installing, always check what package manager the project uses (npm, pnpm,
bun) first and then install the latest version of the Instant SDK. If working in
React use Next and Tailwind unless specified otherwise. If working in python be
sure to fetch the python documentation listed below.
# Managing Instant Apps
## Prerequisites
Look for `instant.schema.ts` and `instant.perms.ts`. These define the schema and permissions.
Look for an app id and admin token in `.env` or another env file.
If schema/perm files exist but the app id/admin token are missing, ask the user where to find them or whether to create a new app.
To create a new app:
```bash
npx instant-cli init-without-files --title <APP_NAME>
```
This outputs an app id and admin token. Store them in an env file.
If you get an error related to not being logged in tell the user to:
- Sign up for free or log in at https://instantdb.com
- Then run `npx instant-cli login` to authenticate the CLI
- Then re-run the init command
If you have an app id/admin token but no schema/perm files, pull them:
```bash
npx instant-cli pull --yes
```
## Schema changes
Edit `instant.schema.ts`, then push:
```bash
npx instant-cli push schema --yes
```
New fields = additions; missing fields = deletions.
To rename fields:
```bash
npx instant-cli push schema --rename 'posts.author:posts.creator stores.owner:stores.manager' --yes
```
## Permission changes
Edit `instant.perms.ts`, then push:
```bash
npx instant-cli push perms --yes
```
# CRITICAL Query Guidelines
CRITICAL: When using React make sure to follow the rules of hooks. Remember, you can't have hooks show up conditionally.
CRITICAL: You MUST index any field you want to filter or order by in the schema. If you do not, you will get an error when you try to filter or order by it.
Here is how ordering works:
```text
Ordering: order: { field: 'asc' | 'desc' }
Example: $: { order: { dueDate: 'asc' } }
Notes: - Field must be indexed + typed in schema
- Cannot order by nested attributes (e.g. 'owner.name')
```
CRITICAL: Here is a concise summary of the `where` operator map which defines all the filtering options you can use with InstantDB queries to narrow results based on field values, comparisons, arrays, text patterns, and logical conditions.
```text
Equality: { field: value }
Inequality: { field: { $ne: value } }
Null checks: { field: { $isNull: true | false } }
Comparison: $gt, $lt, $gte, $lte (indexed + typed fields only)
Sets: { field: { $in: [v1, v2] } }
Substring: { field: { $like: 'Get%' } } // case-sensitive
{ field: { $ilike: '%get%' } } // case-insensitive
Logic: and: [ {...}, {...} ]
or: [ {...}, {...} ]
Nested fields: 'relation.field': value
```
CRITICAL: The operator map above is the full set of `where` filters Instant
supports right now. There is no `$exists`, `$nin`, or `$regex`. And `$like` and
`$ilike` are what you use for `startsWith` / `endsWith` / `includes`.
CRITICAL: Pagination keys (`limit`, `offset`, `first`, `after`, `last`, `before`) only work on top-level namespaces. DO NOT use them on nested relations or else you will get an error.
CRITICAL: If you are unsure how something works in InstantDB you fetch the relevant urls in the documentation to learn more.
# CRITICAL Permission Guidelines
Below are some CRITICAL guidelines for writing permissions in InstantDB.
## `data.ref`
- Use `data.ref("<path.to.attr>")` for linked attributes.
- Always returns a **list**.
- Must end with an **attribute**.
**Correct**
```cel
auth.id in data.ref('post.author.id') // auth.id in list of author ids
data.ref('owner.id') == [] // there is no owner
```
**Errors**
```cel
auth.id in data.post.author.id
auth.id in data.ref('author')
data.ref('admins.id') == auth.id
auth.id == data.ref('owner.id')
data.ref('owner.id') == null
data.ref('owner.id').length > 0
```
## `auth.ref`
- Same as `data.ref` but path must start with `$user`.
- Returns a list.
**Correct**
```cel
'admin' in auth.ref('$user.role.type')
auth.ref('$user.role.type')[0] == 'admin'
```
**Errors**
```cel
auth.ref('role.type')
auth.ref('$user.role.type') == 'admin'
```
## Unsupported
```cel
newData.ref('x')
data.ref(someVar + '.members.id')
```
## $users Permissions
- Default `view` permission is `auth.id == data.id`
- Default `update` and `delete` permissions is false
- Default `create` permission is true (anyone can sign up)
- Can override `view`, `update`, and `create`
- Cannot override `delete`
- The `create` rule runs during auth signup flows (not via `transact`). Use it to restrict signups or validate `extraFields`.
- `extraFields` require an explicit `create` rule. Without one, signup is blocked to prevent unvalidated writes.
## $files Permissions
- Default permissions are all false. Override as needed to allow access.
- `data.ref` does not work for `$files` permissions.
- Use `data.path.startsWith(...)` or `data.path.endsWith(...)` to write
path-based rules.
## Field-level Permissions
Restrict access to specific fields while keeping the entity public:
```json
{
"$users": {
"allow": {
"view": "true"
},
"fields": {
"email": "auth.id == data.id"
}
}
}
```
Notes:
- Field rules override entity-level `view` for that field
- Useful for hiding sensitive data (emails, phone numbers) on public entities
# CRITICAL Storage Guidelines
CRITICAL: If an app displays images or files, use Instant Storage. Do not store
URLs as string attributes on your entities. This includes seed scripts: do not
use placeholder image URLs (e.g. picsum.photos) as string attributes to fake
file support.
Uploads auto-create `$files` entities. Link them to your data via the schema,
then query through the relationship to get URLs.
CRITICAL: You MUST include `$files` in your schema entities if you use Storage.
CRITICAL: `$files` entities can only be created via `db.storage.uploadFile`. You
cannot create `$files` via `db.transact`, and you cannot set `url` via transactions.
```tsx
entities: {
$files: i.entity({
path: i.string().unique().indexed(),
url: i.string(),
}),
posts: i.entity({
caption: i.string(),
}),
},
links: {
postImage: {
forward: { on: "posts", has: "one", label: "image" },
reverse: { on: "$files", has: "many", label: "posts" },
},
}
// Upload and link the returned file ID to your entity
const postId = id();
const { data } = await db.storage.uploadFile(`posts/${postId}/${file.name}`, file);
db.transact(
db.tx.posts[postId].update({ caption }).link({ image: data.id })
);
// Query through the relationship to get the URL
const { data } = db.useQuery({ posts: { image: {} } });
<img src={post.image.url} />
```
# CRITICAL Rooms Guidelines
CRITICAL: Hooks for presence and topics live on `db.rooms` and take the room as the first arg. The room object itself has no `usePresence` or `publishPresence` methods.
Rooms host two ephemeral primitives: presence (cursor positions, who's online) and topics (live reactions). Use them only for data that should NOT persist. Persisted data via `transact` already Related in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.