DEV Community

Cover image for A first project with ExpressoTS
Daniel Boll for ExpressoTS

Posted on

A first project with ExpressoTS

Introduction

ExpressoTS is a new developer-friendly TypeScript framework for Server-Side Applications. It's currently built on top of Express, easy to get a new developer on board, light and easy project structure, two different project structure supported (opinionated and non opinionated version), supports MVC, non MVC, architecture. The opinionated template was built on top of clean architecture, you will see concepts embedded in the opinionated template such as entities, useCases, repositories and providers.

Setting Up Your First ExpressoTS Project

Ah, the first step to any great journey in the world of coding—a proper setup. Trust me, nobody wants to get lost before even starting the adventure. So, let's cut the chit-chat and dive right in.

Installation of ExpressoTS CLI

You've got two routes here, and the destination is the same, a functional ExpressoTS environment. Your first option is to install the ExpressoTS CLI globally:

pnpm i -g @expressots/cli
Enter fullscreen mode Exit fullscreen mode

Got limited commitment issues? No worries, you can also use dlx to run the CLI without installing it globally. Ah, the wonders of a one-night stand with a CLI!

pnpx @expressots/cli new expressots-first-project
Enter fullscreen mode Exit fullscreen mode

Configuration Wizard

After running the command, you're greeted by a friendly (albeit text-based) wizard 🧙‍♂️.

[🐎 Expressots]

? Project name expressots-first-project
? Package manager pnpm
? Select a template Non-Opinionated :: A simple ExpressoTS project.
? Do you want to create this project? Yes
Enter fullscreen mode Exit fullscreen mode

Fill out the form wisely but don't overthink it. For this tutorial, I'm going with the "Non-Opinionated" template because, it will give us a shallower learning curve in the start.

Getting Comfy in Your New ExpressoTS Home 🏡

Navigating to Your Project

So you've set up your new ExpressoTS project. Awesome! Time to get inside the engine room and take a look under the hood.

cd expressots-first-project
Enter fullscreen mode Exit fullscreen mode

You're now in the root folder, and if you're curious about what comes packed by default, run a quick tree command.

@expressots/tests/expressots-first-project via  v16.19.0
❯ tree -I node_modules -a
.
├── .eslintrc.js
├── expressots.config.ts
├── .gitignore
├── jest.config.ts
├── package.json
├── pnpm-lock.yaml
├── .prettierrc
├── README.md
├── src
│   ├── app.container.ts
│   ├── app.controller.ts
│   ├── app.module.ts
│   ├── app.usecase.ts
│   └── main.ts
├── test
│   └── app.usecase.spec.ts
├── tsconfig.build.json
└── tsconfig.json

3 directories, 16 files
Enter fullscreen mode Exit fullscreen mode

There you go! These are the files you'll be living with.

Customizing Your Prettier Preferences

You've got your own coding style—don't we all? You can tweak the .prettierrc file to your heart's content.

{
  "singleQuote": false,
  "trailingComma": "all",
  "endOfLine": "auto",
  "tabWidth": 2
}
Enter fullscreen mode Exit fullscreen mode

Let's Take a Quick Tour of package.json

A glance at the scripts section in package.json tells you all you need to know to get things up and running.

cat package.json | jq ".scripts"
{
  "prebuild": "rm -rf ./dist",
  "build": "tsc -p tsconfig.build.json",
  "dev": "tsnd ./src/main.ts",
  "prod": "node ./dist/main.js",
  "test": "jest",
  "test:watch": "jest --watchAll",
  "test:cov": "jest --coverage",
  "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
  "lint": "eslint \"src/**/*.ts\" --fix"
}
Enter fullscreen mode Exit fullscreen mode

Here, you've got your usual suspects: build, dev, test, and more.

Format All The Things!

Before diving into development, let's keep it neat. The format script will handle that.

pnpm format
Enter fullscreen mode Exit fullscreen mode

Running in Dev Mode

And finally, the moment you've been waiting for—fire up the dev server and see your app come to life!

@expressots/tests/expressots-first-project via  v16.19.0
❯ pnpm dev

[INFO] ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.1, typescript ver. 4.9.5)
Application version not provided is running on port 3000 - Environment: development
Enter fullscreen mode Exit fullscreen mode

Making Your First Request in ExpressoTS 🌐

Time for a Little Hello!

