Skip to content

jackofsometrade/moro

 
 

Repository files navigation

Moro

Moro Logo

High-performance multi-runtime framework with intelligent routing Functional • Type-safe • Multi-environment • Production-ready

npm version License: MIT Node.js Version TypeScript

DocumentationQuick StartExamplesAPI Reference


Why Moro?

Moro eliminates the pain points of traditional Node.js frameworks with intelligent routing and automatic middleware ordering. No more debugging middleware order issues or wrestling with type safety!

  • Multi-Runtime Support - Deploy to Node.js, Vercel Edge, AWS Lambda, Cloudflare Workers
  • Intelligent Routing - Chainable + schema-first APIs with automatic middleware ordering
  • Enterprise Authentication - Auth.js integration with RBAC, OAuth, and native adapter
  • Universal Validation - Support for Zod, Joi, Yup, Class Validator with full TypeScript inference
  • WebSocket Support - Pluggable adapters for Socket.IO, native WebSockets, or auto-detection
  • Native Performance - Zero framework overhead, optimized for each runtime
  • Functional Architecture - No decorators, pure functional patterns
  • Zero Order Dependencies - Framework handles optimal middleware execution

Superior Performance

Framework Req/sec Latency Memory
Moro 52,400 1.8ms 24MB
Express 28,540 3.8ms 45MB
Fastify 38,120 2.9ms 35MB
NestJS 22,100 4.5ms 58MB

Quick Start

Installation

npm install @morojs/moro
# or
yarn add @morojs/moro

Hello World

import { createApp, z } from '@morojs/moro';

const app = createApp();

// Intelligent routing - order doesn't matter!
app.post('/users')
   .body(z.object({
     name: z.string().min(2).max(50),
     email: z.string().email()
   }))
   .rateLimit({ requests: 10, window: 60000 })
   .describe('Create a new user')
   .handler((req, res) => {
     // req.body is fully typed and validated!
     return { success: true, data: req.body };
   });

app.get('/health', () => ({ status: 'healthy' }));

app.listen(3000, () => {
  console.log('Moro server running on http://localhost:3000');
});

Multi-Runtime Support

Deploy the same code everywhere:

// Node.js (default)
import { createApp } from '@morojs/moro';
const app = createApp();
app.listen(3000);

// Vercel Edge Functions
import { createAppEdge } from '@morojs/moro';
const app = createAppEdge();
export default app.getHandler();

// AWS Lambda
import { createAppLambda } from '@morojs/moro';
const app = createAppLambda();
export const handler = app.getHandler();

// Cloudflare Workers
import { createAppWorker } from '@morojs/moro';
const app = createAppWorker();
export default { fetch: app.getHandler() };

What Makes Moro Different?

No More Middleware Order Hell

Traditional frameworks:

// Express - Order matters, easy to break
app.use(cors());           // Must be first
app.use(helmet());         // Must be early
app.use(bodyParser());     // Must be before validation
app.use(rateLimit());      // Must be before routes
app.use(validation());     // Must be before handler
app.post('/users', handler); // Must be last

Moro - Order independent:

// Moro - Framework handles optimal ordering
app.post('/users')
   .body(UserSchema)       // Framework places in validation phase
   .rateLimit({ requests: 10, window: 60000 })  // Rate limit phase
   .auth({ roles: ['user'] })  // Auth phase
   .handler(createUser);   // Always executed last

Universal Validation with Full Type Safety

// Use any validation library - Zod (default)
import { z } from '@morojs/moro';
const UserSchema = z.object({
  name: z.string().min(2).max(50),
  email: z.string().email(),
  age: z.number().min(18).optional()
});

// Or Joi with adapter
import { joi } from '@morojs/moro';
import Joi from 'joi';
const UserSchema = joi(Joi.object({
  name: Joi.string().min(2).max(50).required(),
  email: Joi.string().email().required(),
  age: Joi.number().min(18).optional()
}));

app.post('/users')
   .body(UserSchema)  // Works with any validation library!
   .handler((req, res) => {
     // req.body is fully typed regardless of validation library
     const user = req.body; // ✨ Fully typed
     return { success: true, data: user };
   });

Examples

API Styles

