Show HN: PGlite – in-browser WASM Postgres with pgvector and live sync (pglite.dev)
PGlite is a WASM Postgres build packaged into a TypeScript/JavaScript client library, that enables you to run Postgres in the browser, Node.js and Bun, with no need to install any other dependencies. It's 3mb Gzipped, now has support for many Postgres extensions, including pgvector, and it has a reactive "live query" API. It's also fast, with CRUD style queries executing in under 0.3 ms, and larger, multi-row select queries occurring within a fraction of a single frame.
PGlite started as an experimental project we shared on X, and the response to it was incredible, encouraging us to see how far we could take it. Since then we have been working to get it to a point where people can use it to build real things. We are incredibly excited as today, with the release of v0.2, the Supabase team has released the amazing http://postgres.new site built on top of it. Working with them to deliver both PGlite and postgres.new has been a joy.
- https://pglite.dev - PGlite website
- https://github.com/electric-sql/pglite - GitHub repo
- https://pglite.dev/docs - Docs on how to use PGlite
- https://pglite.dev/extensions - Extensions catalog
- https://pglite.dev/benchmarks - Early micro-benchmarks
- https://pglite.dev/repl - An online REPL so that you can try it in the browser
We would love you to try it out, and we will be around to answer any questions.
111 comments
[ 2.8 ms ] story [ 182 ms ] thread(blush) But to be 100% clear: the AHP-based VFS in the SQLite project is a direct port of Roy's, so all of the credit for that one truly goes to him!
It's the perfect solution to have Postgres without the need of Docker. With just `npm install`, you can have a Postgres instance on your computer. So, it's extremely easy to onboard a new developer in your team.
And, the good news, PGlite works perfectly with Next.js.
I'm using PGlite in local and development environment with Next.js Boilerplate: https://github.com/ixartz/Next-js-Boilerplate
With only one command `npm install`, you can have a full-stack application, which also includes the database (a working Postgres). And, no need to have/install external tools.
On top of it, PGlite also perfect for CI and testing.
If a shared dev DB is really what everyone wants, then at least having the scaffolding mentioned above to fix the DB state when pollution happens (it will) will help heal foot shots. In industrialized practice, what you are mentioning (a shared dev/env) is really the "QA"/pre-prod environment. Ideologically and personally (putting on down vote helmet) if you can't run the whole stack locally you're in for a world of trouble down the road.. local first, test extensively there, then promote changes.
More critical still if you have more than one "production" environment, where in different customers/clients may be at different application and db versions from one-another. This is often the case for large business and govt work. With shared environments it's often too easy to have a poorly adapted set of migration scripts.
It already is quite easy to spin up a local PG instance with Docker, but this probably makes it even simpler. Importing mock data and running migrations should just be 1 `npm run` command with a properly set up codebase.
We want to extract the core changes to Postgres that we had to make and create a "libpglite" C lib that can be linked to from any language/platform.
Support important for React Native, as it doesn't have WASM support.
Since that's still not spinning up an actual network server, that feels like it's an alternative to SQLite - you can spin up a full in-process PostgreSQL implementation, that persists to disk, as part of an existing Node.js/Bun application.
That's really interesting!
I'd love to use this from Python, via something like https://github.com/wasmerio/wasmer-python or https://github.com/bytecodealliance/wasmtime-py - has anyone run PGlite via one of those wrappers yet?
- a WASI build with a lower level api that users can wrap with a higher level api.
- a "libpglite" that can be linked to by any native language. The WASI build is likely a WASM build of this.
Most languages already have a Postgres wire protocol implementation and so wrapping a low level API that reads/emits this is relatively easy - it's what the JS side of PGlite does.
Do you have a branch for this work?
Windmill.dev is a workflow engine based fully on postgresql. This would be the missing piece to offer a local development workflow that doesn't require spinning a full pg.
For example, can you use this in/with a commercial project without releasing source? If you embed this, will you need to change your license to match pg/fb?
aside: Mostly asking out of curiosity if anyone knows already, if I actually had an immediate need, would be reviewing this of my own accord. I often dislike a lot of the simplicity behind SQLite in very similar ways as to things I don't care for with MySQL/MariaDB.
db.js:
main.py:While reading this thread, I realized that you could already access PGlite in Pyodide. Pyodide is a Wasm port of CPython. It can work with JavaScript objects through proxies.
Here is a demo. I have run the code in current Node.js 18, Deno 1, and Bun 1.
It works on my machine:Not sure about Prisma but it works with Drizzle ORM.
> You might remember an earlier WASM build[1] that was around ~30MB. The Electric team [2] have gone one step further and created a complete build of Postgres that’s under 3MB.
> Their implementation is technically interesting. Postgres is normally multi-process - each client connection is handed to a child process by the postmaster process. In WASM there’s limited/no support for process forking and threads. Fortunately, Postgres has a relatively unknown built-in “single user mode” [3] primarily designed for bootstrapping a new database and disaster recovery. Single-user mode only supports a minimal cancel REPL, so PGlite adds wire-protocol support which enables parametrised queries etc.
We have some micro-benchmarks here that have some baseline native numbers to compare to: https://pglite.dev/benchmarks
Much of the complexity with WASM in the browser actually comes down to the performance of the underlying VFS for storage. When running in-memory or using the OPFS VFSs both PGlite and the WASM SQLite builds are very performant, absolutely capable of handing the embedded use case.
[0]: https://testcontainers.com
We have different options like embedded-postgres or integreSQL, but none match the simplicity of PGLite. I hope this wish comes true soon.
https://github.com/fergusstrange/embedded-postgres/tree/mast...
https://github.com/allaboutapps/integresql
The team at Supabase have built pg-gateway (https://github.com/supabase-community/pg-gateway) that lets you connect to PGlite from any Postgres client. That's absolutely a way you could use it for CI.
One thing I would love to explore (or maybe commenting on it here will inspire someone else ;-) ) is a copy on write page level VFS for PGLite. I could imagine starting and loading a PGlite with a dataset and then instantly forking a database for each test. Not complexities with devcontainers or using Postgres template databases. Sub ms forks of a database for each test.
https://www.postgresql.org/docs/current/plpython.html
However, running `SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');` fails with `y is not a function`. Then trying to run the first query yields `null`, which is weird. I can open an issue if you want :)
The ability to replicate and subscribe to the changes, all within the browser seems incredibly powerful.
Having worked on medical software that runs a 2,000,000+ patient workload that perform refills for chemotherapy/HIV/immuno drugs, where it was common for people to trample each others work as they ran insurance, called patients etc...
We had to roll our own locking system that relied on interval functions (yay IE7) and websockets... This meant when you called the patient, someone running financial assistance would be unable to work on the same profile.
I can envision other uses for FTS or even vector search locally, since they are insanely expensive at scale.
UH, could you do:
bare_metal --> HeadlessGPU-Chrome --> PGLite with whatever orchesrtration and you have a an automatable 'browser' that can scrape/store/logic/log/be-config'd from/lookup directly to your browserDB
and maybe run a fastAPI ontop of such that you have a full stack, baremetal, headless, browserDB/fastAPI/endpoint processing doohicky?
Or does this sound dumb?
Because this is exactly what I actually need and am attempting to create - but its beyond my capabilities in any functional/elegant implementation...
https://www.browserless.io/blog/browserless-gpu-instances
https://github.com/dhamaniasad/HeadlessBrowsers
So, you can basically use this to deploy a portable fully enclosed little webapp.
Basically any little web-app that has a bunch of backend DB:
A sales USB drive that loads a page that then has the pglite of all your product stuff on there. and you can just provide custom buttons to slurp data either way.
Utils to yank a [data] from a postgress server, onto your little sneaker-DB-USB -- then carry it over and to a DB function...
A little util USB that you already have it setup such that you can curl a bunch of data directly into tables on your little headless-browser-pglite minion?
Full Kisok DB USB (SSD) upgrades.
Basically - running a pico headless postgress DB with a webUI?
--- aside:
samwillis March 2008
samstave March 2009
:-)
---
WOW:
https://i.imgur.com/6YLwEuj.png
--
Yeah this is pretty dopes.
:-)
There is a very good reason for it. EC2 is way way overpriced.
We are working on PostGIS to, which will bring the geo types to PGlite.
Just added a new section to my "Postgres Is Enough" gist:
https://gist.github.com/cpursley/c8fb81fe8a7e5df038158bdfe0f...
If they get it to a stage where other languages apart from JS can use it, it could be revolutionary. The possibilities are limitless.
Is it possible to use PGLite for that purpose in non-JS environments, like e.g. golang?
Support for other languages is high on my list, the plan is to build a "libpglite" as a native C lib and a WASI build that can run in any WASM runtime.
From my perspective, being able to pull pglite into the same golang process is preferable - faster, less IPC complexity, no risk of leaving lingering state.
Making postgres an in-process dependency is much of the appeal of pglite for me.
I already default to SQLite for new side projects with the idea that "eventually I'll migrate to Postgres if this project gets legs", so switching to PGlite feels like a no-brainer as long as it's not going to weigh my apps down or force me to upgrade out of whatever entry-level server solution I'm using is for a given project.
EDIT: Found the benchmarks here https://pglite.dev/benchmarks
Both PGlite and SQLite in the browser is incredible. The latter is a little lighter weight and more mature, but PGlite brings with it all the type support and extensions that you love with Postgres. It comes down to what works best for your project.
Also, fun etymological thing, SQLite is actually SQL-ite, as in, urbanite, not SQ-Lite, but due to rebracketing [0] and libfixing [1], now people seem to use the -lite suffix rather than the -ite one, presumably because lite actually implies something whereas ite would not, as much. It's like how helicopter is actually helic and opter, a helical wing that spins, but now people think of it as heli and copter, calling other things related to it like helipad, or quadcopter, as Wikipedia states.
[0] https://en.wikipedia.org/wiki/Rebracketing
[1] https://en.wikipedia.org/wiki/Libfix
The changes we are making with Electric is towards a more loosely coupled stack, rather than the tightly integrated stack we had before. PGlite is one possible client store for Electric sync, and fulfils the use case where you want to have a full SQL database on the client along with (potentially) the same schema on client and server.
The name is (obviously) a nod to SQLite, which goes without saying is an incredible database. We went with the small "l" in the name to add a slight differentiator and a nod towards "light", and we are a light weight Postgres.
How will it perform if I have 1TB of data?