{"id":48406571,"url":"https://github.com/omnidotdev/typespec-drizzle","last_synced_at":"2026-04-06T03:37:22.305Z","repository":{"id":330411869,"uuid":"1098561721","full_name":"omnidotdev/typespec-drizzle","owner":"omnidotdev","description":"🌧️ Typespec Drizzle emitter","archived":false,"fork":false,"pushed_at":"2026-03-31T08:38:38.000Z","size":118,"stargazers_count":11,"open_issues_count":10,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-06T03:37:19.096Z","etag":null,"topics":["codegen","database","drizzle","emitter","foss","library","omni","open-source","orm","postgres","schema","typescript","typespec"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/omnidotdev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["omnidotdev"],"custom":["https://omni.dev"]}},"created_at":"2025-11-17T21:17:06.000Z","updated_at":"2026-03-24T13:38:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/omnidotdev/typespec-drizzle","commit_stats":null,"previous_names":["omnidotdev/typespec-drizzle"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/omnidotdev/typespec-drizzle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omnidotdev%2Ftypespec-drizzle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omnidotdev%2Ftypespec-drizzle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omnidotdev%2Ftypespec-drizzle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omnidotdev%2Ftypespec-drizzle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/omnidotdev","download_url":"https://codeload.github.com/omnidotdev/typespec-drizzle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omnidotdev%2Ftypespec-drizzle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31458838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"online","status_checked_at":"2026-04-06T02:00:07.287Z","response_time":112,"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":["codegen","database","drizzle","emitter","foss","library","omni","open-source","orm","postgres","schema","typescript","typespec"],"created_at":"2026-04-06T03:37:21.616Z","updated_at":"2026-04-06T03:37:22.300Z","avatar_url":"https://github.com/omnidotdev.png","language":"TypeScript","funding_links":["https://github.com/sponsors/omnidotdev","https://omni.dev"],"categories":[],"sub_categories":[],"readme":"# TypeSpec Drizzle Emitter\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"/assets/logo.png\" width=\"150\" /\u003e\n\n[Join Omni community on Discord](https://discord.gg/omnidotdev)\n\n[![version](https://img.shields.io/github/v/release/omnidotdev/typespec-drizzle?sort=semver)](https://github.com/omnidotdev/typespec-drizzle/releases)\n[![build](https://img.shields.io/github/actions/workflow/status/omnidotdev/typespec-drizzle/release.yml)](https://github.com/omnidotdev/typespec-drizzle/actions/workflows/release.yml)\n[![license: Apache 2.0](https://img.shields.io/github/license/omnidotdev/typespec-drizzle)](https://github.com/omnidotdev/typespec-drizzle/blob/master/LICENSE.md)\n\n\u003c/div\u003e\n\nA [TypeSpec](https://typespec.io) emitter that generates [Drizzle ORM](https://orm.drizzle.team) schema definitions and types from TypeSpec specifications. Learn about TypeSpec emitters [here](https://typespec.io/docs/extending-typespec/emitters-basics).\n\n\u003e [!IMPORTANT]\n\u003e **Project Status:** 🚧 This project is **brand new**. Use at your own risk.\n\n## Overview\n\nThis emitter allows you to define your database schema using TypeSpec's type-safe language with specialized decorators and automatically generate Drizzle ORM schema files, enabling a single source of truth for your database schema definitions alongside other artifacts.\n\n## Features\n\n- Generate Drizzle schema definitions from TypeSpec models\n- Decorator-based configuration for database-specific concerns\n- Support for table customization, constraints, and relationships\n- Primary keys, unique constraints, indexes, and default values\n- One-to-one, one-to-many, and many-to-many relationships\n- Junction table support for many-to-many relationships\n- Schema namespacing and custom table/column names\n- Type-safe database schema generation\n- Integration with TypeSpec's existing ecosystem\n\n## Installation\n\n```sh\nbun add -D @omnidotdev/typespec-drizzle\n```\n\n## Usage\n\n### Basic Usage\n\n1. Add the emitter to your TypeSpec configuration (`tspconfig.yaml`):\n\n```yaml\nemit:\n  - \"@omnidotdev/typespec-drizzle\"\n```\n\n2. Define your models in TypeSpec with decorators:\n\n```typespec\nimport \"@omnidotdev/typespec-drizzle\";\n\n@table({ name: \"users\" })\nmodel User {\n  @id\n  id: string;\n\n  @unique\n  email: string;\n\n  name: string;\n\n  @default(\"now()\")\n  createdAt: utcDateTime;\n}\n\n@table({ name: \"posts\" })\nmodel Post {\n  @id\n  id: string;\n\n  title: string;\n  content: string;\n\n  @manyToOne({\n    foreignKey: \"authorId\",\n    references: \"id\",\n  })\n  authorId: string;\n\n  @default(\"now()\")\n  createdAt: utcDateTime;\n}\n```\n\n3. Add a `tspconfig.yaml` file:\n\n```yaml\nemit:\n  - \"@omnidotdev/typespec-drizzle\"\n  - \"@typespec/json-schema\"\noptions:\n  \"@omnidotdev/typespec-drizzle\":\n    outputDir: \"./tsp-output\"\n```\n\n4. Run the TypeSpec compiler:\n\n```sh\ntsp compile .\n```\n\nThe emitter will generate Drizzle schema files in the output directory, plus JSON schemas for your models.\n\n## Decorators\n\n### Table Decorators\n\n#### `@table(options?)`\n\nMark a model as a database table.\n\n```typespec\n@table({ name: \"custom_users\", schema: \"auth\" })\nmodel User {\n  // ...\n}\n```\n\n**Options:**\n\n- `name?: string` - Custom table name (defaults to model name in lowercase)\n- `schema?: string` - Database schema name\n\n#### `@junction`\n\nMark a model as a junction table for many-to-many relationships.\n\n```typespec\n@junction\n@table({ name: \"user_roles\" })\nmodel UserRole {\n  @manyToOne({ foreignKey: \"userId\", references: \"id\" })\n  userId: string;\n\n  @manyToOne({ foreignKey: \"roleId\", references: \"id\" })\n  roleId: string;\n}\n```\n\n### Column Decorators\n\n#### `@column(options?)`\n\nConfigure column-specific options.\n\n```typespec\n@column({ name: \"user_email\" })\nemail: string;\n```\n\n**Options:**\n\n- `name?: string` - Custom column name (defaults to property name)\n\n#### `@id`\n\nMark a property as the primary key.\n\n```typespec\n@id\nid: string;\n```\n\n#### `@autoIncrement`\n\nMark a numeric primary key as auto-incrementing.\n\n```typespec\n@id\n@autoIncrement\nid: int64;\n```\n\n#### `@default(value)`\n\nSet a default value for a column.\n\n```typespec\n@default(\"'active'\")\nstatus: string;\n\n@default(\"now()\")\ncreatedAt: utcDateTime;\n\n@default(\"0\")\ncount: int32;\n\n@default(\"false\")\nisActive: boolean;\n```\n\n#### `@unique(name?)`\n\nAdd a unique constraint to a column.\n\n```typespec\n@unique(\"unique_email\")\nemail: string;\n\n@unique  // Uses default constraint name\nusername: string;\n```\n\n#### `@index(name?)`\n\nAdd an index to a column.\n\n```typespec\n@index(\"idx_created_at\")\ncreatedAt: utcDateTime;\n\n@index  // Uses default index name\ntitle: string;\n```\n\n### Relationship Decorators\n\n#### `@oneToOne(options?)`\n\nDefine a one-to-one relationship.\n\n```typespec\n@oneToOne({ foreignKey: \"profileId\", references: \"id\" })\nprofileId: string;\n```\n\n#### `@oneToMany(options?)`\n\nDefine a one-to-many relationship.\n\n```typespec\n@oneToMany({ foreignKey: \"categoryId\", references: \"id\" })\nposts: Post[];\n```\n\n#### `@manyToOne(options?)`\n\nDefine a many-to-one relationship.\n\n```typespec\n@manyToOne({ foreignKey: \"authorId\", references: \"id\" })\nauthorId: string;\n```\n\n#### `@manyToMany(options)`\n\nDefine a many-to-many relationship.\n\n```typespec\n@manyToMany({ through: \"post_tags\" })\ntags: Tag[];\n```\n\n**Relationship Options:**\n\n- `foreignKey?: string` - Name of the foreign key field\n- `references?: string` - Field in the target table (defaults to \"id\")\n- `through?: string` - Junction table name (required for many-to-many)\n\n## Examples\n\n### Complete Blog Schema\n\n```typespec\nimport \"@omnidotdev/typespec-drizzle\";\n\n@table({ name: \"users\" })\nmodel User {\n  @id\n  id: string;\n\n  @unique\n  @index(\"idx_username\")\n  username: string;\n\n  @unique\n  @index(\"idx_email\")\n  email: string;\n\n  @default(\"now()\")\n  createdAt: utcDateTime;\n}\n\n@table({ name: \"categories\" })\nmodel Category {\n  @id\n  id: string;\n\n  @unique\n  name: string;\n\n  @manyToOne({ foreignKey: \"parentId\", references: \"id\" })\n  parentId?: string;\n}\n\n@table({ name: \"posts\" })\nmodel Post {\n  @id\n  id: string;\n\n  title: string;\n  content: string;\n\n  @manyToOne({ foreignKey: \"authorId\", references: \"id\" })\n  authorId: string;\n\n  @manyToOne({ foreignKey: \"categoryId\", references: \"id\" })\n  categoryId?: string;\n\n  @manyToMany({ through: \"post_tags\" })\n  tags: Tag[];\n\n  @default(\"now()\")\n  createdAt: utcDateTime;\n}\n\n@table({ name: \"tags\" })\nmodel Tag {\n  @id\n  id: string;\n\n  @unique\n  name: string;\n\n  @default(\"now()\")\n  createdAt: utcDateTime;\n}\n\n@junction\n@table({ name: \"post_tags\" })\nmodel PostTag {\n  @id\n  id: string;\n\n  @manyToOne({ foreignKey: \"postId\", references: \"id\" })\n  postId: string;\n\n  @manyToOne({ foreignKey: \"tagId\", references: \"id\" })\n  tagId: string;\n\n  @default(\"now()\")\n  createdAt: utcDateTime;\n}\n```\n\n## Getting Started\n\n### Local Development\n\nUse [Tilt](https://tilt.dev) for a unified development experience:\n\n```sh\ntilt up\n```\n\nor manually install and build:\n\n```sh\nbun install\nbun run build # or `bun run build:watch`\n```\n\nTests can be run with `bun test`.\n\n## Contributing\n\nSee Omni's [contributing docs](https://docs.omni.dev/contributing/overview).\n\n## License\n\nThe code in this repository is licensed under Apache 2.0, \u0026copy; [Omni LLC](https://omni.dev). See [LICENSE.md](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomnidotdev%2Ftypespec-drizzle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fomnidotdev%2Ftypespec-drizzle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomnidotdev%2Ftypespec-drizzle/lists"}