Ditsmod - new NodeJS webframework writen in TypeScript

If you look through the search results on github for the keyword nodejs-framework (with only TypeScript projects selected), you can see that there are currently about 5 different frameworks designed to create applications that process HTTP requests on the server side.

So why create yet another similar framework? Well, let's see what I, as the author of Ditsmod, can offer you:

  1. Ditsmod doesn't have ExpressJS or any other similar framework under the hood, so it's not complicated by backward compatibility with legacy packages, which makes Ditsmod a more consistent API.
  2. For Ditsmod, modularity is a top priority, so each of its modules can easily migrate to microservices in the future when the need to scale to several separate servers arises. Other frameworks do not have the concept of modularity at all, or their modularity is not as clear as Ditsmod's.
  3. Ditsmod has a powerful Dependency Injection, which allows you to create hierarchical relationships between different injectors (aka IoC containers). At the same time, it boasts high speed and memory efficiency.
  4. Thanks to Dependency Injection, you can override the native classes of the logger, error handler, and any other service. This also helps when writing tests.
  5. If you compare different Node.js frameworks in terms of speed, Ditsmod is one of the fastest (after fastify, koa, and restify). And if we take only those frameworks that have Dependency Injection, I assume that the results will be even better.
  6. Ditsmod has a system of extensions (or plugins), which not all frameworks have.

Of course, these are the most basic differences of this framework. You can read more information on the official website.

Components of Ditsmod applications

Despite the fact that Ditsmod is a new framework, its applications can have a rich structure thanks to such components as:

  • modules;
  • controllers;
  • services;
  • HTTP interceptors;
  • guards;
  • extensions.

This framework relies heavily on decorators, which declaratively describe what needs to be done. Even if you've never seen this kind of programming in TypeScript code before, you can guess what's going on here:

import { controller, route, Res } from '@ditsmod/core';

import { FirstService } from './first.service';

@controller()
export class HelloWorldController {
  @route('GET', 'hello')
  method1(res: Res, firstService: FirstService) {
    res.send(firstService.sayHello());
  }
}

This example declares a controller with a single route that accepts GET requests that have the path /hello. It is worth noting here that Dependency Injection is responsible for passing parameters to method1().

Dependency resolution for services is also handled by Dependency Injection, but in services, most often, dependencies are specified in constructors:

import { injectable } from '@ditsmod/core';

import { FirstService } from './first.service';

@injectable()
export class SecondService {
  constructor(private firstService: FirstService) {}

  methodOne() {
    this.firstService.doSomeThing();
  }
}

Those users who are familiar with other TypeScript frameworks may have seen many similar concepts in NestJS. The fact is that both NestJS and Ditsmod were heavily inspired by Angular, which is why there are some external similarities between them. At the same time, there are plenty of differences between them. For example, they differ greatly in the hierarchy of injectors (aka IoC containers). Ditsmod currently (v2.38) has four static hierarchy levels:

  1. Application level;
  2. Module level;
  3. Route level;
  4. HTTP request level.

While NestJS v10.0 has one injector at the application level, the other is at the HTTP request level. This feature has a significant impact on building a modular application architecture.

There are also significant differences between NestJS and Ditsmod in terms of interceptors and guards, as in NestJS they are so-called "enhancers", so they cannot be exported and imported like regular providers, which degrades the modularity of NestJS applications. In Ditsmod, it's easier with interceptors and guards because they are regular providers.

Ditsmod also compares favorably with NestJS in that it has much better support for nested routes and the ability to write extensions (aka plugins).

Native Ditsmod modules

At the moment (v2.38), Ditsmod has the following native modules:

Examples from the RealWorld

You can also see examples with RealWorld implementation. The specification itself can be found on the official website:

While most "todo" demos provide an excellent cursory glance at a framework's capabilities, they typically don't convey the knowledge & perspective required to actually build real applications with it.RealWorld solves this by allowing you to choose any frontend (React, Angular, & more) and any backend (Node, Django, & more) and see how they power a real world, beautifully designed fullstack app called Conduit.