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.
Confect projects follow a structured directory layout that separates concerns and makes your codebase easy to navigate. This guide explains the recommended project structure and where different types of files belong.
Directory Overview
A typical Confect project has two main directories:
confect/ Your Confect specifications, implementations, and schemas
convex/ Generated Convex functions and traditional Convex files
confect/ Directory
The confect/ directory contains all your Confect-specific code:
confect/
├── _generated/ # Generated by Confect CLI (do not edit)
│ ├── api.ts
│ ├── refs.ts
│ ├── services.ts
│ └── registeredFunctions.ts
├── spec/ # Function specifications
│ ├── users.ts
│ └── notes/
│ ├── create.ts
│ └── list.ts
├── impl/ # Function implementations
│ ├── users.ts
│ └── notes/
│ ├── create.ts
│ └── list.ts
├── tables/ # Database table definitions
│ ├── Users.ts
│ ├── Notes.ts
│ └── Tags.ts
├── spec.ts # Root specification
├── impl.ts # Root implementation
└── schema.ts # Database schema
_generated/
Never edit files in _generated/ directly. These files are automatically generated by the Confect CLI.
Generated files include:
api.ts - Type-safe API object for calling functions
refs.ts - Type-safe function references for scheduling and internal calls
services.ts - Effect service types (DatabaseReader, DatabaseWriter, etc.)
registeredFunctions.ts - Registry of all functions for Convex
spec/
Function specifications define your API contract:
import { FunctionSpec , GenericId } from "@confect/core" ;
import { Schema } from "effect" ;
export const create = FunctionSpec . publicMutation ({
name: "create" ,
args: Schema . Struct ({
text: Schema . String ,
}),
returns: GenericId . GenericId ( "notes" ),
});
Organize specs into subdirectories that mirror your domain structure.
impl/
Function implementations contain your business logic:
import { FunctionImpl } from "@confect/server" ;
import { Effect } from "effect" ;
import api from "../../_generated/api" ;
import { DatabaseWriter } from "../../_generated/services" ;
export const create = FunctionImpl . make (
api ,
"notes" ,
"create" ,
({ text }) =>
Effect . gen ( function* () {
const writer = yield * DatabaseWriter ;
return yield * writer . table ( "notes" ). insert ({ text });
}). pipe ( Effect . orDie ),
);
Implementation files should mirror the structure of your spec files for easy navigation.
tables/
Table definitions use Effect schemas to define your database structure:
import { Table } from "@confect/server" ;
import { Schema } from "effect" ;
export const Notes = Table . make ({
name: "notes" ,
Fields: Schema . Struct ({
text: Schema . String ,
userId: Schema . optionalWith ( Schema . String , { exact: true }),
}),
Indexes: Table . indexes ({
by_creation_time: [ "_creationTime" ],
by_user: [ "userId" ],
}),
});
Root Files
spec.ts
The root specification file combines all your function specs:
import { Spec } from "@confect/core" ;
import { notes } from "./spec/notes" ;
import { users } from "./spec/users" ;
export default Spec . make ()
. add ( notes )
. add ( users );
impl.ts
The root implementation file combines all your function implementations:
import { Impl } from "@confect/server" ;
import { Layer } from "effect" ;
import api from "./_generated/api" ;
import { notes } from "./impl/notes" ;
import { users } from "./impl/users" ;
export default Impl . make ( api ). pipe (
Layer . provide ( Layer . mergeAll ( notes , users )),
Impl . finalize ,
) ;
schema.ts
The database schema file combines all your table definitions:
import { DatabaseSchema } from "@confect/server" ;
import { Notes } from "./tables/Notes" ;
import { Users } from "./tables/Users" ;
import { Tags } from "./tables/Tags" ;
export default DatabaseSchema . make ()
. addTable ( Notes )
. addTable ( Users )
. addTable ( Tags );
convex/ Directory
The convex/ directory contains Convex-specific files:
convex/
├── _generated/ # Generated by Convex CLI (do not edit)
│ ├── api.d.ts
│ ├── dataModel.d.ts
│ └── server.d.ts
├── schema.ts # Convex schema (generated from Confect)
├── http.ts # HTTP endpoints (optional)
└── crons.ts # Cron jobs (optional)
schema.ts
This file is generated by the Confect CLI from your confect/schema.ts:
import { ConvexSchemaToDataModel } from "@confect/server/SchemaToValidator" ;
import { defineSchema } from "convex/server" ;
import confectSchema from "../confect/schema" ;
export default defineSchema (
ConvexSchemaToDataModel ( confectSchema ),
) ;
While this file is generated, it’s safe to add additional Convex-specific configuration here if needed.
HTTP Endpoints
For HTTP endpoints, you can use Effect’s HTTP API modules:
import { httpAction } from "convex/server" ;
import { HttpApi } from "@confect/server" ;
import httpApi from "../confect/http" ;
export default HttpApi . toConvexHttpRouter ( httpAction , httpApi ) ;
Grouping Functions
Confect supports hierarchical function organization using GroupSpec:
import { GroupSpec } from "@confect/core" ;
import { create } from "./notes/create" ;
import { list } from "./notes/list" ;
import { update } from "./notes/update" ;
import { delete_ } from "./notes/delete" ;
export const notes = GroupSpec . make ( "notes" )
. addFunction ( create )
. addFunction ( list )
. addFunction ( update )
. addFunction ( delete_ );
This creates a logical grouping: notes.create, notes.list, etc.
Nested Groups
You can nest groups for deeper organization:
import { GroupSpec } from "@confect/core" ;
import { users } from "./admin/users" ;
import { settings } from "./admin/settings" ;
export const admin = GroupSpec . make ( "admin" )
. addGroup ( users )
. addGroup ( settings );
This creates paths like: admin.users.list, admin.settings.update
File Naming Conventions
PascalCase Table definitions: Users.ts, Notes.ts
camelCase Functions and groups: create.ts, users.ts
lowercase Directories: spec/, impl/, tables/
Reserved Root files: spec.ts, impl.ts, schema.ts
Example Project
Here’s a complete example of a small project structure:
my-app/
├── confect/
│ ├── _generated/
│ │ ├── api.ts
│ │ ├── refs.ts
│ │ └── services.ts
│ ├── spec/
│ │ ├── notes.ts
│ │ └── users.ts
│ ├── impl/
│ │ ├── notes.ts
│ │ └── users.ts
│ ├── tables/
│ │ ├── Notes.ts
│ │ └── Users.ts
│ ├── spec.ts
│ ├── impl.ts
│ └── schema.ts
├── convex/
│ ├── _generated/
│ ├── schema.ts
│ └── http.ts
├── src/
│ └── App.tsx
└── package.json
Best Practices
Keep specs and implementations in sync
Ensure that for every spec file, there’s a corresponding impl file with the same structure.
Use descriptive group names
Group names should reflect your domain: users, posts, comments, not generic names like data or api.
Keep related specs, implementations, and tables close together in the directory structure.
Don't edit generated files
Never manually edit files in _generated/ directories. They will be overwritten by the CLI.
Next Steps
Spec-Impl Model Understand how specs and implementations work together
Services Learn about Effect services in Confect