Next.js
mion resolves your types at build time, so its transform has to run inside Next. withMion sets that up in one line.
import {withMion} from '@mionjs/devtools/next';
// await is required: the whole-program scan must finish before Turbopack hands files over
export default await withMion({
reactStrictMode: true,
});
That is the whole setup. Your front end gets the same compiled validation and JSON round trip functions as the rest of mion, from the same types.
Turbopack and webpack
withMion picks the right setup for you. Turbopack has no plugin API, so mion starts a background process from next.config and registers a loader that asks it to rewrite each file. With next --webpack, mion uses the ordinary webpack plugin.
Only your own TypeScript is rewritten. Files in node_modules are left alone.
Hosting the API in Your Next App
Add a catch-all route handler that imports your routes module and re-exports the handlers @mionjs/platform-vercel builds from them. Give /api to both the router and the client:
import {createVercelHandler} from '@mionjs/platform-vercel';
// creates the router and registers the routes
import './routes-example.ts';
// the App Router method handlers Next expects
export const {GET, POST, PUT, DELETE, PATCH} = createVercelHandler();
import {createMionRouter, Routes, PublicApi} from '@mionjs/router';
// the route handler is mounted under /api; the client uses the same prefix
const mion = createMionRouter({basePath: '/api'});
export interface User {
id: string;
name: string;
email: string;
}
export const routes = {
users: {
getById: mion.route((ctx, id: string): User => {
return {id, name: 'John', email: '[email protected]'};
}),
create: mion.route((ctx, user: Omit<User, 'id'>): User => {
return {id: 'USER-123', ...user};
}),
},
} satisfies Routes;
export const myApi = mion.initRoutes(routes);
export type MyApi = PublicApi<typeof routes>;
import {initClient} from '@mionjs/client';
// type only, from the routes module the route handler registers
import type {MyApi} from './routes-example.ts';
// same /api prefix as the router, so baseURL stays at the app's own origin
const {routes} = initClient<MyApi>({
baseURL: 'https://my-app.example.com',
basePath: '/api',
});
export const greeting = await routes.users.getById('USER-123').call();
Batches in Your Next App
Nothing to configure. The build reads your batches and compiles them into the route handler. Batches need the API in this app's build.
Editing Types While the Dev Server Runs
Edit a type and every file rewritten from it recompiles, even when the type sits in a .d.ts with no import to follow. next dev stays correct without a restart.
Options
withMion takes the same tsConfig, client and runTypes options as the Vite plugin, for example to fetch route metadata:
import {withMion} from '@mionjs/devtools/next';
export default await withMion(
{reactStrictMode: true},
{
// fetch each route's metadata from the server on first use
client: {routes: 'fetch'},
}
);
The Vite server block is refused, and the Vue single file component switch is ignored. Next runs its own dev server and builds your API route with everything else.