Typescript RPC APIsAt The Speed Of Light ⚡

mion is the definitive TypeScript Framework for Full Stack APIs.
It offers The best Developer Experience for building Single Page Apps.

RPC Like

RPC architecture for simpler and easier to consume APIs. Just use remote methods as any other local async method. mion is focused on offering the best developer experience.

Validation and JSON round trip of params and results out of the box.

JSON Round Trip
serverMap<string, number>wire[["a",1]]client✓Map<string, number>plain JSON: ✕ empty {}
serverSet<string>wire["admin"]client✓Set<string>plain JSON: ✕ empty {}
serverDatewire"2024-02-02T02:02:02.000Z"client✓Dateplain JSON: ✕ a string
serverbigintwire"9007199254740993"client✓bigintplain JSON: ✕ throws TypeError
serverTemporal.PlainDatewire"2024-02-02"client✓Temporal.PlainDateplain JSON: ✕ a string
Client & Server Validation
callroutes.getUser('1234')client✕validation-errorserverno request sent
callroutes.getUser(1234)client✓valid, sentserver✓checked again, route runstyped result: ✓ User | null
mion-router.ts
// packages/private-examples/src/_homepage/home-server.tsimport {createMionRouter, Routes} from '@mionjs/router';import {startNodeServer} from '@mionjs/platform-node';const mion = createMionRouter();
Automatic Validation and JSON Round Trip from Typescript types
interface User { id: number; name: string; age: number; createdAt: Date; tags: Set<string>;}interface Order { id: string; userId: number; amount: number;}
Object based router with rpc methods that receive Fully Validated params
const routes = { getUser: mion.query((ctx, id: number): User | null => { if (id !== 1234) return null; const tags = new Set(['tag1', 'tag2']); const user: User = { id: 1234, name: 'John', age: 30, createdAt: new Date(), tags, }; return user; }), getOrder: mion.query((ctx, id: string): Order | null => { if (id !== 'ORDER-123') return null; const order: Order = {id: 'ORDER-123', userId: 1234, amount: 100}; return order; }), sayHello: mion.route((ctx, name: string): string => `Hello ${name}`),} satisfies Routes;export const myApi = mion.initRoutes(routes);export type MyApi = typeof myApi;startNodeServer({port: 3000});

Fully Typed Client

Fully typed client that seamlessly bridges frontend and backend with static type checking, autocompletion, automatic validation and JSON round trip.

Lightweight and framework-agnostic. Use it with React, Vue, Svelte, or any frontend framework.

mion-client.ts
// packages/private-examples/src/_homepage/home-client.tsimport {initClient} from '@mionjs/client';import type {MyApi} from './home-server.ts';const {routes} = initClient<MyApi>({  baseURL: 'http://localhost:3000',});
Autocomplete: shows available routes
const [user, error] = await routes.
  • getOrder
  • getUser
  • sayHello
getUser(1234).call();
if (user) { user.
User.createdAt: Date
createdAt
;
// @annotate: Native Classes Like Set Make the JSON Round Trip Automatically user.
User.tags: Set<string>
tags
;
}// Type error: id must be a number// @ts-expect-error -- shown on purpose; the assertion fails the build if this ever stops erroringroutes.getUser('1234').call();

Batch Requests

Execute multiple routes in a single HTTP request. Batch API calls together, and orchestrate router logic from the client.

GraphQL-like data composition with the simplicity of RPC. Resolve relationships in a single request using inputFrom.
mion-batch.ts
// packages/private-examples/src/_homepage/home-batch.tsimport {initClient, batch, inputFrom} from '@mionjs/client';import type {MyApi} from './home-server.ts';const {routes} = initClient<MyApi>({baseURL: 'http://localhost:3000'});const orderReq = routes.getOrder('ORDER-123');
inputFrom maps order.userId → getUser input, (mapping function runs server-side)
const userIdMapping = inputFrom(orderReq, (order) => order!.userId);const userReq = routes.getUser(userIdMapping.asArg());const [[order], [user]] = await batch([orderReq, userReq]).call();if (order && user) { console.log(`Order ${order.id} placed by ${user.name}`);}

RunTypes

mion uses RunTypes behind the scenes to generate validation and JSON round trip functions from your TypeScript types, at build time. RunTypes supports advanced type formats and can be used as a standalone library.

No schema libraries needed. TypeScript is the single source of truth.

mion-run-types.ts
// packages/private-examples/src/_homepage/home-run-types.tsimport {createValidateFn, createJsonEncoderFn} from '@mionjs/run-types';import {createMockDataFn} from '@mionjs/run-types/mocking';interface User {  id: string;  name: string;  createdAt: Date;  tags: Set<string>;}
Create precompiled functions directly from TypeScript types
const isUser = createValidateFn<User>();const encodeUser = createJsonEncoderFn<User>();const mockUser = createMockDataFn<User>();
Generate mock data - respects type structure
const
const user: User
user
= mockUser();
Validate data at runtime
isUser(user);
JSON round trip for complex types (Date, Set, unions)
const
const json: string
json
= encodeUser(user);

Drizzle ORM

Declare Drizzle ORM tables with drizzle's names and settings, and get full validation fidelity from the inferred models. Same builders, same runtime: only the types get smarter.

Column params like varchar length reach the compiled validators, and routes share them.

mion-drizzle.ts
// packages/private-examples/src/_homepage/home-drizzle.tsimport * as DZ from '@mionjs/drizzle-orm-pg-core';import type {InferSelectModel} from '@mionjs/drizzle-orm';import {createValidateFn} from '@mionjs/run-types';
Declare drizzle tables with the column builders from @mionjs/drizzle-orm-pg-core
const users = DZ.pgTable('users', { id: DZ.uuid('id', {primaryKey: true, defaultRandom: true}), name: DZ.varchar('name', {length: 100, notNull: true}), age: DZ.integer('age', {notNull: true}), createdAt: DZ.timestamp('created_at', {defaultNow: true, notNull: true}),});
The inferred model carries formats, not plain primitives: UUID, String<{maxLength: 100}>, Int32
type User = InferSelectModel<typeof users>;
The compiled validator enforces every captured param with no runtime guards
export const validateUser = createValidateFn<User>();

Vertical Integration

Most modern stacks are tools glued together (validation, routing, JSON round trip, client generation), all wired manually. mion replaces that with a single integrated system, reducing boilerplate, inconsistencies, and maintenance overhead.

Hover a library to see what mion does instead.

Solid Performance

Routes are looked up in memory rather than matched against a URL pattern, validation and the JSON round trip are compiled at build time, and routes load on demand so a cold start has little to do. The result is measured against the fastest frameworks on every deploy.

Benchmarks (Req/S)

$ loading benchmarks…

 

Copyright © 2026