Open source codemods for moving to MoroJS

Migrations

Move existing Node.js apps to MoroJS with predictable, mechanical rewrites. No magic, no rewriting your business logic — just the syntactic shifts that get you running on @morojs/moro.

Supported Frameworks

Express is shipping today. The rest are next on the roadmap — open an issue or PR if you need one sooner.

Available

Express

Mechanical rewrites for the most common Express patterns. Battle-tested codemod with full test coverage.

View guide
Planned

Fastify

Schema-first migration with hook and plugin mapping to MoroJS modules and middleware.

Coming soon
Planned

Koa

Context-style middleware translated into MoroJS request/response handlers.

Coming soon
Planned

NestJS

Decorator-driven controllers and providers mapped onto MoroJS modules and dependency injection.

Coming soon
Available now

Express → MoroJS

The Express codemod walks your project tree and rewrites Express imports plus the usual factory and middleware helpers to their MoroJS equivalents. It is intentionally small and predictable — you keep ownership of the rest.

1

Clone & dry-run

See exactly what will change before touching a single file.

Dry run

bash

# Clone the migrations repo
git clone https://github.com/Moro-JS/migrations.git
cd migrations

# Dry-run against your project (prints a colored diff, no writes)
node express/scripts/migrate-express.mjs /path/to/your/app
2

Apply the rewrites

Add --write to commit the changes in place.

Write changes

bash

# Apply changes in place
node express/scripts/migrate-express.mjs /path/to/your/app --write

# Limit which extensions are scanned (default: ts,tsx,js,mjs,cjs)
node express/scripts/migrate-express.mjs /path/to/your/app --write --ext=ts,js
3

Swap the dependency

Once the diff looks good, install MoroJS and remove Express. The rewritten imports already point at @morojs/moro.

Update dependencies

bash

# Install MoroJS in your project
npm install @morojs/moro

# Remove Express once the migration is verified
npm uninstall express

Before & After

A representative file the codemod will rewrite for you.

Before (Express)

javascript

1// Express
2const express = require('express');
3const app = express();
4
5app.use(express.json());
6app.use(express.urlencoded({ extended: true }));
7app.use('/public', express.static('./public'));
8
9const router = express.Router();
10router.get('/users/:id', (req, res) => {
11  res.json({ id: req.params.id });
12});
13
14app.use('/api', router);
15app.listen(3000);

After (MoroJS)

javascript

1// MoroJS
2const { createApp, createRouter, json, urlencoded, staticFiles } = require('@morojs/moro');
3const app = createApp();
4
5app.use(json());
6app.use(urlencoded({ extended: true }));
7app.use('/public', staticFiles('./public'));
8
9const router = createRouter();
10router.get('/users/:id', (req, res) => {
11  res.json({ id: req.params.id });
12});
13
14app.use('/api', router);
15app.listen(3000);

What gets rewritten

The full set of mechanical swaps the codemod performs.

ExpressMoroJS
require('express')require('@morojs/moro')
import ... from 'express'import ... from '@morojs/moro'
express()createApp()
express.Router()createRouter()
express.json(...)json(...)
express.urlencoded(...)urlencoded(...)
express.static(path)staticFiles(path)

CLI flags

<dir>

The root of the codebase to scan. Required positional argument.

--write

Apply the changes in place. Without this flag the script runs as a dry run.

--ext=ts,js

Comma-separated extension filter. Defaults to ts,tsx,js,mjs,cjs.

The script automatically skips node_modules, dist, build, .git, .next, and coverage.

Known limitations

  • Only the swaps in the table above are performed. Arbitrary middleware logic and routing APIs are left untouched.
  • app.listen() callback style and 4-arg error middleware are already compatible — nothing to rewrite.
  • Aliased imports like import { Router as R } from 'express' have their source updated, but local names stay as you wrote them.
  • Always run a dry run first and review the diff — especially in projects with custom wrappers around Express.

After the codemod

You are now on MoroJS. Here is where to go next to take advantage of the things Express never gave you.

Intelligent Routing

Replace ad-hoc route files with chainable, type-safe routes that infer params, queries, and bodies.

Read the docs

Validation by Default

Bring Zod, Joi, Yup, or class-validator into the request lifecycle without writing custom middleware.

Read the docs

Multi-Runtime Adapters

Take the same MoroJS app to Node, Lambda, Cloudflare Workers, or Vercel Edge with no rewrites.

Read the docs

Need a different framework?

The migrations repo is intentionally small and easy to read. Open an issue with the patterns you want automated, or contribute a codemod for your stack.