RPC Docs.

Prim+RPC is prerelease software. It may be unstable and functionality may change prior to full release.

Server Handlers

These are the currently supported handler plugins for Prim+RPC. For each Prim+RPC server instance you may choose one method handler and one callback handler (see Plugin Type in tables below). Remember that for each handler on the server you must also specify a compatible plugin on the client. For plugins/handlers to be compatible they must use the same type of transport (given in Transport Type in tables below).

Table of Contents

Astro

ForPlugin TypeTransport TypeFile Support
AstroMethod handlerHTTPFile

Prim+RPC supports Astro in SSR mode. It supports both Astro 2 and 3.

You can configure Astro with Prim+RPC like so ([...prim] in filename represents a catch-all route):

src/pages/prim/[...prim].ts

import { createPrimServer } from "@doseofted/prim-rpc"
import { defineAstroPrimHandler } from "@doseofted/prim-rpc-plugins/astro"
import module from "./my-example-module"
const prim = createPrimServer({ module })
// Astro 3.0
export const { GET, POST } = defineAstroPrimHandler({ prim })
// Astro 2.0 (exported method names are lowercase)
export const { GET: get, POST: post } = defineAstroPrimHandler({ prim })

The .contextTransform option of the plugin can be used to set the this value inside of functions used with Prim+RPC.

On the client-side, you can use the Prim+RPC client with a compatible method plugin. Since the client could be used either server or client side, you may conditionally set the URL and module depending on the environment, like so:


import { createMethodPlugin } from "@doseofted/prim-rpc-plugins/browser"
// We can import the module directly server-side (module is tree-shaken from client-side bundle)
const module = import.meta.env.SSR ? import("./my-example-module") : null
// And we only need the endpoint on the client-side where module is not available
const endpoint = import.meta.env.SSR ? "" : "/prim"
const client = createPrimClient({
module,
endpoint,
methodPlugin: createMethodPlugin(),
})

Tree-shaking server-side code with import.meta.env.SSR condition works in Astro. If you are using this plugin outside of Astro, you'll need to ensure that conditional code is tree-shaken properly.

Hono

ForPlugin TypeTransport TypeFile Support
HonoMethod handlerHTTPFile

Prim+RPC supports Hono allowing it to be used from serverless environments easily.

You can configure Hono with Prim+RPC like so:


import { createPrimServer } from "@doseofted/prim-rpc"
import { createMethodHandler } from "@doseofted/prim-rpc-plugins/hono"
import { Hono } from "hono"
import module from "./my-example-module"
const app = new Hono()
const methodHandler = createMethodHandler({ app })
createPrimServer({ module, methodHandler })
export default app

You may also register the Hono middleware yourself by importing honoPrimRpc and using it directly with Hono. The .contextTransform option of the module can be used to set the this value inside of functions used with Prim+RPC.

Fastify

ForPlugin TypeTransport TypeFile Support
FastifyMethod handlerHTTPFile

You can configure Fastify with Prim+RPC like so (note that both the multipartPlugin and formDataHandler options are completely optional and useful for for uploading files or supporting binary in JSON-like body):


import { createPrimServer } from "@doseofted/prim-rpc"
import { createMethodHandler } from "@doseofted/prim-rpc-plugins/fastify"
import Fastify from "fastify"
import multipartPlugin from "@fastify/multipart"
import formDataHandler from "form-data"
import module from "./my-example-module"
const fastify = Fastify()
const methodHandler = createMethodHandler({
fastify,
multipartPlugin,
formDataHandler,
})
createPrimServer({ module, methodHandler })
fastify.listen({ port: 1234 })

You may use the .contextTransform option of createMethodHandler() to determine what values from Fastify are bound to the function's this context.

Express

ForPlugin TypeTransport TypeFile Support
ExpressMethod handlerHTTPFile

You can configure Express with Prim+RPC like so (note that both the multipartPlugin and formDataHandler options are completely optional and useful for for uploading files or supporting binary in JSON-like body):


import { createPrimServer } from "@doseofted/prim-rpc"
import { createMethodHandler } from "@doseofted/prim-rpc-plugins/express"
import express from "express"
import multipartPlugin from "formidable"
import formDataHandler from "form-data"
import module from "./my-example-module"
const app = express()
const methodHandler = createMethodHandler({
app,
multipartPlugin,
formDataHandler,
})
createPrimServer({ module, methodHandler })
app.listen(1234)

You may use the .contextTransform option of createMethodHandler() to determine what values from Express are bound to the function's this context.

WS

ForPlugin TypeTransport TypeFile Support
wsCallback handlerWebSocketNone

You can configure ws with Prim+RPC like so:


