PGlite

repository·main·Indexed 12 days ago

https://github.com/electric-sql/pglite

A WASM-based Postgres build packaged as a TypeScript library, allowing developers to run a full Postgres instance directly in the browser, Node.js, Bun, or Deno. Includes React integration via PGliteProvider, usePGlite, and useLiveQuery, as well as extensions such as Apache AGE, pg_ivm, pg_hashids, pg_textsearch, and pg_uuidv7.

Tokens
66.7K
Snippets
212
Records
269
Agent score
93%

What's inside PGlite

  1. Overview of PGlite

    main

    PGlite is an embeddable Postgres database that runs locally in WASM. It is designed to be lightweight, extendable, and reactive, making it suitable for running full Postgres instances directly in the browser or in environments like Node, Bun, and Deno.

    Key features include:

    • Lightweight: A complete WASM build of Postgres under 3MB Gzipped.
    • Extendable: Supports a dynamic extension loading mechanism, including popular extensions like pgvector and PostGIS.
    • Reactive: Built-in support for data loading, synchronization, and live query primitives.
  2. What is PGlite

    main

    PGlite is a Postgres build compiled to WebAssembly (WASM) and packaged as a TypeScript/JavaScript client library. It allows running Postgres directly in the browser, Node.js, Bun, or Deno without external dependencies.

    Key characteristics:

    • Lightweight: Under 3MB Gzipped.
    • No VM required: Unlike other browser-based Postgres projects, it runs Postgres directly in WASM rather than inside a Linux virtual machine.
    • Extensible: Supports various Postgres extensions, including pgvector for vector similarity search.
    • Flexible Storage: Supports ephemeral in-memory mode, IndexedDB persistence (browser), or file system persistence (Node/Bun).
  3. Use PGlite React hooks

    main

    The @electric-sql/pglite-react package provides several hooks and components to integrate PGlite with React, leveraging the live query plugin.

    Core features include:

    • Context Management: Use PGliteProvider to make a PGlite instance available to your component tree, and usePGlite to access that instance.
    • Reactive Queries: Use useLiveQuery to trigger component re-renders when query results change, or useLiveIncrementalQuery to offload diffing to PGlite for optimized reactive updates.
    • Type Safety: Use makePGliteProvider to generate typed versions of the provider and hook.
  4. Use PGlite React hooks: PGliteProvider, usePGlite, and useLiveQuery

    main

    The PGlite React integration provides several hooks and components to manage database state and reactivity:

    • PGliteProvider: A provider component used to wrap your application and make the PGlite instance available to the component tree.
    • usePGlite: A hook to access the PGlite instance within a component.
    • useLiveQuery: A hook that watches for changes in the database. It automatically re-renders components when the results of a specific query change, making it ideal for real-time UI updates.

    In a typical workflow, you create a database on page load, use usePGlite to interact with it (e.g., inserting rows), and use useLiveQuery to display the data reactively.

  5. How PGliteWorker and multi-tab proxying work

    main

    Because PGlite is single-connection only, running it in multiple browser tabs can cause conflicts. PGliteWorker solves this by using a Web Worker to run PGlite off the main thread and implementing a leader election mechanism to proxy multiple tabs to a single PGlite instance.

    How it works:

    1. Each tab starts its own worker process.
    2. The workers run an election to nominate one as the leader.
    3. Only the leader calls the init function to start the actual PGlite instance and handles all queries.
    4. If the leader tab is closed, a new election is triggered, and a new leader starts a new PGlite instance.
  6. Understand PGlite concurrency limitations

    main

    PGlite is fundamentally a single-connection database. To support multiple simultaneous connections, pglite-server uses a multiplexer that routes multiple client connections over the single underlying PGlite connection.

    Key implications:

    • Use the -m, --max-connections=N flag to allow up to N concurrent connections.
    • Because of the multiplexing, not all complex PostgreSQL use cases are guaranteed to work as they would on a full Postgres installation.
    • By default, concurrency is set to 1 (no concurrent connections).
  7. Use live query extensions for reactivity

    main

    PGlite provides extensions for reactive data handling. You can use the following methods to observe changes in real-time:

    • .live.query(): For reactive queries.
    • .live.changes(): To listen for changes.
    • .live.incrementalQuery(): For incremental updates to queries.
  8. How Live Queries work in PGlite

    main

    PGlite provides three distinct ways to handle live data updates via the live namespace, depending on your performance and complexity needs:

    1. live.query(): Best for small result sets and narrow rows. It re-runs the query and sends the full result set to a callback whenever dependencies change.
    2. live.incrementalQuery(): Best for large result sets and wide rows (e.g., feeding React state). It maintains a temporary table in Postgres to diff the new state against the previous state, sending only the changes from WASM to JS.
    3. live.changes(): A low-level API that emits raw INSERT, UPDATE, or DELETE operations. This is ideal for implementing highly efficient in-place UI updates (like DOM mutations) by mapping changes directly to the view.
  9. How PGlite works

    main
    PGlite is a WASM build of Postgres that operates in a single-process mode. Because Emscripten-compiled programs cannot fork new processes, PGlite utilizes PostgreSQL's "single user mode" to facilitate interaction within a JavaScript environment. This allows it to run without a Linux virtual machine, making it lightweight (approx. 3mb gzipped) and suitable for browsers and edge runtimes.
  10. Use PGlite extensions and the plugin API

    main
    PGlite supports standard Postgres extensions and provides a plugin API. This allows extensions to not only add database functionality but also to extend the public API of the PGlite interface itself. Developers can use these extensions to add specialized capabilities like full-text search, vector support, or specific data types to their PGlite instance.
  11. Understand PGlite performance characteristics

    main

    PGlite performance varies significantly based on the storage backend and durability settings. When evaluating PGlite for your application, consider these key findings:

    • In-Memory vs. Persistent: Like most databases, PGlite is fastest when run purely in memory. Persistent storage (like IndexedDB or OPFS) introduces latency due to I/O operations.
    • CRUD Performance: For single-row CRUD operations (inserts and updates), PGlite can be faster than wa-sqlite because PGlite utilizes the Postgres Write-Ahead Log (WAL), whereas wa-sqlite uses the SQLite rollback journal mode.
    • Durability vs. Speed: Performing an fsync or flush to underlying storage (e.g., IndexedDB in the browser) can be slow. Using relaxed durability modes can significantly accelerate queries and is often suitable for many embedded use cases where absolute immediate durability is not the highest priority.
    • Storage Backends: Performance is heavily influenced by the Virtual File System (VFS) implementation used for persistence, such as IndexedDB or OPFS (Origin Private File System).