Extensions
Extensions are linked into the pgmem build statically. CREATE EXTENSION works for every name below without installing anything.
Bundled
Section titled “Bundled”| Group | Extensions |
|---|---|
| Procedural language | plpgsql |
| Types and operators | citext, hstore, ltree, cube, seg, isn, intarray, lo, earthdistance |
| Text search and fuzzy matching | pg_trgm, fuzzystrmatch, unaccent, dict_int, dict_xsyn |
| Indexes | btree_gist, btree_gin, bloom |
| Vectors | vector (pgvector 0.8.6) |
| Cryptography and IDs | pgcrypto, uuid-ossp |
| Table functions and sampling | tablefunc, tsm_system_rows, tsm_system_time |
| Inspection and statistics | pg_stat_statements, pgstattuple, pageinspect, pg_buffercache, pg_freespacemap, pg_visibility, amcheck, pg_prewarm |
| Loadable module | auto_explain (LOAD 'auto_explain', not CREATE EXTENSION) |
Snowball stemming dictionaries and every encoding conversion are linked in as well.
pgcrypto without OpenSSL. pgcrypto’s OpenSSL and zlib layers are replaced by calls into Go’s crypto, math/big and compress packages. Digests, AES, Blowfish, DES, 3DES and CAST5, OpenPGP encryption with RSA or ElGamal keys, and OpenPGP compression all work, and messages made by GnuPG decrypt. fips_mode() is always false, and bzip2-compressed OpenPGP packets are unsupported, as upstream.
Not bundled
Section titled “Not bundled”Extensions outside that list fail with module is not linked into this pgmem build. Some are out of scope by design:
- extensions with their own background worker, such as
pg_cronandpg_partman’s worker (the postmaster could start them now; none is bundled yet); - outbound network access, such as
dblinkandpostgres_fdw; - other language runtimes, such as
plv8,plperlandplpython; - PostGIS, for its size and its dependency chain.
Use a container for tests that need them.
How an extension is added
Section titled “How an extension is added”The selection rule is simple: extensions that most managed services (Amazon RDS, Google Cloud SQL) and PGlite offer, ORM-facing ones first. The same steps build a custom pgmem with an extension the release does not ship.
With an agent
Section titled “With an agent”The repository carries a skill, add-pgmem-extension, that walks a coding agent through the whole procedure. In a pgmem checkout, Claude Code finds it as /add-pgmem-extension on its own. For another agent, or a fork, install it from the repository:
npx skills add shibukawa/pgmem --skill add-pgmem-extensionThen ask in plain words, naming the contrib module:
Add pg_surgery to pgmem.
The skill points the agent at a driver script, skills/add-pgmem-extension/add-extension.sh, and the agent does this:
add-extension.sh statuslists what is bundled and which upstream contrib modules still have regression tests, downloading the pinned PostgreSQL source intowasm/out/srcwhen it is not there.add-extension.sh add <name>appends the name toCONTRIB_MODULESinwasm/build.sh, copiescontrib/<name>/sql,expectedanddatatotestdata/regress/<name>, and registers the Makefile’sREGRESSlist inregress_test.go. It reports psql commands the regression runner cannot emulate, upstreamREGRESS_OPTSto mirror, and host libraries the module links.- The agent edits the extension lists by hand:
README.md,.knowledge/policy/bundled-extensions.mdand this page in both languages. add-extension.sh buildrunswasm/build.sh(Emscripten through Devbox:postgres.wasmandinternal/assets/share.tar.gz) andwasm/gen-aot.sh(the wasm2go fork:internal/aot/pgaot). This takes a few minutes and is the only step that needs the wasm toolchain.add-extension.sh smoke <name>starts pgmem, runsCREATE EXTENSIONand lists the objects it installed;add-extension.sh test <name>replays the vendored regression files and diffs the transcript against upstream’s expected output.- One commit per extension,
pgmem: bundle <name>.
An extension outside the PostgreSQL tree follows pgvector: a lock file with repository, version and checksum, and its own compile step in build.sh. The skill describes that pattern but the driver does not automate it.
By hand
Section titled “By hand”The same steps without the driver:
- Append the contrib name to
CONTRIB_MODULESinwasm/build.sh. Its control, SQL and data files are copied into the share tree that ships with the module. - For an extension outside the PostgreSQL tree, add a lock file with repository, version and checksum, and a compile step in
build.sh, as for pgvector. - Rebuild with
./wasm/build.shand regenerate the Go with./wasm/gen-aot.sh. - Vendor the extension’s upstream regression files into
testdata/regress/<name>and list them inregress_test.go, so the suite replays them against pgmem. - Commit one extension per commit.
Each module is compiled with its _PG_init and magic-block symbols renamed, and a generated table lets a static replacement for dlopen find them. That is what makes CREATE EXTENSION work without dynamic linking.