# pgrx: Building PostgreSQL Extensions in Rust

> pgrx is a framework and cargo subcommand for writing PostgreSQL extensions in Rust. It handles schema generation, type mapping and version targeting, but it expects a working Rust and C toolchain.

**pgcentralfoundation/pgrx** — Build Postgres Extensions with Rust!

- Repository: https://github.com/pgcentralfoundation/pgrx
- Stars: 4,794 · Forks: 333
- Language: Rust
- License: NOASSERTION
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/pgcentralfoundation-pgrx

## What pgrx solves for Rust developers writing Postgres extensions

Writing a PostgreSQL extension normally means C, a Makefile wired to PGXS, and a manual mapping between SQL types and C structs. pgrx replaces that with a Rust crate and a set of procedural macros. The README describes it as a framework for developing PostgreSQL extensions in Rust that "strives to be as idiomatic and safe as possible."

The intended reader is a Rust developer who needs server-side logic inside Postgres: a user-defined function, a custom type, a trigger, or an executor hook. The README lists first-class UDF support via #[pg_extern], custom types via #[derive(PostgresType)] and #[derive(PostgresEnum)], and trigger functions via #[pg_trigger]. None of that requires writing SQL by hand, because the SQL schema is generated from the Rust source.

The project also targets teams that must ship one extension across several database versions. The README states support for Postgres 13 through Postgres 18, plus Postgres 19beta1, from the same codebase, with Rust feature gating for version-specific APIs. That multi-version story is the main reason to pick pgrx over hand-written C for a new extension.

## How the framework maps Rust code onto PostgreSQL internals

The workspace in Cargo.toml shows the architecture. pgrx-macros holds the procedural macros, pgrx-sql-entity-graph collects the SQL entities the macros emit, pgrx-pg-sys exposes generated bindings to Postgres internals, pgrx-pg-config locates and manages PostgreSQL installations, and cargo-pgrx is the command-line driver. The pgrx crate is the user-facing library that re-exports the pieces an extension author needs.

The data flow runs in one direction at build time. You annotate Rust items, the macros record them, and the SQL entity graph turns that record into a schema. The README notes the schema is generated automatically, or manually through cargo pgrx schema, and that raw SQL can be injected with extension_sql! and extension_sql_file!.

At runtime, the boundary is guarded. The README states that Rust panic! calls are translated into Postgres ERRORs that abort the transaction rather than the process, that memory management follows Rust drop semantics even through panic! and elog(ERROR), and that the #[pg_guard] macro enforces this. Datums are represented as Option<T> where T: FromDatum, so a SQL NULL arrives as Option::None instead of a raw pointer. For code that needs to go lower, the pgrx::pg_sys module gives direct unsafe access to Postgres internals, and pgrx::PgBox<T> wraps Postgres-allocated pointers.

## Installing cargo-pgrx and running a first extension

The README points to cargo-pgrx as the managed development environment. It documents subcommands for creating a project, initializing PostgreSQL installs, running the extension in psql, testing across versions, and packaging. The subcommands named in the README are cargo pgrx new, cargo pgrx init, cargo pgrx run, cargo pgrx test and cargo pgrx package, and the README points readers to the cargo-pgrx README for the rest.

The README explains that cargo pgrx init installs new PostgreSQL versions or registers existing ones. On Linux and macOS it can download and compile PostgreSQL on its own, so a local server installation is not required. On Windows it downloads precompiled PostgreSQL versions from EnterpriseDB.

On macOS there is one extra step. The README warns that Postgres 17's configure script does not detect the Homebrew install directory and may fail with "ICU library not found". The documented fix is to export the pkgconfig path before running init:

```bash
export PKG_CONFIG_PATH=/opt/homebrew/opt/icu4c/lib/pkgconfig
```

If you use Homebrew, the README also suggests installing the supporting packages it names:

```bash
brew install git icu4c pkg-config
```

Note that pgrx has no MSRV policy, so the README says it may require the latest stable Rust; the workspace Cargo.toml sets rust-version to 1.96 and edition to 2024.

## Where pgrx stops being the right tool

The system requirements are the first real constraint. You need a Rust toolchain with rustc, cargo and rustfmt, git, libclang 11 or greater for bindgen, a C compiler on Windows in the form of MSVC or Clang, and PostgreSQL's build dependencies. On Debian-like systems that means a package list including build-essential, libreadline-dev, zlib1g-dev, flex, bison, libxml2-dev, libxslt-dev and libssl-dev. A CI runner or developer laptop without those packages cannot build the extension at all.

The README is explicit that PGRX has been tested on x86_64 Linux, aarch64 Linux, aarch64 macOS and x86_64 Windows, and that other Unix systems are expected to work with possible small changes but remain untested. It also states that 32-bit is untested, that the library attempts to handle Datum conversion to and from int8 and double, and that official support is not planned without considerable ongoing technical and financial contributions.

There is a second category of mismatch. If your extension is a collection of SQL functions and PL/pgSQL procedures, pgrx adds a Rust toolchain and a bindgen dependency for no benefit. The framework earns its cost when you need custom types, SPI access, memory context control, or executor and planner hooks, all of which the README lists as advanced features. For a pure-SQL extension, plain PGXS is simpler.

