Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,24 @@

<h3 align="center">Typesafe APIs Made Simple 🪄</h3>

**oRPC is a powerful combination of RPC and OpenAPI**, makes it easy to build APIs that are end-to-end type-safe and adhere to OpenAPI standards, ensuring a smooth and enjoyable developer experience.
**oRPC is a powerful combination of RPC and OpenAPI**, makes it easy to build APIs that are end-to-end type-safe and adhere to OpenAPI standards

---

## Highlights

- **End-to-End Type Safety 🔒**: Ensure complete type safety from inputs to outputs and errors, bridging server and client seamlessly.
- **First-Class OpenAPI 📄**: Adheres to the OpenAPI standard out of the box, ensuring seamless integration and comprehensive API documentation.
- **Contract-First Development 📜**: (Optional) Define your API contract upfront and implement it with confidence.
- **Exceptional Developer Experience ✨**: Enjoy a streamlined workflow with robust typing and clear, in-code documentation.
- **Multi-Runtime Support 🌍**: Run your code seamlessly on Cloudflare, Deno, Bun, Node.js, and more.
- **Framework Integrations 🧩**: Supports Tanstack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
- **Server Actions ⚡️**: Fully compatible with React Server Actions on Next.js, TanStack Start, and more.
- **Standard Schema Support 🗂️**: Effortlessly work with Zod, Valibot, ArkType, and others right out of the box.
- **Fast & Lightweight 💨**: Built on native APIs across all runtimes – optimized for speed and efficiency.
- **Native Types 📦**: Enjoy built-in support for Date, File, Blob, BigInt, URL and more with no extra setup.
- **Lazy Router ⏱️**: Improve cold start times with our lazy routing feature.
- **SSE & Streaming 📡**: Provides SSE and streaming features – perfect for real-time notifications and AI-powered streaming responses.
- **Reusability 🔄**: Write once and reuse your code across multiple purposes effortlessly.
- **Extendability 🔌**: Easily enhance oRPC with plugins, middleware, and interceptors.
- **Reliability 🛡️**: Well-tested, fully TypeScript, production-ready, and MIT licensed for peace of mind.
- **Simplicity 💡**: Enjoy straightforward, clean code with no hidden magic.
- **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
- **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
- **📝 Contract-First Development**: Optionally define your API contract before implementation.
- **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
- **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
- **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
- **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
- **⏱️ Lazy Router**: Enhance cold start times with our lazy routing feature.
- **📡 SSE & Streaming**: Enjoy full type-safe support for SSE and streaming.
- **🌍 Multi-Runtime Support**: Fast and lightweight on Cloudflare, Deno, Bun, Node.js, and beyond.
- **🔌 Extendability**: Easily extend functionality with plugins, middleware, and interceptors.
- **🛡️ Reliability**: Well-tested, TypeScript-based, production-ready, and MIT licensed.

## Documentation

Expand Down
9 changes: 6 additions & 3 deletions apps/content/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import llmstxt from 'vitepress-plugin-llms'

