Wrappers: a Rust framework for building Postgres foreign data wrappers
Postgres Foreign Data Wrapper development framework in Rust.
At a glance
- What is it?
- Wrappers is a Supabase project that gives Rust developers a scaffold for Postgres foreign data wrappers, so a REST API, a document store or a SaaS product can be queried as if it were a table. It ships about thirty wrappers built on pgrx, split between native Rust ones and WebAssembly ones, with a read and modify matrix in the readme.
- Who is it for?
- Wrappers suits a developer who wants to query a third party service from Postgres SQL without writing an extension in C, and the FDW catalogue is broad enough that some of those integrations may already be built. It does not suit a team that needs a foreign table to behave like a first class table with full transactional semantics, since most of the wrappers are read only, and the ones that support modification vary in how much they support.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two FDW families: native Rust and WebAssembly
Wrappers is described as a development framework for Postgres Foreign Data Wrappers written in Rust, with the goal of making FDW development easier while keeping what Rust brings: high performance, strong types and safety.
The framework is also a collection of FDWs built by Supabase, and the readme lists them with a read and modify column for each. The split by directory is the interesting part, because it is a real architectural fork rather than a packaging detail.
The native Rust wrappers live under wrappers/src/fdw/. They cover AWS Cognito, Airtable, Apache Iceberg, Auth0, BigQuery, Clickhouse, DuckDB, DynamoDB, Firebase, Logflare, MongoDB, MySQL, Redis, AWS S3, AWS S3 Vectors, Microsoft SQL Server and Stripe. The HelloWorld wrapper sits in the same tree as a demo FDW showing how to develop a basic one.
The WebAssembly wrappers live under wasm-wrappers/fdw/. They cover Calendly, Cal.com, Clerk, Cloudflare D1, HubSpot, Infura blockchain data, Langfuse, Notion, OpenAPI for any 3.0 or later REST API, Orb, Paddle, Slack and Snowflake.
That OpenAPI entry is the one to look at first if you are evaluating, because it is generic rather than vendor specific. A wrapper for any REST API that conforms to OpenAPI 3.0 or later covers a very large share of the cases you would otherwise write by hand.
The Cargo workspace confirms the shape, listing the two framework crates supabase-wrappers and supabase-wrappers-macros, the wrappers crate, and one member per WebAssembly FDW. The default members are the three framework crates, so a plain cargo build covers the framework and the native wrappers rather than the WebAssembly set.
The workspace also uses edition 2024 and pins rust-version 1.97.1, which is a specific toolchain requirement rather than a floor.
The read and modify matrix is where the honest limits are
The FDW table carries two columns beyond the description, and they are the most informative thing on the page.
Read support is universal across the catalogue apart from the HelloWorld demo, which is a development example. Modify support is much narrower.
The wrappers that support both read and modify are BigQuery, Clickhouse, Cloudflare D1, DynamoDB, MongoDB, MySQL, Paddle, S3 Vectors, Snowflake and Stripe. Everything else is read only, including all of the REST API style targets and the data stores that expose their own write semantics.
The distinction makes sense once you look at what each backend is. A MySQL or MongoDB FDW can offer real modification because the underlying system has a well defined write API. An Airtable or Notion FDW that reads a REST API could in principle write back, but the wrapper authors have chosen not to, and the reason is usually that the API write path does not map cleanly onto SQL UPDATE semantics.
That is worth understanding before you build a pipeline on top of a wrapper. A read only foreign table is fine for joining local Postgres data against a SaaS dataset, and fine for reporting. It is not fine for a workflow where the local transaction writes back to the remote system, because there is no path for the write.
The framework features list says it supports both sync and async backends such as RDBMS, RESTful APIs and flat files, and supports rich data types. Where, ORDER BY and LIMIT pushdown are supported, which is the difference between a wrapper that reads a whole table into memory and one that lets the remote side do the filtering.
The framework is built on top of pgrx, which provides higher level interfaces without hiding the lower level C APIs. That phrase matters for anyone who knows how Postgres extensions normally work: pgrx lets you write Rust instead of C, but the C interface is still reachable, so there is an escape hatch when a wrapper needs to do something the safe layer does not cover.
Installation is a pgrx install with a feature flag
Wrappers is a pgrx extension, so the installation path goes through pgrx. The readme points at the pgrx system requirements and then gives the shape of the command.
cargo pgrx install --pg-config [path_to_pg_config] --features stripe_fdwThe feature flag is the important part. Each FDW is a Cargo feature, so you name the ones you want at install time rather than shipping all thirty into your Postgres installation. The example names stripe_fdw.
There is also a crates.io badge and a docs.rs badge for the supabase-wrappers crate, so the framework itself is usable as a library dependency, not only as an installed extension. The developer documentation is on docs.rs at supabase_wrappers, and the usage documentation is on fdw.dev.
The warning section in the readme covers a failure mode that is worth reading before you deploy anything. Restoring a logical backup of a database with a materialized view using a foreign table can fail. The remedy is stated as either not using foreign tables in materialized views, or using them in databases with physical backups enabled.
That is a real operational constraint rather than a theoretical one. A materialized view over a foreign table captures whatever the remote API returned at refresh time, and a logical restore replays the view definition and its contents in an order that may not match the remote system's current state. Whether that matters depends on whether you treat the remote data as authoritative, which is usually the case for the analytics style workload these wrappers suit.
The repository layout backs up the documentation story. There is a docs/ directory with an mkdocs.yaml, a CONTRIBUTING.md, a CLAUDE.md and an .agents/ directory, plus a test workflow badge for test_wrappers.yml.
Where Wrappers is the wrong tool
Three cases, and the first is the most common disappointment.
Foreign tables are not real tables. A foreign table lives in Postgres and has a schema, but the data lives in the remote system, and the transaction semantics are limited in ways that surprise people. A local UPDATE inside a transaction that touches a foreign table cannot be rolled back in the remote system, and a local rollback does not undo a remote write that already happened. For a reporting workload that is fine. For a system where correctness of the data depends on the two being in step, it is not, and the read only wrappers do not even let you try.
The second case is performance at scale. The FDW approach means Postgres plans a query against a foreign table and the wrapper turns it into remote calls. The WHERE, ORDER BY and LIMIT pushdown support mitigates that, but a wrapper that cannot push down a particular filter will pull the relevant relation and filter locally, which is a table scan over a network call. For a small dataset that is fine. For a large one it is the wrong shape, and the right answer is to land the data locally and query it there.
The third case is the API that does not fit OpenAPI. The generic OpenAPI wrapper covers services that publish a spec, but many APIs are awkward: they need custom auth flows, they paginate in ways the wrapper does not model, or their resources do not map to rows. Then you are back to writing a wrapper, and you should ask whether a Rust extension is the right vehicle for that specific integration rather than assuming the framework removes the work.
The alternative approaches differ in what they cost. PostgREST and Hasura give you a REST or GraphQL layer over Postgres in the other direction, so they do not solve remote reads. The postgres_fdw and file_fdw extensions that ship with Postgres cover the RDBMS case without Rust. And a scheduled ETL job that syncs a remote dataset into local tables gives you correct transaction semantics and local query performance at the cost of freshness, which for reporting is often the better trade.
Editorial conclusion
Wrappers suits a developer who wants to query a third party service from Postgres SQL without writing an extension in C, and the FDW catalogue is broad enough that some of those integrations may already be built. It does not suit a team that needs a foreign table to behave like a first class table with full transactional semantics, since most of the wrappers are read only, and the ones that support modification vary in how much they support. Before adopting it, read the warning about foreign tables in materialized views, check whether the specific wrapper you need supports what you want to do, and confirm your Postgres and Rust versions match the pgrx requirements the project points you at.
Frequently asked questions
What is the Wrappers project from Supabase?
It is a development framework for Postgres Foreign Data Wrappers written in Rust, intended to make FDW development easier while keeping Rust's performance, strong typing and safety. It is built on top of pgrx and provides higher level interfaces without hiding the lower level C APIs.
How do I install the Wrappers FDW extension?
Wrappers is a pgrx extension, so you follow the pgrx installation steps for its system requirements and then run cargo pgrx install --pg-config [path_to_pg_config] with the features you want, for example --features stripe_fdw. The framework crate supabase-wrappers is also published on crates.io and documented on docs.rs.
Which Wrappers foreign data wrappers support writing data back?
The read and modify matrix in the readme marks BigQuery, Clickhouse, Cloudflare D1, DynamoDB, MongoDB, MySQL, Paddle, S3 Vectors, Snowflake and Stripe as supporting both read and modify. The rest of the catalogue, including the WebAssembly API wrappers, are read only.
What is the limitation with foreign tables in materialized views in Wrappers?
The documentation warns that restoring a logical backup of a database with a materialized view using a foreign table can fail, and advises either not using foreign tables in materialized views or using them in databases with physical backups enabled.
Which Wrappers FDW covers arbitrary REST APIs?
The OpenAPI wrapper, a Wasm FDW for any OpenAPI 3.0 or later REST API, is the generic entry in the catalogue. The other WebAssembly wrappers cover specific services such as Calendly, Cal.com, Clerk, HubSpot, Notion, Slack, Snowflake, Paddle, Orb, Langfuse and Infura blockchain data.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/supabase-wrappers)Was this useful?