spanner-orm
A TypeScript ORM for Google Spanner & PostgreSQL, designed for Node.js and Bun.
Inspired by Drizzle ORM, spanner-orm
aims to provide a single, elegant object model for defining your schema and querying your data across both database systems.
Find it on NPM at https://www.npmjs.com/package/spanner-orm or on github at https://github.com/Flux159/spanner-orm/
Quickstart
Read the getting started doc.
Key Requirements & Design Goals
spanner-orm
is built to address the following key requirements for developers working with PostgreSQL and Google Spanner:
- Single Object Model for PostgreSQL & Spanner: Supports both PostgreSQL & Google Spanner with a single, Drizzle-inspired object model. Define your schema once and use it across both database systems.
- Cross-Dialect Migrations: Produces migrations for both PostgreSQL & Spanner. These migrations can be run via the
spanner-orm-cli migrate
command or programmatically. - Flexible Querying: Build queries with a type-safe query builder or fall back to raw SQL using the
sql
template literal tag when needed. - Dialect-Aware SQL:
- Spanner: Supports Google SQL as the dialect for Spanner.
- PostgreSQL/PGLite: Uses almost equivalent SQL for PostgreSQL & PGLite.
- This allows users to leverage PostgreSQL for non-Spanner deployments, PGLite for local development or embedded applications, and Spanner for global-scale web apps, all from a unified codebase.
- Composable Schemas (Drizzle-Inspired): Easily create and reuse schema components (e.g., common fields like
id
,timestamps
, or base entity structures likeownableResource
), promoting DRY (Don’t Repeat Yourself) principles and leading to more maintainable and understandable data models.
Why spanner-orm?
In today’s diverse application landscape, developers often need to target multiple database backends. You might start with Pglite for rapid prototyping or local-first applications, move to PostgreSQL for self-hosted or managed deployments, and eventually require the massive scalability and global consistency of Google Spanner. spanner-orm
addresses the critical challenge of managing data models and queries across these different systems without rewriting your data access layer.
Currently, the Node.js/Bun ecosystem lacks a dedicated ORM that elegantly bridges PostgreSQL and Google Spanner with a single, consistent object model and a unified migration strategy. spanner-orm
fills this gap by:
- Enabling a Single Codebase: Define your schema and write your queries once.
spanner-orm
handles the dialect-specific SQL generation. - Streamlining Development & Deployment: Simplify the transition between local development (Pglite/Postgres), testing, and production environments (Spanner or Postgres).
- Reducing Complexity: Abstract away the differences between Google SQL and PostgreSQL DDL/DML where possible, while still allowing access to dialect-specific features when needed.
- Providing a Productive API: Offer a familiar and productive Drizzle-inspired API that TypeScript developers will appreciate.
Architecture Overview
graph TD A[User Code: Schema Definitions & Queries] --> B{ORM Core}; B --> C[Abstract Schema Representation]; C --> D1[PostgreSQL SQL Generator]; C --> D2[Google Spanner SQL Generator]; B --> E[Query Builder AST]; E --> D1; E --> D2; D1 --> F1[PostgreSQL Adapter pg, pglite]; D2 --> F2[Spanner Adapter @google-cloud/spanner]; F1 --> G1[PostgreSQL/Pglite Database]; F2 --> G2[Google Spanner Database]; M[Migration Engine] --> C; M --> D1; M --> D2; M --> F1; M --> F2; style A fill:#fff,color:#000,stroke:#333,stroke-width:2px style B fill:#fff,color:#000,stroke:#333,stroke-width:2px style C fill:#lightgrey,stroke:#333,stroke-width:2px style E fill:#lightgrey,stroke:#333,stroke-width:2px style M fill:#fff,color:#000,stroke:#333,stroke-width:2px
To dive deeper, check out the Docs section.