export default defineConfig({
lang: 'en-US',
title: 'oRPC',
description:
'oRPC makes it easy to build APIs that are end-to-end type-safe and adhere to OpenAPI standards, ensuring a smooth and enjoyable developer experience.',
title: 'oRPC - Typesafe APIs Made Simple 🪄',
description: 'Easy to build APIs that are end-to-end type-safe and adhere to OpenAPI standards',
lastUpdated: true,
cleanUrls: true,
markdown: {
Expand Down Expand Up @@ -51,6 +50,7 @@ export default defineConfig({
{ text: 'Docs', link: '/docs/getting-started', activeMatch: '/docs/(?!openapi/)' },
{ text: 'OpenAPI', link: '/docs/openapi/getting-started', activeMatch: '/docs/openapi/' },
{ text: 'Examples', link: '/examples/openai-streaming', activeMatch: '/examples/' },
{ text: 'Blog', link: '/blog/v1-announcement', activeMatch: '/blog/' },
{
text: 'About',
items: [
Expand Down Expand Up @@ -205,6 +205,9 @@ export default defineConfig({
'/examples/': [
{ text: 'OpenAI Streaming', link: '/examples/openai-streaming' },
],
'/blog/': [
{ text: 'V1 Announcement', link: '/blog/v1-announcement' },
],
},
},
head: [
Expand Down
134 changes: 134 additions & 0 deletions apps/content/blog/v1-announcement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: oRPC v1 Announcement - Typesafe APIs Made Simple 🪄
description: oRPC v1 is now available - tRPC, ts-rest, next-safe-action, and more alternatives!
titleTemplate: ':title'
---

# oRPC v1 Announcement - Typesafe APIs Made Simple 🪄

oRPC is a thing help you build type-safe APIs with TypeScript. It's has own goal but can fairly be compared to other libraries like tRPC, ts-rest, next-safe-action, etc. or even alternative them.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Grammar correction needed in introduction.

Change "It's has own goal but can fairly be compared..." to "It has its own goal but can fairly be compared...".

-oRPC is a thing help you build type-safe APIs with TypeScript. It's has own goal but can fairly be compared to other libraries like tRPC, ts-rest, next-safe-action, etc. or even alternative them.
+oRPC is a tool to help you build type-safe APIs with TypeScript. It has its own goal but can fairly be compared to other libraries like tRPC, ts-rest, next-safe-action, etc., or even serve as an alternative to them.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
oRPC is a thing help you build type-safe APIs with TypeScript. It's has own goal but can fairly be compared to other libraries like tRPC, ts-rest, next-safe-action, etc. or even alternative them.
oRPC is a tool to help you build type-safe APIs with TypeScript. It has its own goal but can fairly be compared to other libraries like tRPC, ts-rest, next-safe-action, etc., or even serve as an alternative to them.
🧰 Tools
🪛 LanguageTool

[grammar] ~9-~9: The verb form seems incorrect.
Context: ...build type-safe APIs with TypeScript. It's has own goal but can fairly be compared to ...

(IS_VBZ)


## My Story

My oRPC journey started in early 2024 after I lost my job. Finding a new one was hard, and I realized a standard job wasn't really what I wanted. I had always dreamed of being an "indie hacker" – someone who makes useful things for others.

But looking back at my past work, I noticed something: I often spent more time complaining about the tools I used than focusing on what users needed. Maybe I cared too much about the tools themselves.

Because I was often frustrated with existing tools, I changed my plan. I thought, "What if I make a tool for developers, one that fixes the problems I always had?" I hoped that if I built a tool I liked, other developers would like it too.

That's how oRPC started. I began working hard on it around September 17, 2024. It wasn't easy; I had to rebuild oRPC three times to get the base right. After about three months, I shared an early version on Reddit ([see post](https://www.reddit.com/r/nextjs/comments/1h13upv/new_introducing_orpc_a_dropin_replacement_for/)).

At first, oRPC was just a side project. Then, a turning point came when someone privately offered **$100** to support it. I was surprised and really motivated! A month after that, I decided to stop my other projects and work on oRPC full-time, even though I didn't have another job. My life became: code, eat, sleep, repeat.

I had so many ideas for oRPC. I realized it would take all my focus and time, probably until the end of 2025, to make it happen.

But !!! Today is a **big step** on that journey. I'm happy and proud to announce that the core of oRPC is now stable, and Version 1.0 is officially out!

::: info
V1 means the public API is stable and ready for production use.
:::

## The Idea behind oRPC

oRPC philosophy is **powerful simplicity**. Define your API endpoints almost as easily as writing standard functions, yet automatically gain:

- End-to-end type safety (includes **errors**)
- Server Action compatibility
- Full OpenAPI specification generation
- Contract-first workflow support
- Standard function call compatibility

```ts
const getting = os
.use(dbProvider)
.use(requiredAuth)
.use(rateLimit)
.use(analytics)
.use(sentryMonitoring)
.use(retry({ times: 3 }))
.route({ method: 'GET', path: '/getting/{id}' })
.input(z.object({ id: z.string() }))
.use(canGetting, input => input.id)
.errors({
SOME_TYPE_SAFE_ERROR: {
data: z.object({ something: z.string() })
}
})
.handler(async ({ input, errors, context }) => {
// do something
})
.actionable() // server action compatible
.callable() // regular function compatible
```

Beyond built-in features, oRPC [metadata](https://orpc.unnoq.com/docs/metadata) system allows for community-driven extensions and future possibilities.

## Highlights

- **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
- **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
- **📝 Contract-First Development**: Optionally define your API contract before implementation.
- **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
- **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
- **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
- **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
- **⏱️ Lazy Router**: Enhance cold start times with our lazy routing feature.
- **📡 SSE & Streaming**: Enjoy full type-safe support for SSE and streaming.
- **🌍 Multi-Runtime Support**: Fast and lightweight on Cloudflare, Deno, Bun, Node.js, and beyond.
- **🔌 Extendability**: Easily extend functionality with plugins, middleware, and interceptors.
- **🛡️ Reliability**: Well-tested, TypeScript-based, production-ready, and MIT licensed.

## tRPC alternative

I used tRPC extensively and really liked it. However, I needed OpenAPI support for my projects. Although I found `trpc-openapi` to add OpenAPI to tRPC, it didn't work with Edge runtimes and has since been deprecated. This was very frustrating, prompting me to look for alternatives.

Also, setting up tRPC sometimes felt too complicated, especially for smaller projects like Cloudflare Durable Objects where I just needed a simple API. Another point is that tRPC mostly supports React Query. That was okay for me, but less helpful if you want to use Vue, Solid, or Svelte.

I did some **simple** benchmarks between oRPC and tRPC, and results show (full report [here](https://github.com/unnoq/orpc-benchmarks)):

- oRPC is **1,6 times typecheck faster** (5.9s vs 9.3s)
- oRPC is **2,8 times runtime faster** (295k reqs vs 104k reqs / 20 sec)
- oRPC is **1,26 times less max cpu usage** (102% vs 129%)
- oRPC is **2,6 times less max ram usage** (103MB vs 268MB)
- oRPC is **2,6 smaller in bundle size** ([32.5 kB](https://bundlejs.com/?q=%40orpc%2Fserver%2Cnode%3Ahttp%2C%40orpc%2Fclient%2C%40orpc%2Fclient%2Ffetch%2C%40orpc%2Fserver%2C%40orpc%2Fserver%2Fnode&treeshake=%5B*%5D%2C%5B*%5D%2C%5B*%5D%2C%5B*%5D%2C%5B*%5D%2C%5B*%5D&text=%22const+router+%3D+%7B%5Cn++ping%3A+os.handler%28%28%29+%3D%3E+%27pong%27%29%2C%5Cn%7D%5Cn%5Cnconst+handler+%3D+new+RPCHandler%28router%2C+%7B%5Cn++strictGetMethodPluginEnabled%3A+false%2C%5Cn%7D%29%5Cn%5Cnexport+const+server+%3D+createServer%28async+%28req%2C+res%29+%3D%3E+%7B%5Cn++const+%7B+matched+%7D+%3D+await+handler.handle%28req%2C+res%29%5Cn%5Cn++if+%28%21matched%29+%7B%5Cn++++res.statusCode+%3D+404%5Cn++++res.end%28%27Not+Found%27%29%5Cn++%7D%5Cn%7D%29%5Cn%5Cnconst+link+%3D+new+RPCLink%28%7B%5Cn++url%3A+%27https%3A%2F%2Fexample.com%27%2C%5Cn%7D%29%5Cn%5Cnexport+const+orpc%3A+RouterClient%3Ctypeof+router%3E+%3D+createORPCClient%28link%29%22) vs [84.5 kB](https://bundlejs.com/?q=%40trpc%2Fclient%2C%40trpc%2Fserver%2C%40trpc%2Fserver%2Fadapters%2Fstandalone%2Csuperjson&treeshake=%5B*%5D%2C%5B*%5D%2C%5B*%5D%2C%5B*%5D&share=MYewdgzgLgBLC8MCWYlQCoCUAKBhAdMAE4CmAhlCQBQDeAUDHEWZAGYhEC2JRAXDBACuABx4ArCOAA0dAL4BKOnVCRYZYcMwhBlIjERR8RbbtoMYwlAHN%2Bh4ceAkAJoNL4AjoJ4BPKlXn6AHwwAOTC4FYh8jIKSiQAHuFEsCrQAjwAbjz6MMTklAAS6OjYAMqZPGaMxjo8-OqaJjwyjHkUJLjglPFQ-jD0jNUkUK5g-bLmsjGKdAlJKeBpUETCwDltlFh4uAA2SCRgUAA8UN6iIKwwDVq1RIFVMHtgANYQ-ADa5owQwntQADIoZ4PQa5cBONBIcD8EDCIIwWH4U6ifTwRAhIQAIwgxCQwigULAIRaoKYXn4AAsoFBhKVBNjcfjCYCXiDSa4dvwQlSaW8APR8hJkTi-EiEECcYlfUnLFgQdhcOoCETiSRgEmghQawasMg7CAkSnU4Qs4EDUmMDlcnnCfmC%2BLC0XiyXa0Gytgcbh8ZWiIgSaTSxha6XBxgAXWmQA))

:::warning
Benchmark results can vary across environments and depend heavily on factors like your project's size, complexity, and setup. Many conditions can influence the outcome — so treat these numbers as a helpful reference, not a guarantee.
:::

::: info
You can read more about comparion [here](/docs/comparison)
:::

## ts-rest alternative

After running into the OpenAPI issues with tRPC, I tried ts-rest. While it helped with OpenAPI, I soon found it was missing features I relied on from tRPC, like flexible middleware and easy handling of certain data types (like Dates or Files). After using it for some APIs, I felt it wasn't the complete solution I wanted. This frustration was a key reason I started building oRPC.

::: info
You can read more about comparion [here](/docs/comparison)
:::

## next-safe-action alternative

I also experimented with `next-safe-action` to test server actions in Next.js, hoping they might be a good replacement for the tRPC style. However, I found they didn't quite fit my needs. I believe a dedicated RPC library like oRPC still provides a better developer experience for building APIs.

## Sponsors

In this long journey, I specially thank all my sponsors, they help me to keep going.

- [Zuplo - Serverless API Gateway, designed for developers](https://zuplo.link/orpc)
- [村上さん](https://github.com/SanMurakami)
- [あわわわとーにゅ](https://github.com/u1-liquid)
- [motopods](https://github.com/motopods)
- [Maxie](https://github.com/MrMaxie)
- [Stijn Timmer](https://github.com/Stijn-Timmer)
- [Robbe95](https://github.com/Robbe95)
- And my first sponsor (private) to start my story

If you interested in sponsoring oRPC, you can do it [here](https://github.com/sponsors/unnoq).
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Grammar correction: "If you interested" → "If you're interested".

Change "If you interested in sponsoring oRPC, you can do it here" to "If you're interested in sponsoring oRPC, you can do it here".

-If you interested in sponsoring oRPC, you can do it [here](https://github.com/sponsors/unnoq).
+If you're interested in sponsoring oRPC, you can do it [here](https://github.com/sponsors/unnoq).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
If you interested in sponsoring oRPC, you can do it [here](https://github.com/sponsors/unnoq).
If you're interested in sponsoring oRPC, you can do it [here](https://github.com/sponsors/unnoq).
🧰 Tools
🪛 LanguageTool

[uncategorized] ~128-~128: “you” seems less likely than “you’re” (you are).
Context: ...sponsor (private) to start my story If you interested in sponsoring oRPC, you can ...

(AI_HYDRA_LEO_CP_YOU_YOUARE)


<p align="center">
<a href="https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg">
<img src='https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg'/>
</a>
</p>
50 changes: 25 additions & 25 deletions apps/content/docs/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@ This comparison table helps you understand how oRPC differs from other popular T
- 🟡 Lacks features, or requires third-party integrations
- 🛑 Not supported or not documented

| Feature | oRPC | tRPC | ts-rest |
| ---------------------------------------- | ---- | ---- | ------- |
| End-to-end Input/Output Typesafe | ✅ | ✅ | ✅ |
| End-to-end Errors Typesafe | ✅ | 🟡 | ✅ |
| End-to-end File/Blob Typesafe | ✅ | 🟡 | 🛑 |
| End-to-end Streaming Typesafe | ✅ | ✅ | 🛑 |
| Tanstack Query Integration (React) | ✅ | ✅ | 🟡 |
| Tanstack Query Integration (Vue) | ✅ | 🛑 | 🟡 |
| Tanstack Query Integration (Solid) | ✅ | 🛑 | 🟡 |
| Tanstack Query Integration (Svelte) | ✅ | 🛑 | 🛑 |
| Vue Pinia Colada Integration | ✅ | 🛑 | 🛑 |
| With Contract-First Approach | ✅ | 🛑 | ✅ |
| Without Contract-First Approach | ✅ | ✅ | 🛑 |
| OpenAPI Support | ✅ | 🟡 | 🟡 |
| Server Actions Support | ✅ | | 🛑 |
| Lazy Router | ✅ | | 🛑 |
| Native Types (Date, URL, Set, Maps, ...) | ✅ | ✅ | 🛑 |
| Streaming response (SSE) | ✅ | ✅ | 🛑 |
| Standard Schema | ✅ | | 🛑 |
| Plugins-able (CORS, ...) | ✅ | ✅ | 🛑 |
| Dedicated Zod Schemas | ✅ | N/A | 🛑 |
| Use Native Modules on each runtime | ✅ | | 🟡 |
| Batch Request | ✅ | ✅ | 🛑 |
| WebSockets | 🛑 | ✅ | 🛑 |
| Nest.js integration | 🛑 | 🟡 | ✅ |
| Feature | oRPC docs | oRPC | tRPC | ts-rest |
| -------------------------------------------- | -------------------------------------------------------------------------------------------- | ---- | ---- | ------- |
| End-to-end Typesafe Input/Output | | ✅ | ✅ | ✅ |
| End-to-end Typesafe Errors | [1](/docs/client/error-handling), [2](/docs/error-handling#type%E2%80%90safe-error-handling) | ✅ | 🟡 | ✅ |
| End-to-end Typesafe File/Blob | [1](/docs/file-upload-download) | ✅ | 🟡 | 🛑 |
| End-to-end Typesafe Streaming | [1](/docs/event-iterator) | ✅ | ✅ | 🛑 |
| Tanstack Query Integration (React) | [1](/docs/tanstack-query/react) | ✅ | ✅ | 🟡 |
| Tanstack Query Integration (Vue) | [1](/docs/tanstack-query/vue) | ✅ | 🛑 | 🟡 |
| Tanstack Query Integration (Solid) | [1](/docs/tanstack-query/solid) | ✅ | 🛑 | 🟡 |
| Tanstack Query Integration (Svelte) | [1](/docs/tanstack-query/svelte) | ✅ | 🛑 | 🛑 |
| Vue Pinia Colada Integration | [1](/docs/pinia-colada) | ✅ | 🛑 | 🛑 |
| With Contract-First Approach | [1](/docs/contract-first/define-contract) | ✅ | 🛑 | ✅ |
| Without Contract-First Approach | | ✅ | ✅ | 🛑 |
| OpenAPI Support | [1](/docs/openapi/openapi-handler) | ✅ | 🟡 | 🟡 |
| OpenAPI Support for multiple schema | [1](/docs/openapi/openapi-handler) | ✅ | 🛑 | 🛑 |
| OpenAPI Bracket Notation Support | [1](/docs/openapi/bracket-notation) | ✅ | 🛑 | 🛑 |
| Server Actions Support | [1](/docs/server-action) | ✅ | ✅ | 🛑 |
| Lazy Router | [1](/docs/router#lazy-router) | ✅ | ✅ | 🛑 |
| Native Types (Date, URL, Set, Maps, ...) | [1](/docs/rpc-handler#supported-data-types) | ✅ | 🟡 | 🛑 |
| Streaming response (SSE) | [1](/docs/event-iterator) | ✅ | ✅ | 🛑 |
| Standard Schema (Zod, Valibot, ArkType, ...) | | ✅ | | 🛑 |
| Built-in Plugins (CORS, CSRF, Retry, ...) | | ✅ | 🛑 | 🛑 |
| Batch Request/Response | [1](/docs/plugins/batch-request-response) | ✅ | ✅ | 🛑 |
| WebSockets | (working) | 🛑 | ✅ | 🛑 |
| Nest.js integration | | 🛑 | 🟡 | ✅ |
Loading