The graphile/ directory contains all PostGraphile v5 plugins, organized as individual packages in the pnpm workspace. The central entry point is graphile-settings, which exports ConstructivePreset — a single preset that wires everything together.
ConstructivePreset
├── MinimalPreset (no Node/Relay — keeps id as id)
├── InflektPreset (custom inflection via inflekt library)
├── ConflictDetectorPreset (warns about naming conflicts between schemas)
├── InflectorLoggerPreset (debug logging for inflector calls)
├── NoUniqueLookupPreset (primary key only lookups)
├── ConnectionFilterPreset (v5-native connection filter with relation filters)
├── EnableAllFilterColumnsPreset (allow filtering on all columns)
├── ManyToManyOptInPreset (many-to-many via @behavior +manyToMany)
├── MetaSchemaPreset (_meta query for schema introspection)
├── UnifiedSearchPreset (tsvector + BM25 + pg_trgm + pgvector)
├── GraphilePostgisPreset (PostGIS types + spatial filter operators)
├── UploadPreset (S3/MinIO file uploads)
├── SqlExpressionValidatorPreset (validates @sqlExpression columns)
└── PgTypeMappingsPreset (custom type → GraphQL scalar mappings)
The main configuration package. Exports ConstructivePreset and all sub-presets. This is the only package most consumers need to import.
- Combines all plugins into a single composable preset
- Disables
conditionargument (all filtering viawhere) - Configures connection filter options (logical operators, arrays, computed columns)
- Aggregates satellite plugin operator factories
import { ConstructivePreset } from 'graphile-settings/presets';V5-native connection filter plugin. Adds the where argument to connections with per-table filter types (e.g. UserFilter) and per-scalar operator types (e.g. StringFilter, IntFilter).
Key features:
- Standard operators:
equalTo,notEqualTo,isNull,in,notIn,lessThan,greaterThan - Pattern matching:
includes,startsWith,endsWith,like+ case-insensitive variants - Type-specific operators: JSONB, hstore, inet, array, range
- Logical operators:
and,or,not - Relation filters: filter by related table fields (forward and backward)
- Declarative operator API: satellite plugins register custom operators via
connectionFilterOperatorFactories
import { ConnectionFilterPreset } from 'graphile-connection-filter';Unified search plugin with adapter pattern. Replaces the previous separate plugins (graphile-tsvector, graphile-bm25, graphile-trgm, graphile-pgvector) with a single plugin that supports all four search algorithms.
Each algorithm is a ~50-line adapter implementing the SearchAdapter interface:
- tsvector — PostgreSQL full-text search via
ts_rank - BM25 —
pg_textsearchextension scoring - pg_trgm — Trigram fuzzy matching via
similarity() - pgvector — Vector similarity search (cosine, L2, inner product)
Generated GraphQL fields per adapter:
- Score fields:
{column}{Algorithm}{Metric}(e.g.bodyBm25Score,titleTrgmSimilarity) - Composite score:
searchScore— normalized 0..1 aggregating all active search signals - OrderBy enums:
{COLUMN}_{ALGORITHM}_{METRIC}_ASC/DESC+SEARCH_SCORE_ASC/DESC - Filter fields:
{algorithm}{Column}on connection filter input types (e.g.fullTextBody,trgmTitle)
Zero config — auto-discovers columns and indexes per adapter.
import { UnifiedSearchPreset } from 'graphile-search';PostGIS support. Generates GraphQL types for geometry/geography columns including GeoJSON scalar types, dimension-aware interfaces, and spatial filter operators.
Features:
- GeoJSON scalar type for input/output
- Concrete types for all geometry subtypes (Point, LineString, Polygon, etc.)
- Geography-aware field naming (longitude/latitude instead of x/y)
- Spatial filter operators via
createPostgisOperatorFactory() - Graceful degradation when PostGIS is not installed
import { GraphilePostgisPreset, createPostgisOperatorFactory } from 'graphile-postgis';Collection of smaller plugins that don't warrant their own package:
| Plugin/Preset | Description |
|---|---|
MinimalPreset |
PostGraphile without Node/Relay features |
InflektPreset |
Custom inflection using inflekt library |
ConflictDetectorPreset |
Warns about naming conflicts between schemas |
InflectorLoggerPreset |
Debug logging (enable with INFLECTOR_LOG=1) |
EnableAllFilterColumnsPreset |
Allow filtering on all columns (not just indexed) |
ManyToManyOptInPreset |
Many-to-many via @behavior +manyToMany smart tag |
NoUniqueLookupPreset |
Disable non-primary-key unique lookups |
MetaSchemaPreset |
_meta query for database schema introspection |
PgTypeMappingsPreset |
Custom PostgreSQL type → GraphQL scalar mappings |
PostGraphile instance LRU cache with automatic cleanup when PostgreSQL pools are disposed. Integrates with pg-cache for pool management.
import { graphileCache } from 'graphile-cache';Lightweight GraphQL SDL builder. Build schemas directly from a database or fetch from a running endpoint — no server dependencies.
import { buildSchemaSDL } from 'graphile-schema';
import { fetchEndpointSchemaSDL } from 'graphile-schema';GraphQL query execution utilities. Supports pgSettings, role-based access control, and custom request context.
GraphileQuery— Full-featured with roles, settings, and request contextGraphileQuerySimple— Minimal wrapper for simple execution
import { GraphileQuery } from 'graphile-query';Testing utilities for PostGraphile. Builds on pgsql-test to provide isolated, seeded, role-aware test databases with GraphQL helpers.
- Per-test rollback via savepoints
- RLS-aware context injection (
setContext) - GraphQL
query()function with snapshot support - Seed support for SQL, JSON, CSV, Constructive, or Sqitch
For batteries-included testing with all Constructive plugins, use @constructive-io/graphql-test instead.
import { getConnections, seed } from 'graphile-test';SQL expression validation for PostGraphile v5. Validates SQL expressions against a configurable allowlist of functions and schemas.
import { SqlExpressionValidatorPreset } from 'graphile-sql-expression-validator';File upload support for PostGraphile v5. Handles S3/MinIO uploads for image, upload, and attachment domain columns.
import { UploadPreset } from 'graphile-upload-plugin';The following directories contain npm-installed upstream packages from the v4 era. They have no package.json or src/ — only dist/ and node_modules/. They are consumed as dependencies but not maintained as source:
| Directory | Status |
|---|---|
graphile-i18n |
Upstream v4 package |
graphile-many-to-many |
Upstream @graphile-contrib/pg-many-to-many |
graphile-meta-schema |
Folded into graphile-misc-plugins as MetaSchemaPreset |
graphile-pg-type-mappings |
Folded into graphile-misc-plugins as PgTypeMappingsPreset |
graphile-plugin-connection-filter |
Replaced by v5-native graphile-connection-filter |
graphile-plugin-fulltext-filter |
Replaced by graphile-search unified plugin |
graphile-simple-inflector |
Replaced by InflektPreset in graphile-misc-plugins |
Satellite plugins (search, PostGIS, trgm) register custom filter operators via the declarative operator factory API on graphile-connection-filter. Each factory is a function that receives the Graphile build object and returns operator registrations:
// In constructive-preset.ts
schema: {
connectionFilterOperatorFactories: [
createMatchesOperatorFactory('FullText', 'english'), // tsvector matches
createTrgmOperatorFactories(), // similarTo, wordSimilarTo
createPostgisOperatorFactory(), // spatial operators
],
}This ensures graphile-config's array replacement behavior is handled correctly — all factories are collected at the top-level preset.
-
conditionis disabled. All filtering lives underwhere(the v5-native filter argument).PgConditionArgumentPluginandPgConditionCustomFieldsPluginare explicitly disabled in the preset. -
All columns are filterable.
EnableAllFilterColumnsPresetoverrides PostGraphile's default of only filtering indexed columns. Index optimization is left to DBAs. -
Many-to-many is opt-in. No many-to-many fields are generated unless the junction table has
@behavior +manyToManysmart tag. This prevents API bloat. -
Relation filters are enabled.
connectionFilterRelations: trueallows filtering across foreign key relationships (forward and backward). -
Search is unified. One plugin (
graphile-search) handles all four search algorithms via adapters instead of four separate plugins. -
Computed fields are excluded from codegen defaults. The codegen's
getSelectableScalarFields()helper uses the TypeRegistry to filter out plugin-added computed fields (search scores, hash UUIDs) from default CLI select objects.
This monorepo contains several packages that depend on the Graphile v5 release candidate (RC) ecosystem. The Graphile v5 RC packages are tightly coupled -- all packages in the ecosystem must be at matching RC versions to work correctly.
Graphile v5 RC packages declare peer dependencies on each other. When a new RC is released, the minimum required versions of those peer deps often bump together. For example, graphile-build-pg@5.0.0-rc.5 requires @dataplan/pg@^1.0.0-rc.5 and tamedevil@^0.1.0-rc.4, whereas the earlier rc.3 only required rc.3 versions of those peers.
If our packages use loose caret ranges (e.g., ^5.0.0-rc.3), the package manager may resolve to the latest RC (e.g., rc.5 or rc.7), which introduces new peer dependency requirements that nothing in our tree satisfies.
All Graphile RC dependencies are pinned to exact versions (no ^ or ~ prefix). This ensures:
- Every package in the monorepo uses the same RC version set
- No version drift when new RCs are published
- All peer dependency requirements are explicitly satisfied
- Deterministic installs across environments
| Package | Pinned Version |
|---|---|
grafast |
1.0.0-rc.7 |
grafserv |
1.0.0-rc.6 |
graphile-build |
5.0.0-rc.4 |
graphile-build-pg |
5.0.0-rc.5 |
graphile-config |
1.0.0-rc.5 |
graphile-utils |
5.0.0-rc.6 |
pg-sql2 |
5.0.0-rc.4 |
postgraphile |
5.0.0-rc.7 |
@dataplan/json |
1.0.0-rc.5 |
@dataplan/pg |
1.0.0-rc.5 |
tamedevil |
0.1.0-rc.4 |
@graphile-contrib/pg-many-to-many |
2.0.0-rc.1 |
- graphile-settings -- Core settings/configuration for PostGraphile v5 (most deps, including the transitive peer deps
tamedevil,@dataplan/pg,@dataplan/json,grafserv) - graphile-schema -- Builds GraphQL SDL from PostgreSQL using PostGraphile v5
- graphile-query -- Executes GraphQL queries against PostGraphile v5 schemas
- graphile-search -- Unified search plugin (tsvector + BM25 + pg_trgm + pgvector via adapter pattern)
- graphile-connection-filter -- v5-native connection filter plugin (scalar, logical, array, relation, computed column filters)
- graphile-postgis -- PostGIS types, GeoJSON scalars, spatial filter operators
- graphile-cache -- LRU cache with PostGraphile v5 integration
- graphile-test -- PostGraphile v5 testing utilities
- graphile-sql-expression-validator -- SQL expression validation for safe default expressions
- graphile-upload-plugin -- File upload support (S3/MinIO)
- graphile-misc-plugins -- Inflection, conflict detection, meta-schema, type mappings
- @constructive-io/graphql-server -- GraphQL server with PostGraphile v5
- @constructive-io/graphql-test -- GraphQL testing with all plugins loaded
- @constructive-io/graphql-query -- GraphQL query builder
- @constructive-io/graphql-explorer -- GraphQL Explorer UI
Important: Having different versions of grafast (or other singleton graphile packages) installed in the same workspace causes runtime errors like Preset attempted to register version 'X' of 'grafast', but version 'Y' is already registered. This is why all packages must use the same pinned versions.
When upgrading to a new Graphile RC set:
- Check the latest RC versions on npm for all packages listed in the table above
- Verify peer dependency compatibility by running
npm view <package>@<version> peerDependenciesfor each package - Update all packages in this table simultaneously -- do not upgrade one without the others
- Update every
graphile/*/package.jsonandgraphql/*/package.jsonthat references these packages - Run
pnpm installto update the lockfile - Run
pnpm buildto verify no type errors - Run tests to verify nothing broke
- Update the version table in this document
| Test Suite | Command | What It Covers |
|---|---|---|
graphile-connection-filter |
pnpm --filter graphile-connection-filter test |
51 filter operator tests |
graphile-search |
pnpm --filter graphile-search test |
Unified search adapter tests |
graphile-settings |
pnpm --filter graphile-settings test |
Preset integration + metadata tests |
graphile-test |
pnpm --filter graphile-test test |
Test framework self-tests |
graphql/test |
pnpm --filter @constructive-io/graphql-test test |
Full ConstructivePreset integration (84 tests) |
graphql/server-test |
pnpm --filter @constructive-io/graphql-server-test test |
Server-level integration + search mega queries |
All tests run in CI against constructiveio/postgres-plus:18 (includes PostGIS, pg_trgm, pgvector, pg_textsearch).