Requirements
PostGraphile is packaged as a Node.js module, you can install it with any Node
package manager such as npm or yarn (depending on your preference) — users
tend to have fewer issues with yarn, so we recommend it (but if you use yarn
"berry", we recommend using nodeLinker: node-modules in your .yarnrc.yml).
We recommend using the latest LTS version of Node.js and PostgreSQL, but we have
limited support for older versions, so long as they are still LTS. Using newer
released versions should generally work fine (we don't recommend using with
alpha/beta versions though), but if there's any issues let us know in an issue.
PostGraphile supports Node.js 22+ and recommends Node.js 24+ for the best
experience (including built-in type stripping for .ts files).
Your PostgreSQL database
These aren't exactly "requirements", but they will impact your PostGraphile experience.
- Use primary keys: if you don't have primary keys on your tables then they
won't get the
nodeIdglobally unique identifier interface. Further if you don't have unique constraints then you won't be able to use the automatic update/delete mutations (since they need a way to identify the row to update/delete). - Use foreign keys: we infer relations between tables using foreign key constraints; if you don't use these constraints then we won't know there's a relationship between the tables. There are plugins to get around this (using smart comments) but it's highly recommended that you use PostgreSQL's built in relations support.
- Don't use column-based
SELECT grants: column-based grants work well for
INSERTandUPDATE(especially when combined withPgRBACPlugin!), but they don't make sense forDELETEand they cause issues when used withSELECT. You cannotSELECT *which makes your life harder, and rules out some of our possible optimization strategies. Computed columns (where we pass the entire record to the function) typically have issues with column-basedSELECTgrants. It's recommended that you instead split your tables on permission boundaries and use one-to-one relations to join them together again — this also makes writing your RBAC/RLS policies simpler. If you want to omit a column entirely then you can give it the@behavior -*smart tag. - Function restrictions: we have pretty good support for PostgreSQL functions, but there's some common function restrictions you should check out.
- Use unique constraints rather than unique indexes when appropriate:
we use unique constraints to create mutations such as
updateUserByUsername; note that "PostgreSQL automatically creates a unique index when a unique constraint or primary key is defined for a table." -- PG docs - Use the defaults for formatting output; we only run tests for the
defaults so if you change them you may face issues. (You may change
intervalstylesince we have specific handling code for that.) - Use UTF8 encoding: GraphQL operates over the UTF8 character set, using different encodings may impact your ability to store/retrieve certain values.
On top of this, standard PostgreSQL best practices apply: use indexes carefully for performance, use constraints and triggers to ensure your data is valid and consistent, etc.
Unique indexes
PostGraphile treats unique constraints as data guarantees, but unique indexes as optimisations that you might remove later; this is why it only creates accessors and mutations from unique constraints by default.
If your tooling does not understand this subtlety and can only create unique indexes, you might want to opt in to treating unique indexes as if they were constraints by using a plugin. We've included an example plugin to achieve this below.
Click to view plugin to treat unique indexes as constraints.
Only use this if you are confident that all of your unique indexes are true constraints.
// WARNING: this plugin was reworked from a GitHub issue and is currently untested
// Ref: https://github.com/graphile/crystal/issues/2054
export const PgUniqueIndexesPlugin: GraphileConfig.Plugin = {
name: "PgUniqueIndexesPlugin",
version: "0.1.0",
description: "Treats unique indexes as if they were unique constraints.",
gather: {
hooks: {
async pgTables_PgResourceOptions(_, event) {
const { pgClass, resourceOptions } = event;
if (pgClass.relkind !== "r") return;
if (resourceOptions.parameters) return;
if (!resourceOptions.uniques) return;
const mutableUniques = [...resourceOptions.uniques];
resourceOptions.uniques = mutableUniques;
const indexes = pgClass.getIndexes().filter((idx) => idx.indisunique);
const existingUniqueAttributeSets = new Set(
mutableUniques.map((u) => JSON.stringify(u.attributes)),
);
for (const idx of indexes) {
const attributes = idx.getKeys();
if (!attributes.every((a) => a != null)) continue;
const attributeNames = attributes.map((a) => a.attname);
const hash = JSON.stringify(attributeNames);
if (existingUniqueAttributeSets.has(hash)) continue;
existingUniqueAttributeSets.add(hash);
const { description, tags = Object.create(null) } =
idx.getIndexClass()?.getTagsAndDescription() ?? {};
mutableUniques.push({
isPrimary: idx.indisprimary ?? false,
attributes: attributeNames,
description,
extensions: { tags },
});
}
},
},
},
};
Node.js: use the active LTS
PostGraphile supports Node.js 22+ but recommends Node.js 24+ where possible. We only support LTS versions of Node.js. Once a Node.js version reaches end-of-life we no longer support it, and any future patch release may be incompatible with it. We do not see this as a violation of semver — once a Node.js version reaches EOL no reasonable user should use it, and as such a change to drop support for it is not a breaking change for reasonable users.
TypeScript v5.0.0+ (optional)
We recommend that you use TypeScript for the best experience — auto-completion, inline documentation, etc.
You do not need to use TypeScript to use PostGraphile, but if you do then you
must use a version from TypeScript v5.0.0 upward and configure it to support
the exports property in package.json, you can do so by adding this to your
TypeScript configuration:
"moduleResolution": "node16", // Or "nodenext"
Instead of configuring TypeScript manually, we recommend that you use the appropriate TSConfig Base for your Node.js version.
{
"extends": "@tsconfig/node24/tsconfig.json"
}
If you want to use type stripping (which limits the syntax you can use,
but means Node can run your TS files directly), then also add the
@tsconfig/node-ts preset and make sure you're running Node 24+ and TypeScript
v5.8.0+. To use the LTS version of Node along with type stripping:
{
"extends": [
"@tsconfig/node-lts/tsconfig.json",
"@tsconfig/node-ts/tsconfig.json"
]
}
Our adherence to semver does not cover types — we may make breaking changes to TypeScript types in patch-level updates. The reason for this is that TypeScript itself is ever-changing, and the libraries we depend on often make breaking type changes, forcing us to do so too. Further, improvements to types are generally a good thing for developer experience, even if it might mean you have to spend a couple minutes after updating to address any issues.
However, we try and keep the TypeScript types as stable as possible, only making breaking changes when their benefits outweigh the costs (as determined by our maintainer), and we do our best to detail in the release notes how to deal with these changes (if any action is necessary).
Not using TypeScript?
You do not need to use TypeScript to use PostGraphile, but without it you will
find editors such as VSCode will highlight your import paths with error
notifications. To stop this, you can add the following to jsconfig.json:
{
"compilerOptions": {
"moduleResolution": "node16"
}
}
PostgreSQL: use latest
For best results we recommend you use the latest stable release of PostgreSQL that we officially support, however PostGraphile should run well on any earlier version of PostgreSQL that has not yet reached end-of life.
Once a PostgreSQL version reaches end-of-life we no longer support it, and any future patch release may be incompatible with it. We do not see this as a violation of semver — once a PostgreSQL version reaches EOL no reasonable user should use it, and as such a change to drop support for it is not a breaking change for reasonable users.
Currently versions 12 and 13 are EOL according to the PostgreSQL project. They work with PostGraphile and are exercised in CI at time of writing; however, they are not officially supported and may be removed from CI if they hold us back.
PG 12 [unsupported - EOL Nov 2024]
Works well; but not officially supported and support may be dropped in a patch release.
PG 13 [unsupported - EOL Nov 2025]
Works well; but not officially supported and support may be dropped in a patch release.
PG 14 [officially supported]
Works well.
PG 15 [officially supported]
Works well.
PG 16 [officially supported]
Works well.
PG 17 [officially supported]
Works well.
PG 18 [officially supported]
Works well.
Operating system
PostGraphile is developed on *nix operating systems like GNU/Linux and macOS. As far as we know it works on Windows, but since no-one in the core team uses Windows for development our Windows support is "best effort" rather than "officially supported" — please file an issue if you have problems, but we may be asking for your help to fix/test them!