Configuration Reference
Every configurable knob is set via defineConfig in baeta.ts. This page is the reference for the minimum setup, see Getting started → Configuration.
Resolvers
Resolvers in Baeta are chained method calls on the generated module: declare them once per field with .resolve() / .map() / .key(), then collect them with $fields. This page walks through a User type and its Query together.
Scalars
GraphQL ships with Int, Float, String, Boolean, and ID. For anything else like dates, UUIDs, or money, declare a custom scalar in your schema and register a resolver that handles serialization, parsing, and AST validation.
Custom Types
src/modules/types.ts is the single place to override the TypeScript types Baeta hands to your resolvers: source types per GraphQL type, scalar mappings, the context shape, and the info type.
Middlewares
Middlewares wrap a resolver so you can run logic before, after, or instead of it. Chain $use(fn) calls onto a field, follow with .resolve(), and pass the result into $fields.
Context
The context object is shared across every resolver and middleware in a request. Use it for per-request state like auth, loaders, transport-specific helpers, or anything resolvers shouldn't reach for themselves.
Context Store
A context store is a typed, request-scoped slot on the context that loads its value lazily and memoizes the result for the rest of the request. It's the idiomatic way to share per-request data (the current user, the active organization, a tenant config) between resolvers without padding the Context type with optional fields or paying for queries you may not use.
Application
createApplication is where everything comes together: a list of modules in, a runnable GraphQLSchema out. From there you hand the schema to the server of your choice.
Error handling
@baeta/errors ships ready-made GraphQLError subclasses for the cases you hit on almost every API: unauthenticated, forbidden, bad input, internal failure. Each one tags extensions.code so clients can branch on the failure mode without parsing strings.
Subscriptions
Baeta typechecks subscription resolvers the same way it typechecks queries and mutations. The transport (PubSub) is yours to pick: Yoga's built-in PubSub for single-instance deployments, TypedPubSub over Redis for multi-instance, or @baeta/subscriptions-cloudflare for Durable-Object-backed Workers.
Interfaces & Unions
Interfaces and unions are GraphQL's abstract types. An interface defines a set of fields that a concrete Object type (or another interface) must include to implement it. A union has no fields of its own; it only lists which Object types a field may return.
Custom Directives
A custom directive is a schema-transformer function paired with a directive @name declaration. Register the transformer with $directive on a module and Baeta applies it to the compiled schema. For input/argument transforms specifically, see Input Directives; the API there is friendlier than hand-rolling a schema transformer.
Input Directives
GraphQL doesn't include a built-in way to mutate input values via directives — the spec only covers schema-side transforms. createInputDirective from @baeta/core fills the gap with a small API for reading and writing input values before they reach the resolver.
Typed PubSub
TypedPubSub is a thin wrapper around graphql-subscriptions that types channel names and payloads. The publish and subscribe methods accept only channels declared in your event map; typos and payload mismatches fail at compile time.
Environment
Baeta provides a type-safe environment variable parser that validates and transforms environment variables at runtime.