{"id":22308848,"url":"https://github.com/makay11/rpc","last_synced_at":"2025-07-29T06:31:08.299Z","repository":{"id":228649617,"uuid":"773177103","full_name":"Makay11/rpc","owner":"Makay11","description":"An RPC library for quick development of seamless full-stack applications.","archived":true,"fork":false,"pushed_at":"2025-01-16T17:01:48.000Z","size":80,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-08T19:40:44.950Z","etag":null,"topics":["real-time","rpc","server-sent-events","sse","subscriptions","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@makay/rpc","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Makay11.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2024-03-17T00:06:08.000Z","updated_at":"2025-01-16T17:04:37.000Z","dependencies_parsed_at":"2024-04-05T23:21:01.617Z","dependency_job_id":"5bfb7779-9bd3-4e11-a726-7c09a1c1e57f","html_url":"https://github.com/Makay11/rpc","commit_stats":null,"previous_names":["makay11/rpc"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/Makay11/rpc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makay11%2Frpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makay11%2Frpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makay11%2Frpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makay11%2Frpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Makay11","download_url":"https://codeload.github.com/Makay11/rpc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makay11%2Frpc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267639569,"owners_count":24119780,"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-07-29T02:00:12.549Z","response_time":2574,"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":["real-time","rpc","server-sent-events","sse","subscriptions","typescript"],"created_at":"2024-12-03T20:15:38.829Z","updated_at":"2025-07-29T06:31:08.283Z","avatar_url":"https://github.com/Makay11.png","language":"TypeScript","readme":"# 🌐 @makay/rpc\n\nAn RPC library for quick development of seamless full-stack applications.\n\nPowered by a [Vite](https://vitejs.dev/) plugin and inspired by [Telefunc](https://telefunc.com/), [tRPC](https://trpc.io/) and other similar libraries.\n\n\u003e [!CAUTION]\n\u003e This project has been renamed to [SeamlessRPC](https://github.com/Makay11/seamlessrpc) and is no longer maintained here.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n[✨ Features](#-features)\n[🔧 Installation and setup](#-installation-and-setup)\n[🚀 Usage](#-usage)\n\n[📝 Input validation](#-input-validation)\n[🚨 Errors](#-errors)\n[📦 Async server state](#-async-server-state)\n[👍 Results](#-results)\n[📡 Subscriptions](#-subscriptions)\n\n[🔌 Adapters](#-adapters)\n[🔥 Hono](#-hono)\n[💎 Zod](#-zod)\n\n[🧑🏻‍💻 Contributing](#-contributing)\n[📄 License](#-license)\n\n\u003c/div\u003e\n\n---\n\n## ✨ Features:\n\n- 🎉 End-to-end TypeScript\n- 🚫 Zero boilerplate\n- 📡 Optional [server-sent events](https://en.wikipedia.org/wiki/Server-sent_events) support for real-time [subscriptions](#-subscriptions)\n- 🪶 Extremely small client bundle size addition\n- 🔗 Directly import and call tailored server functions from client code\n- 📄 Colocate server and client files (or don't)\n- 📦 Front-end and back-end framework agnostic\n- 📦 Validation library agnostic\n- 🚫 Low server overhead with no implicit run-time validations\n- 🪝 Use the [composables](https://vuejs.org/guide/reusability/composables)/[hooks](https://react.dev/reference/react/hooks) pattern in server code\n- 🔌 Includes adapters for popular libraries like [Hono](https://hono.dev/) and [Zod](https://zod.dev/)\n- 🧰 Includes utilities for [async server state](https://github.com/Makay11/rpc/blob/main/lib/src/server/state.ts) and [results](https://github.com/Makay11/rpc/blob/main/lib/src/result.ts)\n\n## 🔧 Installation and setup\n\n1. Install a single package:\n\n   ```sh\n   npm i @makay/rpc\n   ```\n\n   ```sh\n   yarn add @makay/rpc\n   ```\n\n   ```sh\n   pnpm add @makay/rpc\n   ```\n\n   ```sh\n   bun add @makay/rpc\n   ```\n\n   Everything is included out-of-the-box!\n\n2. Set up the Vite plugin:\n\n   ```ts\n   // vite.config.ts\n   import { rpc } from \"@makay/rpc/vite\"\n   import { defineConfig } from \"vite\"\n\n   export default defineConfig({\n     plugins: [rpc()],\n   })\n   ```\n\n   You can run both `vite` to start a dev server or `vite build` to build for production.\n\n3. Set up the RPC server (example using the included [Hono](https://hono.dev/) adapter):\n\n   ```ts\n   // src/server.ts\n   import { serve } from \"@hono/node-server\"\n   import { createRpc } from \"@makay/rpc/hono\"\n   import { Hono } from \"hono\"\n   import { cors } from \"hono/cors\"\n\n   const app = new Hono()\n\n   app.use(\n     \"/rpc\",\n     cors({ origin: \"http://localhost:5173\", credentials: true }),\n     await createRpc()\n   )\n\n   serve(app, (info) =\u003e {\n     console.log(`Server is running on http://localhost:${info.port}`)\n   })\n   ```\n\n   You can run the above file with something like `npx tsx src/server.ts`.\n\n   You can also run `npx tsx watch src/server.ts` to auto-reload during development.\n\n4. Configure your client:\n\n   ```ts\n   // src/main.ts\n   import { config } from \"@makay/rpc/client\"\n\n   config.url = \"http://localhost:3000/rpc\"\n   config.credentials = \"include\"\n   ```\n\n## 🚀 Usage\n\nCreate client and server files and seamlessly import server types and functions from client code with full TypeScript support!\n\n```ts\n// src/components/Todos.ts\nimport { createTodo, getTodos, type Todo } from \"./Todos.server\"\n\nlet todos: Todo[] = []\n\nasync function main() {\n  todos = await getTodos()\n\n  console.log(todos)\n\n  const newTodo = await createTodo(\"New Todo\")\n\n  console.log(newTodo)\n}\n\nmain()\n```\n\n```ts\n// src/components/Todos.server.ts\nexport type Todo = {\n  id: string\n  text: string\n}\n\nconst todos: Todo[] = []\n\nexport async function getTodos() {\n  return todos\n}\n\nexport async function createTodo(text: string) {\n  const todo = {\n    id: crypto.randomUUID(),\n    text,\n  }\n\n  todos.push(todo)\n\n  return todo\n}\n```\n\nServe the above `src/components/Todos.ts` through Vite and you should see the array of todos printed to your browser console. Reload the page a bunch of times and you should see the array grow since the state is persisted in the server!\n\nIn a real scenario you would store your data in a database rather than in the server memory, of course. The snippets above are merely illustrative.\n\n## 📝 Input validation\n\nThere is no implicit run-time validation of inputs in the server. In the example above, the function `createTodo` expects a single string argument. However, if your server is exposed publicly, bad actors or misconfigured clients might send something unexpected which can cause undefined behavior in you program.\n\nTherefore, it is **extremely recommended** that you validate all function inputs. You can use any validation library you want for this.\n\nHere's a basic example using [Zod](https://zod.dev/):\n\n```ts\n// src/components/Todos.server.ts\nimport { z } from \"zod\"\n\nconst TextSchema = z.string().min(1).max(256)\n\nexport async function createTodo(text: string) {\n  TextSchema.parse(text)\n\n  // `text` is now safe to use since Zod would have\n  // thrown an error if it was invalid\n}\n```\n\nWhen using the [Hono](https://hono.dev/) adapter, for instance, the code above will result in a `500 Internal Server Error` when you send an invalid input. In order to return the expected `400 Bad Request` instead, you have many options depending on the libraries, frameworks, and adapters you are using. Here are a few examples:\n\n1. Catch the [Zod](https://zod.dev/) error and throw a `ValidationError` from `@makay/rpc/server` instead:\n\n   ```ts\n   import { ValidationError } from \"@makay/rpc/server\"\n\n   const TextSchema = z.string().min(1).max(256)\n\n   export async function createTodo(text: string) {\n     try {\n       TextSchema.parse(text)\n     } catch (error) {\n       if (error instanceof ZodError) {\n         throw new ValidationError(error.error.format())\n       }\n       throw error\n     }\n\n     // `text` is now safe to use\n   }\n   ```\n\n   This is of course a bit too verbose to be practical.\n\n2. Use the included [Zod](https://zod.dev/) adapter:\n\n   ```ts\n   import { z, zv } from \"@makay/rpc/zod\"\n\n   const TextSchema = z.string().min(1).max(256)\n\n   export async function createTodo(text: string) {\n     zv(text, TextSchema)\n\n     // `text` is now safe to use\n   }\n   ```\n\n   This is much less verbose than the previous option.\n\n3. Use the `onError` callback of the [Hono](https://hono.dev/) adapter:\n\n   ```ts\n   import { serve } from \"@hono/node-server\"\n   import { createRpc } from \"@makay/rpc/hono\"\n   import { Hono } from \"hono\"\n   import { cors } from \"hono/cors\"\n   import { ZodError } from \"zod\"\n\n   const app = new Hono()\n\n   const rpc = await createRpc({\n     onError(ctx, error) {\n       if (error instanceof ZodError) {\n         return ctx.json(error.error.format(), 400)\n       }\n       throw error\n     },\n   })\n\n   app.use(\n     \"/rpc\",\n     cors({ origin: \"http://localhost:5173\", credentials: true }),\n     rpc\n   )\n\n   serve(app, (info) =\u003e {\n     console.log(`Server is running on http://localhost:${info.port}`)\n   })\n   ```\n\n   This allows you to catch any unhandled [Zod](https://zod.dev/) errors and return `400 Bad Request` regardless of which server function threw the error.\n\nYou can easily adapt any of the examples above to work with any libraries and frameworks you are using. Remember that `@makay/rpc` is completely agnostic.\n\n## 🚨 Errors\n\nWIP\n\n## 📦 Async server state\n\nWIP\n\n## 👍 Results\n\nWIP\n\n## 📡 Subscriptions\n\nWIP\n\n## 🔌 Adapters\n\n### 🔥 Hono\n\nWIP\n\n### 💎 Zod\n\nWIP\n\n## 🧑🏻‍💻 Contributing\n\nContributions, issues, suggestions, ideas and discussions are all welcome!\n\nThis is an extremely young library and a lot can still change, be added and removed.\n\n## 📄 License\n\n[MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmakay11%2Frpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmakay11%2Frpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmakay11%2Frpc/lists"}