File: createCollection.md | Updated: 11/15/2025
Search...
+ K
Auto
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Maintainers Partners Support Learn StatsBETA Discord Merch Blog GitHub Ethos Brand Guide
Documentation
Framework
React
Version
Latest
Search...
+ K
Menu
Getting Started
Guides
Collections
Frameworks
Community
API Reference
Framework
React
Version
Latest
Menu
Getting Started
Guides
Collections
Frameworks
Community
API Reference
On this page
Copy Markdown
Function: createCollection()
============================
Call Signature
--------------
ts
function createCollection<T, TKey, TUtils>(options): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & NonSingleResult;
function createCollection<T, TKey, TUtils>(options): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & NonSingleResult;
Defined in: packages/db/src/collection/index.ts:131
Creates a new Collection instance with the given configuration
T extends StandardSchemaV1<unknown, unknown>
The schema type if a schema is provided, otherwise the type of items in the collection
TKey extends string | number = string | number
The type of the key for the collection
TUtils extends UtilsRecord = UtilsRecord
The utilities record type
CollectionConfig <InferSchemaOutput <T>, TKey, T, TUtils> & object & NonSingleResult
Collection options with optional utilities
Collection <InferSchemaOutput <T>, TKey, TUtils, T, InferSchemaInput <T>> & NonSingleResult
A new Collection with utilities exposed both at top level and under .utils
ts
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
ts
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
ts
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
ts
function createCollection<T, TKey, TUtils>(options): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & SingleResult;
function createCollection<T, TKey, TUtils>(options): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & SingleResult;
Defined in: packages/db/src/collection/index.ts:144
Creates a new Collection instance with the given configuration
T extends StandardSchemaV1<unknown, unknown>
The schema type if a schema is provided, otherwise the type of items in the collection
TKey extends string | number = string | number
The type of the key for the collection
TUtils extends UtilsRecord = UtilsRecord
The utilities record type
CollectionConfig <InferSchemaOutput <T>, TKey, T, TUtils> & object & SingleResult
Collection options with optional utilities
Collection <InferSchemaOutput <T>, TKey, TUtils, T, InferSchemaInput <T>> & SingleResult
A new Collection with utilities exposed both at top level and under .utils
ts
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
ts
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
ts
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
ts
function createCollection<T, TKey, TUtils>(options): Collection<T, TKey, TUtils, never, T> & NonSingleResult;
function createCollection<T, TKey, TUtils>(options): Collection<T, TKey, TUtils, never, T> & NonSingleResult;
Defined in: packages/db/src/collection/index.ts:158
Creates a new Collection instance with the given configuration
T extends object
The schema type if a schema is provided, otherwise the type of items in the collection
TKey extends string | number = string | number
The type of the key for the collection
TUtils extends UtilsRecord = UtilsRecord
The utilities record type
CollectionConfig <T, TKey, never, TUtils> & object & NonSingleResult
Collection options with optional utilities
Collection <T, TKey, TUtils, never, T> & NonSingleResult
A new Collection with utilities exposed both at top level and under .utils
ts
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
ts
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
ts
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
ts
function createCollection<T, TKey, TUtils>(options): Collection<T, TKey, TUtils, never, T> & SingleResult;
function createCollection<T, TKey, TUtils>(options): Collection<T, TKey, TUtils, never, T> & SingleResult;
Defined in: packages/db/src/collection/index.ts:171
Creates a new Collection instance with the given configuration
T extends object
The schema type if a schema is provided, otherwise the type of items in the collection
TKey extends string | number = string | number
The type of the key for the collection
TUtils extends UtilsRecord = UtilsRecord
The utilities record type
CollectionConfig <T, TKey, never, TUtils> & object & SingleResult
Collection options with optional utilities
Collection <T, TKey, TUtils, never, T> & SingleResult
A new Collection with utilities exposed both at top level and under .utils
ts
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
// Pattern 1: With operation handlers (direct collection calls)
const todos = createCollection({
id: "todos",
getKey: (todo) => todo.id,
schema,
onInsert: async ({ transaction, collection }) => {
// Send to API
await api.createTodo(transaction.mutations[0].modified)
},
onUpdate: async ({ transaction, collection }) => {
await api.updateTodo(transaction.mutations[0].modified)
},
onDelete: async ({ transaction, collection }) => {
await api.deleteTodo(transaction.mutations[0].key)
},
sync: { sync: () => {} }
})
// Direct usage (handlers manage transactions)
const tx = todos.insert({ id: "1", text: "Buy milk", completed: false })
await tx.isPersisted.promise
ts
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
// Pattern 2: Manual transaction management
const todos = createCollection({
getKey: (todo) => todo.id,
schema: todoSchema,
sync: { sync: () => {} }
})
// Explicit transaction usage
const tx = createTransaction({
mutationFn: async ({ transaction }) => {
// Handle all mutations in transaction
await api.saveChanges(transaction.mutations)
}
})
tx.mutate(() => {
todos.insert({ id: "1", text: "Buy milk" })
todos.update("2", draft => { draft.completed = true })
})
await tx.isPersisted.promise
ts
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
// Using schema for type inference (preferred as it also gives you client side validation)
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean()
})
const todos = createCollection({
schema: todoSchema,
getKey: (todo) => todo.id,
sync: { sync: () => {} }
})