You've been through the house tour, you've feng shui'd your .prettierrc and got your scripts all figured out. Now what? Well, how about actually seeing your app in action?

Using HTTPie for Your First GET Request

For this demonstration, we're going to use HTTPie — the cURL for the 21st century. But like, way more readable. Here's how to send your first GET request to http://localhost:3000.

@expressots/tests/expressots-first-project via  v16.19.0
❯ http :3000
Enter fullscreen mode Exit fullscreen mode

Bam! You should see a response like:

HTTP/1.1 200 OK
...
Hello Expresso TS!
Enter fullscreen mode Exit fullscreen mode

Congrats! You just made your server say hello.

Anatomy of the "Hello Expresso TS!" 🦴

Alright, let's dissect that "Hello Expresso TS!" message. How does this simple string pass through layers of TypeScript files to make it to your browser? Spoiler: It's not magic; it's just well-structured code.

The Starting Point: src/main.ts

This is where the baton is picked up. Here, we import the essential parts from ExpressoTS and set up the initial application instance. Simple enough.

import "reflect-metadata";
import { AppInstance, ServerEnvironment } from "@expressots/core";
import { container } from "./app.container";

async function bootstrap() {
  AppInstance.create(container);
  AppInstance.listen(3000, ServerEnvironment.Development);
}

bootstrap();
Enter fullscreen mode Exit fullscreen mode

The Container: src/app.container.ts

Think of this as the backstage, where everyone gets ready for the show. It's where the application container is configured with your custom modules.

import { AppContainer } from "@expressots/core";
import { AppModule } from "./app.module";

const appContainer = new AppContainer();
const container = appContainer.create([AppModule]);

export { container };
Enter fullscreen mode Exit fullscreen mode

The Module: src/app.module.ts

Modules in ExpressoTS group related functionalities. Here, it's as simple as importing the AppController.

import { CreateModule } from "@expressots/core";
import { AppController } from "./app.controller";

const AppModule = CreateModule([AppController]);

export { AppModule };
Enter fullscreen mode Exit fullscreen mode

The Controller: src/app.controller.ts

This is the conductor of our orchestra. It's responsible for handling HTTP requests and directing traffic. In this case, it's just saying, "Hello Expresso TS!".

import { BaseController, controller, httpGet, response } from "inversify-express-utils";
import { Response } from "express";
import { AppUseCase } from "./app.usecase";

@controller("/")
class AppController extends BaseController {
  constructor(private appUseCase: AppUseCase) {
    super("app-controller");
  }

  @httpGet("/")
  execute(@response() res: Response) {
    return res.send(this.appUseCase.execute());
  }
}
Enter fullscreen mode Exit fullscreen mode

The Use Case: src/app.usecase.ts

Here's where the actual "Hello Expresso TS!" lives.

import { provide } from "inversify-binding-decorators";

@provide(AppUseCase)
class AppUseCase {
  execute() {
    return "Hello Expresso TS!";
  }
}
Enter fullscreen mode Exit fullscreen mode

"Hello, Who?" Changing the Default Response 🖊️

Got bored of the usual "Hello Expresso TS!"? Let's give it a personal touch. To do that, we only need to venture into the src/app.usecase.ts file. See, this is the beauty of a well-structured codebase; you don't have to jump through hoops to make a simple change.

The Tweak: src/app.usecase.ts

One line change. That's it. Here we just swap out the text to "Hello from <Daniel::Boll>".

@provide(AppUseCase)
class AppUseCase {
  execute() {
    return "Hello from <Daniel::Boll>";
  }
}
Enter fullscreen mode Exit fullscreen mode

The Reload: Auto-refresh FTW

As soon as you save that change, the development server detects this update and reloads itself. No manual effort required. Ah, the joys of modern development.

[INFO] Restarting: /../@expressots/tests/expressots-first-project/src/app.usecase.ts has been modified
Application version not provided is running on port 3000 - Environment: development
Enter fullscreen mode Exit fullscreen mode

The Result: Let's Talk to the Server Again

Run the command, and voila! The updated greeting is now served hot, right from your server.

Hello from <Daniel::Boll>
Enter fullscreen mode Exit fullscreen mode

Dive deeper

If you are interested in more stuff you can do in this simple ExpressoTS project make sure to check out the full blog at daniel-boll.me.

Latest comments (33)

Collapse
 
f0ntana profile image
Felipe Fontana

