Documentation Index Fetch the complete documentation index at: https://mintlify.com/rjdellecese/confect/llms.txt
Use this file to discover all available pages before exploring further.
The @confect/server package provides server-side APIs for implementing queries, mutations, and actions with full type safety and Effect integration.
Overview
Database Operations Type-safe database reads and writes with schema validation
Context Services Access to QueryCtx, MutationCtx, and ActionCtx
Function Runners Execute queries, mutations, and actions programmatically
Effect Integration Full integration with Effect for composable error handling
DatabaseReader
The DatabaseReader service provides type-safe read access to your database.
Accessing DatabaseReader
packages/server/src/DatabaseReader.ts
import { DatabaseReader } from "@confect/server" ;
import { Effect } from "effect" ;
import type { databaseSchema } from "../schema" ;
type DB = DatabaseReader < typeof databaseSchema >;
const listUsers = Effect . gen ( function* () {
const db = yield * DatabaseReader < typeof databaseSchema >();
const users = yield * db
. table ( "users" )
. collect ();
return users ;
});
Query Operations
table Access a specific table for querying
collect Collect all documents matching the query
first Get the first document matching the query
unique Get a unique document by index
Examples
// Get all documents
const allUsers = yield * db
. table ( "users" )
. collect ();
// Filter with where clause
const activeUsers = yield * db
. table ( "users" )
. filter (( q ) => q . eq ( q . field ( "status" ), "active" ))
. collect ();
// Get first matching document
const firstUser = yield * db
. table ( "users" )
. filter (( q ) => q . eq ( q . field ( "email" ), "user@example.com" ))
. first ();
// Get by unique index
const userByEmail = yield * db
. table ( "users" )
. getByIndex ( "by_email" , "user@example.com" );
// Order results
const sortedPosts = yield * db
. table ( "posts" )
. order ( "desc" )
. collect ();
// Pagination
const paginatedUsers = yield * db
. table ( "users" )
. paginate ({ numItems: 20 , cursor: null });
Get Document by ID
import type { Id } from "convex/values" ;
const getUser = ( userId : Id < "users" >) =>
Effect . gen ( function* () {
const db = yield * DatabaseReader < typeof databaseSchema >();
const user = yield * db
. table ( "users" )
. get ( userId );
if ( user === null ) {
return yield * Effect . fail ( new Error ( "User not found" ));
}
return user ;
});
DatabaseWriter
The DatabaseWriter service provides type-safe write access to your database.
Accessing DatabaseWriter
packages/server/src/DatabaseWriter.ts
import { DatabaseWriter } from "@confect/server" ;
import { Effect } from "effect" ;
import type { databaseSchema } from "../schema" ;
const createUser = Effect . gen ( function* () {
const db = yield * DatabaseWriter < typeof databaseSchema >();
const userId = yield * db . table ( "users" ). insert ({
name: "Alice" ,
email: "alice@example.com" ,
status: "active"
});
return userId ;
});
Write Operations
insert Insert a new document and return its ID
patch Update specific fields of a document
replace Replace entire document (except system fields)
delete Delete a document by ID
Examples
import type { Id } from "convex/values" ;
// Insert a document
const userId = yield * db . table ( "users" ). insert ({
name: "Bob" ,
email: "bob@example.com" ,
role: "user"
});
// Patch (partial update)
yield * db . table ( "users" ). patch ( userId , {
status: "verified"
});
// Replace (full update)
yield * db . table ( "users" ). replace ( userId , {
name: "Bob Smith" ,
email: "bob.smith@example.com" ,
role: "admin" ,
status: "active"
});
// Delete
yield * db . table ( "users" ). delete ( userId );
Complex Write Example
const createPostWithTags = (
title : string ,
content : string ,
tags : string []
) =>
Effect . gen ( function* () {
const db = yield * DatabaseWriter < typeof databaseSchema >();
const auth = yield * Auth ();
const identity = yield * auth . getUserIdentity ();
if ( ! identity ) {
return yield * Effect . fail ( new Error ( "Not authenticated" ));
}
// Create the post
const postId = yield * db . table ( "posts" ). insert ({
title ,
content ,
authorId: identity . subject ,
createdAt: Date . now ()
});
// Create tag associations
for ( const tag of tags ) {
yield * db . table ( "postTags" ). insert ({
postId ,
tag
});
}
return postId ;
});
Context Services
Confect provides type-safe context services for each function type.
QueryCtx
packages/server/src/QueryCtx.ts
import { QueryCtx } from "@confect/server" ;
import type { GenericDataModel } from "convex/server" ;
type DataModel = GenericDataModel ;
const useQueryContext = Effect . gen ( function* () {
const ctx = yield * QueryCtx < DataModel >();
// Access query context methods
const db = ctx . db ;
const auth = ctx . auth ;
});
MutationCtx
packages/server/src/MutationCtx.ts
import { MutationCtx } from "@confect/server" ;
import type { GenericDataModel } from "convex/server" ;
type DataModel = GenericDataModel ;
const useMutationContext = Effect . gen ( function* () {
const ctx = yield * MutationCtx < DataModel >();
// Access mutation context methods
const db = ctx . db ;
const auth = ctx . auth ;
const storage = ctx . storage ;
const scheduler = ctx . scheduler ;
});
ActionCtx
packages/server/src/ActionCtx.ts
import { ActionCtx } from "@confect/server" ;
import type { GenericDataModel } from "convex/server" ;
type DataModel = GenericDataModel ;
const useActionContext = Effect . gen ( function* () {
const ctx = yield * ActionCtx < DataModel >();
// Access action context methods
const runQuery = ctx . runQuery ;
const runMutation = ctx . runMutation ;
const auth = ctx . auth ;
const storage = ctx . storage ;
const scheduler = ctx . scheduler ;
});
Function Runners
Run functions programmatically from within other functions.
QueryRunner
packages/server/src/QueryRunner.ts
import { QueryRunner } from "@confect/server" ;
import { refs } from "../confect/_generated/refs" ;
const composedQuery = Effect . gen ( function* () {
const runQuery = yield * QueryRunner ;
// Run another query
const users = yield * runQuery (
refs . internal . users . list ,
{}
);
return users . map ( u => u . name );
});
MutationRunner
packages/server/src/MutationRunner.ts
import { MutationRunner } from "@confect/server" ;
import { refs } from "../confect/_generated/refs" ;
const composedMutation = Effect . gen ( function* () {
const runMutation = yield * MutationRunner ;
// Run another mutation
const userId = yield * runMutation (
refs . internal . users . create ,
{
name: "Charlie" ,
email: "charlie@example.com"
}
);
return userId ;
});
ActionRunner
packages/server/src/ActionRunner.ts
import { ActionRunner } from "@confect/server" ;
import { refs } from "../confect/_generated/refs" ;
const composedAction = Effect . gen ( function* () {
const runAction = yield * ActionRunner ;
// Run another action
const result = yield * runAction (
refs . internal . notifications . send ,
{
userId: "user123" ,
message: "Hello!"
}
);
return result ;
});
Additional Services
Auth
Authentication service for accessing user identity.
packages/server/src/Auth.ts
import { Auth } from "@confect/server" ;
const checkAuth = Effect . gen ( function* () {
const auth = yield * Auth ();
const identity = yield * auth . getUserIdentity ();
if ( ! identity ) {
return yield * Effect . fail ( new Error ( "Not authenticated" ));
}
return {
userId: identity . subject ,
email: identity . email ,
name: identity . name
};
});
Storage
File storage operations.
packages/server/src/Storage.ts
import { Storage } from "@confect/server" ;
const uploadFile = ( content : ArrayBuffer ) =>
Effect . gen ( function* () {
const storage = yield * Storage ;
const storageId = yield * Effect . promise (() =>
storage . store ( new Blob ([ content ]))
);
return storageId ;
});
const getFileUrl = ( storageId : Id < "_storage" >) =>
Effect . gen ( function* () {
const storage = yield * Storage ;
const url = yield * Effect . promise (() =>
storage . getUrl ( storageId )
);
return url ;
});
Scheduler
Schedule functions to run later.
packages/server/src/Scheduler.ts
import { Scheduler } from "@confect/server" ;
import { refs } from "../confect/_generated/refs" ;
const scheduleTask = Effect . gen ( function* () {
const scheduler = yield * Scheduler ;
// Schedule after 1 hour
yield * Effect . promise (() =>
scheduler . runAfter (
3600000 , // 1 hour in ms
refs . internal . tasks . processData ,
{ taskId: "task123" }
)
);
// Schedule at specific time
const targetTime = new Date ( "2026-03-08T12:00:00Z" );
yield * Effect . promise (() =>
scheduler . runAt (
targetTime ,
refs . internal . tasks . sendReminder ,
{ userId: "user123" }
)
);
});
DatabaseSchema
Define your database schema with type safety.
Creating a Schema
packages/server/src/DatabaseSchema.ts
import { DatabaseSchema , Table } from "@confect/server" ;
import { Schema } from "effect" ;
import { defineTable } from "convex/server" ;
import { v } from "convex/values" ;
const usersTable = Table . make (
"users" ,
defineTable ({
name: v . string (),
email: v . string (),
role: v . union (
v . literal ( "user" ),
v . literal ( "admin" )
),
status: v . string ()
})
. index ( "by_email" , [ "email" ])
. index ( "by_role" , [ "role" ]),
{
name: Schema . String ,
email: Schema . String ,
role: Schema . Literal ( "user" , "admin" ),
status: Schema . String
}
);
const postsTable = Table . make (
"posts" ,
defineTable ({
title: v . string (),
content: v . string (),
authorId: v . string (),
createdAt: v . number ()
})
. index ( "by_author" , [ "authorId" ])
. searchIndex ( "search_title" , {
searchField: "title"
}),
{
title: Schema . String ,
content: Schema . String ,
authorId: Schema . String ,
createdAt: Schema . Number
}
);
const databaseSchema = DatabaseSchema . make ()
. addTable ( usersTable )
. addTable ( postsTable );
export default databaseSchema ;
import type { DatabaseSchema } from "@confect/server" ;
type Tables = DatabaseSchema . Tables < typeof databaseSchema >;
type TableNames = DatabaseSchema . TableNames < typeof databaseSchema >;
HTTP API
Define HTTP routes for your backend.
packages/server/src/HttpApi.ts
import { HttpApi } from "@confect/server" ;
import { httpRouter } from "convex/server" ;
const http = httpRouter ();
http . route ({
path: "/api/health" ,
method: "GET" ,
handler : async () => {
return new Response (
JSON . stringify ({ status: "ok" }),
{
status: 200 ,
headers: { "Content-Type" : "application/json" }
}
);
}
});
http . route ({
path: "/api/webhook" ,
method: "POST" ,
handler : async ( request ) => {
const data = await request . json ();
// Process webhook
return new Response ( null , { status: 200 });
}
});
export default http ;
Next Steps
Core API Learn about core types and specifications
React Hooks Use Confect in your React app
Testing Test your server functions
CLI Manage your project with the CLI