import { createPrimServer } from "@doseofted/prim-rpc"
import { createCallbackHandler } from "@doseofted/prim-rpc-plugins/ws"
import { WebSocketServer } from "ws"
import module from "./my-example-module"
const wss = new WebSocketServer({ port: 1234 })
const callbackHandler = createCallbackHandler({ wss })
createPrimServer({ module, callbackHandler })

You may use the .contextTransform option of createCallbackHandler() to determine what values from ws are bound to the function's this context. The callback handler can be used with the method handler of your choice.

Nuxt / Nitro / H3

ForPlugin TypeTransport TypeFile Support
Nuxt, Nitro, H3Method handlerHTTPFile

Prim+RPC can be used with H3 and frameworks built upon H3 such as Nitro and Nuxt 3. Setup steps vary depending on which framework you are using.

You can configure H3 with Prim+RPC like so (note that formDataHandler is optional and is only used for sending files back to the client):


import { createPrimServer } from "@doseofted/prim-rpc"
import { createMethodHandler } from "@doseofted/prim-rpc-plugins/h3"
import formDataHandler from "form-data"
import { createApp, toNodeListener } from "h3"
import { createServer } from "node:http"
import module from "./my-example-module"
const app = createApp()
const server = createServer(toNodeListener(app))
const methodHandler = createMethodHandler({ app, formDataHandler })
createPrimServer({ module, methodHandler })
server.listen(1234)

If you're not using H3 directly and are instead looking to use Prim+RPC with Nitro (Nuxt 3's server), you can configure a route for Prim+RPC like so (note that the filename is [...].ts, representing a catch-all route in Nitro):

api/[...].ts

import { createPrimServer } from "@doseofted/prim-rpc"
import { defineH3PrimHandler } from "@doseofted/prim-rpc-plugins/h3"
import module from "./my-example-module"
const prim = createPrimServer({ module, prefix: "/api/prim" })
export default defineH3PrimHandler({ prim })

On the client-side, you can use the Prim+RPC client with a compatible method plugin. Since the client could be used either server or client side, you may conditionally set the URL depending on the environment, like so:


import { createMethodPlugin } from "@doseofted/prim-rpc-plugins/browser"
// We can import the module directly server-side (module is tree-shaken from client-side bundle)
const module = process.server ? import("./my-example-module") : null
// And we only need the endpoint on the client-side where module is not available
const endpoint = process.server ? "" : "/prim"
const client = createPrimClient({
module,
endpoint,
methodPlugin: createMethodPlugin(),
})

Tree-shaking server-side code with process.server condition works in Nuxt 3. If you are using this plugin outside of Nuxt 3, you'll need to ensure that conditional code is tree-shaken properly.

Next.js

ForPlugin TypeTransport TypeFile Support
Next.jsMethod handlerHTTPFile

Prim+RPC can be used with Next.js by defining a dedicated route. Currently, only the App Router is supported but Pages Router support is being considered. Next.js allows App/Page Routers to live in the same project.

You can configure the integration on the server like so (the [[...prim]] folder represents a catch-all route in Next.js):

app/prim/[[...prim]]/route.ts

import { createPrimServer } from "@doseofted/prim-rpc"
import { defineNextjsAppPrimHandler } from "@doseofted/prim-rpc-plugins/nextjs"
import module from "./my-example-module"
const prim = createPrimServer({ module, prefix: "/prim" })
export const { GET, POST } = defineNextjsAppPrimHandler({ prim })

On the client-side, you can use the Prim+RPC client with a compatible method plugin. Since the client could be used either server or client side, you may conditionally set the URL depending on the environment, like so:


import { createMethodPlugin } from "@doseofted/prim-rpc-plugins/browser"
// We can import the module directly server-side (module is tree-shaken from client-side bundle)
const module = typeof window === "undefined" ? import("./my-example-module") : null
// And we only need the endpoint on the client-side where module is not available
const endpoint = typeof window === "undefined" ? "" : "/prim"
const client = createPrimClient({
module,
endpoint,
methodPlugin: createMethodPlugin(),
})

Tree-shaking server-side code by checking typeof window condition works in Next.js. If you are using this plugin outside of Next.js, you'll need to ensure that conditional code is tree-shaken properly.

Node / HTTP

ForPlugin TypeTransport TypeFile Support
NodeMethod handlerHTTPN/A

Unavailable (planned)

Socket.io

ForPlugin TypeTransport TypeFile Support
Socket.ioCallback handlerSocket.ioN/A

Unavailable (planned)

Prim+RPC: a project by Ted Klingenberg

Dose of Ted

Anonymous analytics collected with Ackee