Devtools

Next.js

Run mion's build transform in a Next.js app, on Turbopack or webpack.

mion resolves your types at build time, so its transform has to run inside Next. withMion sets that up in one line.

next.config.ts
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();

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:

next.config.ts
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.

Copyright © 2026