What Happens When You Build a Node.js Backend Framework From Scratch?

1 4
calendar_today agoschedule3 min read

Building a backend framework sounds exciting.

Until you actually start building one.

You quickly discover that routing is probably one of the easiest parts.

The difficult questions come afterward:

How should dependency injection work?

How should middleware execute?

Where should validation happen?

How do you manage application lifecycle?

How should errors propagate?

How do you handle authentication?

How do you expose database access?

How do you build realtime communication?

How do you make everything work together without creating a giant, tightly coupled codebase?

These are some of the problems I've been working through while building StreetJS.

The architecture matters more than the decorators

When people see a TypeScript framework, they often notice decorators first:

@Controller('/users')
export class UserController {
  @Get('/')
  async getUsers() {
    // ...
  }
}

But the decorator isn't the interesting part.

The interesting part is what happens after the decorator is evaluated.

StreetJS has to turn application declarations into runtime behavior.

That means the framework needs systems for:

  • Application bootstrapping
  • Dependency injection
  • Routing
  • Middleware
  • Request lifecycle
  • Error handling
  • Validation
  • Configuration
  • Database access
  • Authentication
  • Observability

The challenge is making these systems work together without making application code depend on every internal implementation detail.

I wanted infrastructure to be predictable

A backend framework should make it obvious where something belongs.

For example:

Controller

Handles HTTP interaction.

Service

Contains application/business logic.

Repository

Handles persistence.

Middleware

Handles cross-cutting request behavior.

Module

Organizes related functionality.

This isn't a revolutionary architecture.

That's intentional.

Developers don't need an architecture that looks clever.

They need an architecture that remains understandable six months later.

Runtime validation is important

TypeScript gives us excellent developer-time safety.

But TypeScript types disappear at runtime.

An API can receive:

{
  "name": 123,
  "email": true
}

even if your TypeScript interface says:

interface CreateUser {
  name: string;
  email: string;
}

That's why StreetJS treats runtime validation as a separate concern.

The server shouldn't trust incoming data simply because the TypeScript compiler was happy with your code.

The boundary of your application needs validation.

The database shouldn't dictate your application architecture

Another area I've spent considerable time thinking about is database access.

For a real backend, you eventually need things like:

  • Transactions
  • Connection management
  • Migrations
  • Query execution
  • Repository patterns
  • Error handling
  • PostgreSQL support

But your controller shouldn't become a giant collection of SQL queries.

For example, I'd rather see:

const user = await userService.create(input);

than:

const result = await db.query(
  'INSERT INTO users ...'
);

inside an HTTP controller.

The framework should make the clean approach easier.

Realtime changes the architecture

REST APIs are only one part of modern applications.

Consider a:

  • Chat application
  • Delivery platform
  • Trading dashboard
  • Collaboration tool
  • Notification system
  • Multiplayer application

These applications need realtime communication.

That's why StreetJS includes WebSocket and SSE capabilities.

The goal is to make realtime communication part of the backend architecture rather than something developers bolt on at the very end.

Observability shouldn't be an afterthought

A backend that works on your laptop is easy.

A backend running in production at 2 AM is different.

You need to know:

  • Is the application healthy?
  • How long are requests taking?
  • Which endpoints are failing?
  • Are dependencies responding?
  • Are errors increasing?
  • Is the application running out of resources?

StreetJS includes health checks, metrics and telemetry capabilities because production software needs visibility.

Building a framework teaches you something unexpected

The biggest lesson I've learned so far is this:

A framework isn't primarily about features. It's about boundaries.

Every feature you add creates another architectural question.

Where does it live?

Who owns it?

What does it depend on?

What depends on it?

What happens when it fails?

Can developers replace it?

Can it be tested independently?

Can it evolve without breaking everything else?

Those questions are much harder than writing the feature itself.

StreetJS is still evolving

StreetJS is an open-source project, and I'm continuing to improve its architecture, documentation, developer experience and ecosystem.

I'm particularly interested in feedback from developers who have built serious Node.js backends.

If you were designing a backend framework today:

What would you do differently from existing frameworks?

And more importantly:

What should a modern TypeScript backend framework absolutely get right?

I'd love to hear your thoughts.

GitHub: https://github.com/hassanmubiru/StreetJS

Documentation: https://hassanmubiru.github.io/StreetJS/

npm: https://www.npmjs.com/package/streetjs

2 Comments

1 vote
0 votes
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelski - Apr 23

Merancang Backend Bisnis ISP: API Pelanggan, Paket Internet, Invoice, dan Tiket Support

Masbadar - Mar 13

Cisco's Amy Chang: A Model's "Passport" Doesn't Tell You Where It Actually Came From

Tom Smithverified - Aug 27

The Sovereign Vault — A Comprehensive Guide to Protocol-Driven AI

Ken W. Algerverified - Jun 4

I Wrote a Script to Fix Audible's Unreadable PDF Filenames

snapsynapseverified - Apr 20
chevron_left
194 Points5 Badges
Kenyateeb.com
3Posts
0Comments
1Connections
Am kotlin and flutter Developer

Related Jobs

View all jobs →

Commenters (This Week)

3 comments
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!