Confect uses a spec-impl model that separates function specifications from their implementations. This architectural pattern provides type safety, clear contracts, and better code organization.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.
What is the Spec-Impl Model?
The spec-impl model divides your code into two layers:Specification (Spec)
Defines the API contract - function name, arguments, return type, and visibility
Implementation (Impl)
Contains the business logic that fulfills the contract
Why Separate Specs from Implementations?
Type Safety
The CLI generates type-safe bindings from your specs, ensuring that:- Function calls match the declared arguments
- Return types are correctly inferred
- Schema validation happens automatically
Clear Contracts
Specs serve as documentation and contracts:- Anyone can understand your API by reading specs
- Changes to specs require updating implementations
- Clients depend only on specs, not implementations
Testability
Separate specs enable:- Mocking implementations for testing
- Contract testing to verify implementations match specs
- Changing implementations without breaking tests
Code Generation
Specs enable automatic generation of:- Type-safe API objects
- Client-side hooks (React)
- Function references for scheduling
- OpenAPI documentation
Function Specifications
Creating a FunctionSpec
UseFunctionSpec to define your function’s contract:
spec/notes/create.ts
FunctionSpec Properties
Every FunctionSpec includes:name
name
Type:
stringThe function name, which must be a valid identifier (alphanumeric and underscores).args
args
Type:
Schema.Schema.AnyNoContextAn Effect schema defining the function’s input parameters.returns
returns
Type:
Schema.Schema.AnyNoContextAn Effect schema defining the function’s return type.Function Types and Visibility
Confect provides six function spec constructors:Public functions can be called from clients. Internal functions can only be called from other server-side functions.
Node Actions
For actions that need Node.js APIs:Group Specifications
Creating a GroupSpec
UseGroupSpec to organize related functions:
spec/notes.ts
Nested Groups
Groups can contain other groups:spec/admin.ts
Root Spec
Combine all groups in a root spec:spec.ts
Function Implementations
Creating a FunctionImpl
Implementations useFunctionImpl.make to connect specs to business logic:
impl/notes/create.ts
FunctionImpl.make Parameters
api
api
Type:
Api.AnyWithPropsThe generated API object from confect/_generated/api.ts.groupPath
groupPath
Type:
stringThe dot-separated path to the group containing this function.functionName
functionName
Type:
stringThe function name, matching the spec.handler
handler
Type:
(args) => Effect<R, E, Returns>The function handler that implements the business logic.Handler Requirements
Handlers must:- Accept arguments matching the spec’s
argsschema - Return an Effect that yields a value matching the
returnsschema - Handle errors appropriately (usually with
Effect.orDie)
Group Implementations
Creating a GroupImpl
Group implementations combine function implementations:impl/notes.ts
Root Implementation
Combine all group implementations:impl.ts
Always call
Impl.finalize as the last step to complete the implementation.Type Safety Benefits
Compile-Time Validation
The TypeScript compiler ensures:Runtime Validation
Effect schemas provide runtime validation:Benefits Summary
Type Safety
Compile-time and runtime type checking
Documentation
Specs serve as living documentation
Code Generation
Auto-generate client code and APIs
Testability
Mock implementations for testing
Refactoring
Safe refactoring with type checking
Separation
Clear separation of concerns
Example: Complete Function
Here’s a complete example showing spec and implementation:spec/notes/update.ts
impl/notes/update.ts
Next Steps
Services
Learn about Effect services available in Confect
Project Structure
See how to organize specs and implementations