npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

express-mod

v1.3.1

Published

express-mod is an open source library for building API (Application programming interface)

Readme

About

express-mod is an open source library for building API (Application programming interface)

express-mod is based on the express framework.

Features ✨

  • OOP and MVC based routing ✔
  • Route validation ✔
  • Error handling and global exception ✔
    • Intercepting server and API crashes.
  • Catch async error on all routes ✔
    • No more trycatch blocks when dealing with async functions.
  • Typescript support out of the box ✔

All these features are included by default, they can save you the time of setting them up from scratch.

👉 Note: some of these features are optional. You can either use or not to use.

express-mod is a production ready and it's lighter than Express itself

  • express-mod aims to make Express more manageable using its decorator APIs
  • express-mod does not modify any functions of express
  • express-mod aims to be fast, lighter, flexible and maintainable
  • Using express-mod with TypeScript is recommended
  • Using express-mod with JavaScript will gain less benifits or consider using express instead

Table of contents

Example

Attention: Using express-mod with TypeScript projects is recommended. If you are using JavaScript see this.

Routing with decorator

./sevice.ts

import { Injectable } from 'express-mod'

@Injectable()
export class ExampleService {
    public helloWorld(): string {
        return 'Hello world!'
    }
}

./api.ts

import { Api, Get } from 'express-mod'
import { ExampleService } from './sevice'

@Api()
export class ExampleApi {
    constructor(private readonly exampleService: ExampleService) {}

    @Get()
    public helloWorld(): string {
        return this.exampleService.helloWorld()
    }
}

./route.ts

import express, { Route } from 'express-mod'
import { ExampleApi } from './api'

@Route([ExampleApi], { router: express.Router() })
export class ExampleRoute {}

Attach and register decorated route

./index.ts

import express, { Router } from 'express-mod'
import http from 'node:http'
import { ExampleRoute } from './route'

// initialize express
const app = express()

// create http server
const server = http.createServer(app)

// router instance
const router = new Router({ initial: app })

// attach and register decorated route.
router.attach('/api/v1', [ExampleRoute])

async function __main__() {
    // TODO: connect to database
    // await connect({ uri: 'DB_URI' })

    // listen for connections
    server.listen(4000, '0.0.0.0', () => console.info(`⚡️ Server is up in ${process.env.NODE_ENV} mode. visit: http://localhost:${process.env.PORT}`))
}

// execute main
__main__()

Installation

You need nodeJs installed on your OS.

# with npm
npm i express-mod

# installing typescript
1. npm i -D typescript
2. npx tsc --init - to create tsconfig.json file

As we all know, the library uses @decorator without enabling some additional features. Typescript will complain. You need to enable these additional features of Typescript. In the file 'tsconfig.json' enable these:

{
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
}

That's it. well done! see more example

Apis

We provide all the Apis that you will need to create a flexible and maintainable application.

@Api

A class-level defined with methods for handling one or more requests.

  • @param url url path.

Example

import { Api } from 'express-mod'

@Api()
export class ExampleApi {}

@Method

A specific endpoint for HTTP requests.

  • @param method http method type.
  • @param url url path.
  • @param status status code.

Possible methods

@Get(), @Post(), @Put(), @Patch(), @Delete()

Example

import { Get } from 'express-mod'

export class ExampleApi {
    @Get() // => "/"
    // or - @Get("/", 200) => "/"
    // or - @Get(200) => "/"
    public helloWorld(): string {
        return 'hello world!'
    }
}

@Middleware

A function which is called before the route handler. there are 2 types of middleware Method-level and API-level

  • @param mids execute any code.

Example

Method-level

import { Middleware } from 'express-mod'

export class ExampleApi {
    @Middleware([
        (req, res, next) => {
            console.log('mid mounted before route bounds.')
            next()
        },
    ])
    public helloWorld(): string {
        return 'hello world!'
    }
}

API-level

import { Middleware } from 'express-mod'

@Middleware([
    (req, res, next) => {
        console.log('mid mounted before all routes bound.')
        next()
    },
])
export class ExampleRoute {}

@Params

A named URL segments that are used to capture the values specified at their position in the URL.

  • @param name string name.

Possible params

@Req(), @Res(), @Next(), @Params(), @Query(), @Body(), @Cookies(), @Headers(), @Ctx()

Example

import { Req, Request, Body } from 'express-mod'

export class ExampleApi {
    public helloWorld(@Req() req: Request, @Body() body: object): string {
        // `req.body` regular use.
        // instead of `req.body` use `@Body()`
        return 'hello world!'
    }
}

@Validation

Validation middleware. A function which is called before the route handler.

  • @param schema schema object.

Supported library: zod

Note: For other libraries beside zod can also be integrated with express-mod, but you just have to set it up yourself.

Example

with zod

