{"id":30896504,"url":"https://github.com/endel/zodgres","last_synced_at":"2026-03-02T17:04:50.811Z","repository":{"id":310723830,"uuid":"1035640506","full_name":"endel/zodgres","owner":"endel","description":"Postgres.js + Zod","archived":false,"fork":false,"pushed_at":"2025-08-25T14:23:21.000Z","size":332,"stargazers_count":13,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-06T06:07:50.744Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://zodgres.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/endel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-10T20:33:56.000Z","updated_at":"2025-09-03T16:34:54.000Z","dependencies_parsed_at":"2025-08-19T22:09:10.858Z","dependency_job_id":null,"html_url":"https://github.com/endel/zodgres","commit_stats":null,"previous_names":["endel/zodgres"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/endel/zodgres","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2Fzodgres","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2Fzodgres/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2Fzodgres/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2Fzodgres/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/endel","download_url":"https://codeload.github.com/endel/zodgres/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2Fzodgres/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274231202,"owners_count":25245673,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-08T23:08:32.130Z","updated_at":"2026-03-02T17:04:50.759Z","avatar_url":"https://github.com/endel.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cdiv align=\"center\"\u003e\n\u003cimg width=\"440\" height=\"180\" alt=\"Zod + Postgres\" src=\"https://github.com/endel/zodgres/blob/main/zodgres.png?raw=1\"\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003c/div\u003e\n\nTypeScript-first database collections with static type inference and automatic migrations. Built on top of [Postgres.js](https://github.com/porsager/postgres) and [Zod](https://github.com/colinhacks/zod/).\n\n- 🔒 **Type-safe** - Full TypeScript support with Zod schema validation\n- 🚀 **Simple API** - Collection-based interface for common database operations\n- 📦 **Flexible** - Works with Postgres or in-memory PGLite for testing\n- ⚡ **SQL Templates** - Use template literals for complex queries\n- 🔄 **Auto-migration** - Automatic table creation from Zod schemas\n\n\u003e **⚠️ Disclaimer**: PGLite support is currently not working. See [issue #1](https://github.com/endel/zodgres/issues/1) for more details.\n\n## Installation\n\n```bash\nnpm install zodgres\n```\n\n## Quick Start\n\n```typescript\nimport { connect, z } from 'zodgres';\n\n// Set-up database connection\nconst db = connect('postgres://user:password@localhost:5432/mydb');\n\n// Define a collection with Zod schema\nconst users = db.collection('users', {\n  id: z.number().optional(), // auto-incrementing\n  name: z.string().max(100),\n  age: z.number().min(0).max(100).optional(),\n});\n\n// Open the connection and run collection migrations\nawait db.open();\n\n// Create records\nconst user = await users.create({ name: 'John Doe', age: 30 });\n// Result: { id: 1, name: 'John Doe', age: 30 }\n\n// Create multiple records\nconst newUsers = await users.create([\n  { name: 'Alice' },\n  { name: 'Bob', age: 25 }\n]);\n// Result: [{ id: 2, name: 'Alice' }, { id: 3, name: 'Bob', age: 25 }]\n\n// Query records\nconst allUsers = await users.select(); // or users.select`*`\nconst adults = await users.select`* WHERE age \u003e= ${18}`;\n\n// Close connection\nawait db.close();\n```\n\n## API Overview\n\n### Database Connection\n\n#### `connect(uri, options?)`\n\nConnect to a Postgres database or use in-memory storage for testing:\n\n```typescript\n// Connect to Postgres\nconst db = connect('postgres://user:password@localhost:5432/mydb');\n\n// Use in-memory database (great for testing)\nconst testDb = connect(':memory:');\n```\n\n\u003e **Important:** After defining all your collections, you must call `await db.open()` to establish the database connection and run any necessary migrations. This ensures your database schema matches your collection definitions before performing any operations.\n\n\n### Collection Definition\n\n#### `db.collection(name, schema, params?)`\n\nCreate a type-safe collection with Zod schema validation:\n\n```typescript\nconst items = db.collection('items', {\n  id: z.number().optional(),          // auto-incrementing primary key\n  name: z.string().max(100),          // required string with max length\n  price: z.number().positive(),       // required positive number\n  description: z.string().optional(), // optional string\n});\n```\n\n### Collection Operations\n\n#### `create(data)` / `create(data[])`\n\nCreate single or multiple records:\n\n```typescript\n// Single record\nconst item = await items.create({\n  name: 'Widget',\n  price: 19.99\n});\n\n// Multiple records\nconst newItems = await items.create([\n  { name: 'Gadget', price: 29.99 },\n  { name: 'Tool', price: 39.99, description: 'Useful tool' }\n]);\n```\n\n#### `select()` / `select``query` `\n\nQuery records using SQL template literals:\n\n```typescript\n// Select all records\nconst all = await items.select();\n\n// Select with conditions\nconst expensive = await items.select`* WHERE price \u003e ${25}`;\nconst byName = await items.select`* WHERE name = ${'Widget'}`;\n\n// Complex queries\nconst recent = await items.select`\n  name, price\n  WHERE created_at \u003e ${new Date('2024-01-01')}\n  ORDER BY price DESC\n  LIMIT ${10}\n`;\n```\n\n## Testing\n\nThe library supports in-memory databases for fast testing:\n\n\u003e ⚠️ PGLite support is currently not working. See [issue #1](https://github.com/endel/zodgres/issues/1) for more details.\n\n```typescript\nimport { connect, z } from 'zodgres';\n\ndescribe('My tests', () =\u003e {\n  let db;\n\n  before(async () =\u003e {\n    db = await connect(':memory:').open(); // Uses PGLite\n  });\n\n  after(async () =\u003e {\n    await db.close();\n  });\n\n  it('should create users', async () =\u003e {\n    const users = db.collection('users', {\n      id: z.number().optional(),\n      name: z.string(),\n    });\n\n    const user = await users.create({ name: 'Test User' });\n    assert.deepStrictEqual(user, { id: 1, name: 'Test User' });\n  });\n});\n```\n\n## Schema Validation\n\nAll data is validated using Zod schemas before database operations:\n\n```typescript\nconst products = db.collection('products', {\n  id: z.number().optional(),\n  name: z.string().min(1).max(100),\n  price: z.number().positive(),\n  category: z.enum(['electronics', 'books', 'clothing']),\n  tags: z.array(z.string()).optional(),\n  metadata: z.record(z.any()).optional(),\n});\n\n// This will throw validation error\nawait products.create({\n  name: '', // too short\n  price: -10, // not positive\n  category: 'invalid' // not in enum\n});\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fendel%2Fzodgres","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fendel%2Fzodgres","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fendel%2Fzodgres/lists"}