// Chainable API (complex routes)
app.post('/orders')
   .body(OrderSchema)
   .auth({ roles: ['user'] })
   .rateLimit({ requests: 5, window: 60000 })
   .cache({ ttl: 300 })
   .handler(createOrder);

// Schema-first (simple routes)
app.route({
  method: 'GET',
  path: '/users/:id',
  validation: { params: z.object({ id: z.string().uuid() }) },
  handler: getUserById
});

WebSocket Support

Pluggable WebSocket adapters with auto-detection:

import { createApp, SocketIOAdapter, WSAdapter } from '@morojs/moro';

const app = createApp({
  // Auto-detect available WebSocket library
  websocket: { enabled: true },

  // Or use specific adapter
  websocket: { adapter: new SocketIOAdapter() },

  // Or native WebSockets
  websocket: { adapter: new WSAdapter() }
});

// Define WebSocket handlers
app.websocket('/chat', {
  connect: (socket) => {
    console.log(`Client connected: ${socket.id}`);
    socket.join('general');
  },

  message: (socket, data) => {
    socket.to('general').emit('message', {
      user: socket.user,
      text: data.text,
      timestamp: new Date()
    });
  },

  disconnect: (socket) => {
    console.log(`Client disconnected: ${socket.id}`);
  }
});

Authentication & Security

Built-in Auth.js integration with enterprise features:

import { auth, requireAuth, authUtils } from '@morojs/moro/middleware';

// Setup Auth.js with multiple providers
app.use(auth({
  providers: [
    providers.github({
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }),
    providers.google({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  secret: process.env.AUTH_SECRET!,
}));

// Protect routes with role-based access
app.get('/admin/users', withMiddleware(requireAuth({
  roles: ['admin']
}), (req, res) => {
  return { users: getAllUsers() };
}));

// Manual authentication checks
app.get('/profile', (req, res) => {
  if (!authUtils.isAuthenticated(req)) {
    return authResponses.unauthorized(res);
  }

  return {
    user: authUtils.getUser(req),
    permissions: authUtils.getUserPermissions(req)
  };
});

Features:

  • OAuth Providers - GitHub, Google, Microsoft, LinkedIn, Discord
  • Enterprise SSO - Okta, Auth0, AWS Cognito
  • Role-Based Access Control (RBAC) - Fine-grained permissions
  • Native Auth.js Adapter - Zero external dependencies
  • Security Audit Logging - Track authentication events
  • Production Ready - JWT sessions, CSRF protection, secure cookies

Functional Modules

export default defineModule({
  name: 'users',
  routes: [
    {
      method: 'GET',
      path: '/',
      validation: {
        query: z.object({ limit: z.coerce.number().default(10) })
      },
      handler: async (req, res) => {
        return { users: await getUsers(req.query) };
      }
    }
  ]
});

await app.loadModule(UsersModule);

Documentation

Complete Guides

Key Concepts

  • Multi-Runtime Support - Same API works on Node.js, Edge, Lambda, and Workers
  • Intelligent Routing - Automatic middleware ordering eliminates Express.js pain points
  • Enterprise Authentication - Auth.js integration with OAuth, RBAC, and native adapter
  • Universal Validation - Support for any validation library with full type safety
  • WebSocket Flexibility - Choose between Socket.IO, native WebSockets, or auto-detection
  • Functional Architecture - No decorators, pure functions, better performance
  • Type Safety - Universal validation with compile-time and runtime type safety

Why Choose Moro?

Same API everywhere - Write once, deploy to any runtime No middleware dependencies - Framework handles optimal ordering Enterprise authentication - Auth.js integration with native adapter Validation flexibility - Use any validation library (Zod, Joi, Yup, Class Validator) WebSocket choice - Socket.IO, native WebSockets, or auto-detection Full type safety - Universal validation provides end-to-end TypeScript inference Clean APIs - Chainable and schema-first approaches Production ready - Circuit breakers, rate limiting, events, RBAC Performance optimized - Runtime-specific adapters

Contributing

We welcome contributions! See our Contributing Guide for details.

License

MIT © Moro Framework Team


Ready to deploy everywhere with one codebase?

Get StartedGitHubnpmDiscord

About

Moro is a high-performance, type-safe API framework with intelligent routing and multi-runtime support (Node, Edge, Lambda, Workers).

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 98.4%
  • JavaScript 1.6%