{"id":39886311,"url":"https://github.com/rejot-dev/rejot","last_synced_at":"2026-01-18T14:37:41.849Z","repository":{"id":280707359,"uuid":"934317301","full_name":"rejot-dev/rejot","owner":"rejot-dev","description":"Supercharged Replication for Developers","archived":false,"fork":false,"pushed_at":"2025-12-09T13:24:20.000Z","size":5892,"stargazers_count":47,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-23T13:34:34.048Z","etag":null,"topics":["data-catalog","database","developer-tools","distributed-systems","event-streaming","microservices"],"latest_commit_sha":null,"homepage":"https://rejot.dev/","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/rejot-dev.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-02-17T16:19:38.000Z","updated_at":"2025-12-09T13:24:26.000Z","dependencies_parsed_at":"2025-03-23T22:25:14.666Z","dependency_job_id":"97110537-18de-4a43-9fc2-c294c65e1cda","html_url":"https://github.com/rejot-dev/rejot","commit_stats":null,"previous_names":["rejot-dev/rejot"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/rejot-dev/rejot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rejot-dev%2Frejot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rejot-dev%2Frejot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rejot-dev%2Frejot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rejot-dev%2Frejot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rejot-dev","download_url":"https://codeload.github.com/rejot-dev/rejot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rejot-dev%2Frejot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28537845,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T13:04:05.990Z","status":"ssl_error","status_checked_at":"2026-01-18T13:01:44.092Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["data-catalog","database","developer-tools","distributed-systems","event-streaming","microservices"],"created_at":"2026-01-18T14:37:41.150Z","updated_at":"2026-01-18T14:37:41.828Z","avatar_url":"https://github.com/rejot-dev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003ca href=\"https://rejot.dev\"\u003e\n    \u003cpicture\u003e\n      \u003csource height=\"100px\" media=\"(prefers-color-scheme: dark)\" srcset=\"./resources/rejot-logo-text-white.png\"\u003e\n      \u003csource height=\"100px\" media=\"(prefers-color-scheme: light)\" srcset=\"./resources/rejot-logo-text-black.png\"\u003e\n      \u003cimg height=\"100px\" alt=\"The ReJot logo\" src=\"./resources/rejot-logo-text-black.png\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eSupercharged Replication:\u003c/b\u003e\n  \u003ci\u003eTurn the write-ahead log of your database into an asynchronous communication channel for your services 🚀\u003c/i\u003e\n\u003c/p\u003e\n\n\u003ch4 align=\"center\"\u003e\n  \u003ca href=\"https://rejot.dev/docs/start/quickstart/\"\u003eQuickstart\u003c/a\u003e\n  |\n  \u003ca href=\"https://rejot.dev/docs/\"\u003eDocs\u003c/a\u003e\n  |\n  \u003ca href=\"https://x.com/ReJotSync\"\u003eFollow on X\u003c/a\u003e\n\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./resources/rejot-system-overview.webp\" alt=\"ReJot's data catalog system overview\" width=\"90%\"\u003e\n\u003c/p\u003e\n\n## Introduction\n\nReJot is the missing middle-ground solution between synchronous inter-service communication\n(REST/SOAP) and asynchronous event streaming (like Kafka).\n\nOur solution is based on database replication with a focus on developers (as opposed to\ninfrastructure). With ReJot, you define what to publish and consume using your database's query\nlanguage. The transformations and schemas are co-located with a service's internal data model.\n\nWe solve the problem of fragile service calls and compounding latency issues that arise from\nsynchronous microservice communication by being an asynchronous alternative. At the same time we can\navoid the operational complexity that Kafka brings by re-using your database's changelog as a queue.\nMaking ReJot a lightweight addition to your infrastructure.\n\nReplication is managed in your codebase using\n[Public and Consumer Schemas](https://rejot.dev/docs/guides/defining-schemas/). Our CLI collects\nthese into a [Manifest](https://rejot.dev/docs/guides/managing-manifests/) which is then used by our\nsync engine to replicate the data (see [Architecture Overview](#architecture-overview) below).\n\n## Quickstart\n\nSee our [Quickstart Guide](https://rejot.dev/docs/start/quickstart/) to get started.\n\nTL;DR:\n\n- Install the `rejot-cli` (using Node / Bun)\n- Setup a Postgres database with logical replication enabled\n- Initialize a manifest \u0026 add database connections\n- Define your Public \u0026 Consumer schemas\n- Start replicating!\n\n### Installing\n\nGet started with ReJot through `rejot-cli`. You'll need to have [Node.js](https://nodejs.org/) or\n[Bun](https://bun.sh) installed to run it.\n\n```bash\nnpm install -g @rejot-dev/cli\n```\n\n### Setting up a Manifest\n\n(Assuming `$MY_SOURCE_DB` and `$MY_SINK_DB` are Postgres connection strings)\n\n```bash\nrejot-cli manifest init --slug \"rejot-test\" \u0026\u0026 \\\n  rejot-cli manifest connection add --slug source --connection-string $MY_SOURCE_DB \u0026\u0026 \\\n  rejot-cli manifest datastore add --connection source --publication my_rejot_publication --slot my_rejot_slot \u0026\u0026 \\\n  rejot-cli manifest connection add --slug sink --connection-string $MY_SINK_DB \u0026\u0026 \\\n  rejot-cli manifest datastore add --connection sink\n```\n\nNow `rejot-cli manifest info` should show your manifest and the connections you've added. We'll\ncreate the publication and replication slot for you when first starting a sync.\n\n### Public Schema\n\nA public schema defines how a service's internal data model is transformed into a new data model\nthat can be consumed by other services. It is executed once for every change in the source data\nstore.\n\n```ts\ncreatePublicSchema(\"my-public-schema\", {\n  source: { dataStoreSlug: \"source\" },\n  outputSchema: z.object({ id: z.string(), apiKey: z.string() }),\n  config: {\n    publicSchemaType: \"postgres\",\n    transformations: [\n      ...createPostgresPublicSchemaTransformations(\n        \"insertOrUpdate\",\n        \"api_key\",\n        `SELECT id, key AS \"apiKey\" FROM api_key WHERE id = :id`,\n      ),\n    ],\n  },\n  version: { major: 1, minor: 0 },\n});\n```\n\n### Consumer Schema\n\nA consumer schema references a public schema and defines how the data is stored in the sink data\nstore.\n\n```ts\ncreateConsumerSchema(\"my-consumer-schema\", {\n  source: {\n    manifestSlug: \"rejot-test\",\n    publicSchema: { name: \"my-public-schema\", majorVersion: 1 },\n  },\n  config: {\n    consumerSchemaType: \"postgres\",\n    destinationDataStoreSlug: \"sink\",\n    sql: `INSERT INTO target_table (id, api_key) VALUES (:id, :apiKey)\n          ON CONFLICT (id) DO UPDATE SET api_key = :apiKey`,\n  },\n});\n```\n\n### Collecting Schemas\n\nThe `rejot-cli` is used to collect all schemas in a given codebase into the ReJot manifest file.\n\n```bash\nrejot-cli collect --check --print ./schemas.ts\n```\n\nIf all looks good, you can materialize the schemas into your manifest. This will auto-discover the\nmanifest file.\n\n```bash\nrejot-cli collect --write ./schemas.ts\n```\n\n### Start Synchronization\n\n```bash\nrejot-cli manifest sync ./rejot-manifest.json\n```\n\n## How it works\n\n- Data dependencies in ReJot are modelled through Data Contracts known as **Public Schemas** and\n  **Consumer Schemas**. These contracts are defined by developers in code.\n- Public Schemas define how internal datasets are exposed, allowing teams to independently evolve\n  their internal data models while maintaining the contract with consumers. A transformation is\n  required to expose data, which encapsulates the internal data model.\n- Consumers at the same time can ingest these data sources by setting up a Consumer Schema, pointing\n  to a specific Public Schema and version.\n- ReJot connects to the publishing databases's write-ahead log (WAL) and pushes changes to Public\n  schemas to the data stores on the consuming side.\n- An intermediate event store is used as durable storage to store these updates.\n\n## Architecture Overview\n\nThe overview below shows how ReJot operates in a microservice architecture where each service has\nits own data store.\n\n- **Sync Engine**: Consumes the write-ahead log of a data store and applies the public schema\n  transformations to the rows changed in that data store. It stores these public schema\n  events/messages in the event store and handles writing the mutations to the destination data\n  store.\n- **Event Store**: A durable storage backend for public schema events.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./resources/rejot-architecture.svg\" alt=\"ReJot Architecture Overview\" width=\"65%\"\u003e\n\u003c/p\u003e\n\nNote that this diagram shows the \"sync engine\" as a singular monolithic service. In practice, a sync\nservice is a stateless service that can be deployed in a highly-available manner. Only one instance\ncan be active on a given WAL, but stand-bys can take over and also service data from the event\nstore. Each service exposes a `/read` route where a client can obtain events from a certain offset.\n\nEach instance of a sync service runs based on a manifest file. We're operating based on a philosophy\nwhere in enterprise environments, services and their accompanying databases are typically owned by a\nteam. We expect each unit of ownership (service + db) to have a manifest, in which consumer schemas\nwill reference public schemas in manifests owned by other teams. This means each referenced manifest\nslug needs to be resolved to a sync service running somewhere. This is done through\n[resolvers](https://rejot.dev/docs/reference/resolvers/).\n\n## Demo\n\nThe [\"ShopJot\" example repository](https://github.com/rejot-dev/example-microservice-ts) contains a\ndemo webshop application called ShopJot, built using a microservices architecture with Typescript.\nIt showcases how ReJot can be used to synchronize data between different services (which would\ntypically be owned by different teams).\n\nYou can find it live at [example.rejot.dev](https://example.rejot.dev).\n\n## Contributing\n\nWe welcome contributions! Since the project is evolving rapidly, please **create an\n[issue](https://github.com/rejot-dev/rejot/issues/new) before submitting a pull request** to discuss\nyour changes first.\n\nFor any general questions, feel free to [contact us here](https://rejot.dev/contact).\n\n## Thanks!\n\nWe'd be grateful if you could star ⭐️ the repo and share it with others!\n\nFeel free to join the [GitHub discussions](https://github.com/rejot-dev/rejot/discussions/120) to\nsay hi or ask questions!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frejot-dev%2Frejot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frejot-dev%2Frejot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frejot-dev%2Frejot/lists"}