One more caveat worth naming: the README does not document a rollback path for a failed cargo pgrx init or for a partially built PostgreSQL install, and the macOS troubleshooting note about Xcode moving its compiler directory implies that a full rebuild can break if the stored path disappears. The documented remedy there is to re-run cargo pgrx init.

## pgrx compared with PL/pgSQL and C extensions

The nearest alternative for server-side logic is PL/pgSQL, which ships with PostgreSQL and needs no compilation step. The difference in approach is stark: PL/pgSQL is interpreted inside the database and cannot define new base types or hook into the planner, while pgrx compiles a shared library that Postgres loads and that can register custom types, triggers and hooks. Choosing PL/pgSQL means giving up the type system and the hooks; choosing pgrx means accepting a build toolchain and a compile step for every target PostgreSQL version.

The other alternative is a C extension built against PGXS. That is the traditional path and it has no Rust dependency, but it also has no automatic schema generation, no Option<T> mapping for NULL Datums, and no panic-to-ERROR translation. With C you write the SQL install script and the type input and output functions yourself. pgrx generates the schema from the annotated Rust source and documents the NULL handling as part of the framework.

A third name that appears in search traffic around this project is PL/Rust, but the README does not describe a separate PL/Rust project, so the comparison here stops at the languages and build systems the README itself discusses.

## Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-07-30, which coincides with the v0.19.2 release. The two prior releases, v0.19.1 and v0.19.0, are dated 2026-06-23. That cadence suggests releases are still being cut, but the README does not describe a support window or a deprecation policy, so treat version support as something to confirm against the release notes rather than assume.

The workspace Cargo.toml declares license = "MIT" and carries copyright lines for ZomboDB, LLC, Technology Concepts & Design, Inc. and PgCentral Foundation, Inc. The repository's top-level LICENSE file is the authoritative text, and the GitHub metadata reports the licence as NOASSERTION, which means the platform did not classify it automatically. If you redistribute a compiled extension, read the LICENSE file yourself; this is a description of what the repository states, not legal advice.

Upgrade cost has two parts. The framework version is pinned across the workspace at 0.19.2 with exact-match dependencies between the internal crates, so upgrading means moving the whole set together. The Rust side is also pinned: edition 2024 and rust-version 1.96, with no MSRV policy in the README, so a toolchain upgrade can be forced by a pgrx release. On the database side, supporting Postgres 13 through 18 from one codebase is the selling point, but it is also the maintenance burden, because version-specific APIs have to be gated in your own code.

## Conclusion

Adopt pgrx if you already write Rust and want extension code that compiles across Postgres 13 through 18 from one codebase, with cargo pgrx test covering each version. Do not adopt it if your extension is pure SQL and PL/pgSQL, or if you cannot install libclang and PostgreSQL's build dependencies on every machine that builds the extension. Before committing, verify that the Rust toolchain on your build host satisfies the workspace rust-version of 1.96, that cargo pgrx init can reach a PostgreSQL source or binary for each version you target, and that your licence obligations match the MIT terms in the repository's Cargo.toml.

## FAQ

### What are PostgreSQL extensions and how does pgrx relate to them?

Extensions are loadable modules that add functions, types or hooks to a PostgreSQL server. pgrx is a framework for writing those extensions in Rust, generating the SQL schema from annotated Rust code instead of requiring a hand-written install script.

### Is PostgreSQL an open source database, and does pgrx depend on that?

The README treats PostgreSQL as a source or binary you can obtain, since cargo pgrx init downloads and compiles PostgreSQL versions on Linux and macOS and downloads precompiled versions from EnterpriseDB on Windows. The README does not make a licensing claim about PostgreSQL itself.

### Which PostgreSQL versions does pgrx support?

The README states support for Postgres 13 through Postgres 18, plus Postgres 19beta1. It also notes that version-specific APIs can be selected with Rust feature gating so one codebase targets all of them.

### What do I need installed before running cargo pgrx init?

A Rust toolchain with rustc, cargo and rustfmt, git, libclang 11 or greater for bindgen, and PostgreSQL's build dependencies. On macOS the README adds that Postgres 17 may fail with "ICU library not found" unless PKG_CONFIG_PATH points at the Homebrew icu4c pkgconfig directory.

### Does pgrx work on Windows and macOS?

The README says PGRX has been tested on x86_64 Linux, aarch64 Linux, aarch64 macOS and x86_64 Windows. On Windows, cargo pgrx downloads precompiled PostgreSQL versions from EnterpriseDB, and a C compiler such as MSVC or Clang is required.

## Sources

- [Issues](https://github.com/pgcentralfoundation/pgrx/issues)
- [pgcentralfoundation/pgrx on GitHub](https://github.com/pgcentralfoundation/pgrx)
- [README](https://github.com/pgcentralfoundation/pgrx/blob/develop/README.md)
- [Releases](https://github.com/pgcentralfoundation/pgrx/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pgcentralfoundation-pgrx