import { ValidateRequest, Validation } from 'express-mod'
import z from 'zod'

export class ExampleApi {
    @Validation(z.object<ValidateRequest>({ body: z.object({ name: z.string().max(50) }) }))
    public helloWorld(): string {
        return 'hello world!'
    }
}

@Route

A crucial function use to attach api handlers for the next stage.

  • @param Apis api handlers.
  • @param routeOptions route options.

Example

import express, { Route } from 'express-mod'
import ExampleApi from './api'

@Route([ExampleApi, ...], { router: express.Router() })
export class ExampleRoute {}

@Injectable

The @Injectable() decorator is used to define metadata object.

Example

./service.ts

import { Injectable } from 'express-mod'

@Injectable()
export class ExampleService {
    public username(): string {
        return 'Bob'
    }
}

@Inject

The @Inject() decorator is used to mark parameter as dependency. but usually we don't need to use this we inject one time using @Injectable() at the Service level and we're good to go.

Example

./api.ts

import { Inject } from 'express-mod'
import { ExampleService } from './injectable'

export class Example {
    constructor(
        @Inject(ExampleService) private readonly exampleService: ExampleService,
        // short version:
        private readonly exampleService: ExampleService // this will auto inject without using the @Inject() decorator.
    ) {}

    public getName(): string {
        return exampleService.username()
    } // returns "Bob"
}

@Injector

A top-level class used to resolve injector value.

Example

./injector.ts

import { Injector } from 'express-mod'
import { Example } from './inject'

// resolve Example injector value.
const value = Injector.get(Example)
value.username() // Returns "Bob"

Customize

You can customize some Apis according to your needs.

Middleware

Most come with middleware. It has to be flexible. Sure, we got it!

Example

./mids.ts

import { Middleware, UnauthorizedError } from 'express-mod'

// check if user is logged in.
const Authenticated = () =>
    Middleware([
        (req, res, next) => {
            if (req.isUnAuthenticated()) {
                throw new UnauthorizedError('User unauthorized.')
            }
        },
    ])

// example usage:
export class ExampleApi {
    @Authenticated() // TaaDaa!
    public helloWorld(): string {
        return 'hello world!'
    }
}

Method

In addition to the 5 common http methods @Get(), @Post(), @Put(), @Patch(), @Delete() that we provided, there are some other http methods such as ALL, TRACE, HEAD, OPTIONS, etc. that we didn't provided. you can customize it to your needs.

Example

./custom.method.ts

import { METHOD_DECORATOR_FACTORY, PathParams } from 'express-mod'

// head http method
const Head = (url?: PathParams, status: number = 200) => METHOD_DECORATOR_FACTORY('head', url, status)

// example usage:
export class ExampleApi {
    @Head() // TaaDaa!
    public helloWorld(): string {
        return 'hello world!'
    }
}

Errors & Exceptions

Customize error response

Example

./custom.err.ts

import { CustomError } from 'express-mod'

export class BadRequestError extends CustomError {
    public readonly status = 400
    public readonly error = 'BAD_REQUEST'

    constructor(public readonly message: string) {
        super(message)
        Object.setPrototypeOf(this, BadRequestError.prototype)
    }
}

// example usage:
if (!req.user) throw new BadRequestError('User is not logged in.')

// response
response: { status: 400, error: 'BAD_REQUEST', message: 'User is not logged in.' }

Router

The Router is a top-level class used to attach and register decorated route.

import express, { Router } from 'express-mod'

// initialize express
const app = express()

// router constance
const router = new Router({ initial: app })

// attach and register decorated route.
router.attach('/', [route, ...])

Exception

Api error response message. Use inside the Method-level logic.

  • @param message response message.

Possible errors

CustomError(), UnauthorizedError(), NotFoundError(), ConflictError(), ValidationError(), ForbiddenError()

Example

import { ConflictError } from 'express-mid'

if (user) throw new ConflictError('User is already exist')
// response
response: { status: 409, error: 'CONFLICT', message: 'User is already exist' }

Define injector

The defineInjector function is used to define metadata object.

Example

import { defineInjector } from 'express-mod'

export class Example {}

// define injector
const example = defineInjector(Example)
console.log(example.name) // => 'Example'

Using with Javascript

Attention: Using express-mod with Javascript will gain less benefits. But you can still use it or consider using express instead.

Start the server

To start the server using Javascript (CommonJs) you have to make some changes.

./index.js

// CommonJs
const { expressFn } = require('express-mod') // this would work! ✅
// const express = require('express-mod') this will not work!❌

// or

import { expressFn } from 'express-mod'

// initialize express
const app = expressFn()

// listen for connections
app.listen(4000, () => console.log('Server is up! visit: http://localhost:4000'))

express-mod build everything Api (Application programming interface) lighter, easier and maintainable.