ExpressoTS truly stands out as a remarkable framework, boasting an impressive array of cutting-edge features. Its capabilities are simply top-notch!

Collapse
 
shaijut profile image
Shaiju T

Nice , I appreciate your efforts, This tool is good for many uses. But I have a advice for new backend developers who are just using Javascript for everything. I know node is successfull in backend for many use cases. But blindly using Javascript for all projects is not good for now. Is it scalable and secure like Java, C# ? For new developers who are doing backend development, kindly try Java , C# or Golang for building APIs and then decide whether using Javascript in backend for your project is good decision or not. Instead of using one tool for all, Kindly explore different tools and use the best tool for the Job.

Collapse
 
msamgan profile image
Mohammed Samgan Khan

This is a nice project and a good resource if you want to go for a full server-side application. However, when it comes to just APIs it feels like a bit overkill. I myself am working on a lightweight framework focusing on getting the job done efficiently and effortlessly. No flashy gimmicks, just pure development bliss. You can check it out here.

github.com/3rd-planet/framework-x

feel free to give feedback, all and any feedback is most welcome.

Collapse
 
clabnet profile image
Claudio Barca

Nice solution.
How about Openapi3 and Swagger Api documentation ?

Collapse
 
rsaz profile image
Richard Zampieri ExpressoTS

Hi @clabnet

You're spot on—discussions about AI models and documentation are definitely on our radar for the near future. Right now, our focus is on establishing a solid foundation that enables people to build applications both easily and securely, without compromising on performance. Rest assured, we'll circle back to these important topics soon. If you have any suggestions, we'd love to hear them! Feel free to share your thoughts on our Ideas community board: github.com/expressots/expressots/i....

Collapse
 
malpaso profile image
Bill Tindal

Try @adonisframework instead

Collapse
 
malpaso profile image
Bill Tindal

@adonisframework is way ahead. Why build a framework on an old base?

Collapse
 
krtirtho profile image
Kingkor Roy Tirtho

Wait a sec. Isn't it just another NestJS clone?
The same modules, controllers, providers, usecases (fancy word for Nestjs Middlewares) & of course decorators

I love the what NestJS does. But what is the point of straight up copying a framework? This doesn't bring any uniqueness to this project at all

Even the logo of the project is another ripoff of NestJS's logo. A horse instead of a cat/tiger

Ah this is just disappointing 😔

Collapse
 
indexofmayank profile image
Mayank Tiwari

True

Collapse
 
jak2k profile image
Jak2k

Too much boilerplate...

Collapse
 
rsaz profile image
Richard Zampieri ExpressoTS • Edited

Opinionated Template accelerate the development yes by adding reusable code, what you call boilerplate.
Non-opinionated Template you do everything from scratch but still make use of @expressots/core library

The question is, which company has time to wait for you to build the whole infrastructure of an application from scratch? To answer this question frameworks exists. SpringBoot in Java, .Net Core, Laravel - Code Ignite- PHP, Flask and django for Python and so ExpressoTS.

The problem is not to have or have boilerplate, the problem is choosing the right tool to the job you gonna be performing. In Typescript world you do have a few options such as ExpressoTS, Nestjs, AdonisJs, Hapi, Koa, and I can keep going on and on.

Be prepared to adapt and being able to switch technology fast, that's the world we live in! :)

Collapse
 
jak2k profile image
Jak2k • Edited

I want use frameworks, but then I use the original (Nest) and not it's copy.

Thread Thread
 
rsaz profile image
Richard Zampieri ExpressoTS

Fair enough. You're too passionate about a tool in order for us to have this conversation, and for you to see the differences. ExpressoTS is not heavily inspired in Angular, neither in Nest. If you have worked with C# or Java Spring Boot you will see more similarities with them. And perhaps you will find another interesting conclusion, that maybe Angular has copied Java and C# annotation ideas and the DI container, and how the application startUp a project. :)

What I really recommend folks to do is a proper assessment to really make sure you got the project philosophy, what problem its trying to solve and how its trying to solve. Go there and try to understand why there are more than 20 direct contributors to this project called ExpressoTS. We maybe can find a gem.
Maybe ExpressoTS will call your attention years from now, who knows.

Have a good weekend.

Collapse
 
artenlf profile image
Luís Felipe Arten

Very cool! Definitely trying it on future projects!

Collapse
 
phenriquesousa profile image
Pedro Henrique

Heart community passing by! :)