# Building a Mini Express from Scratch

## **1\. Why Build Express From Scratch?**

Ever wondered what's actually happening under the hood when you type `app.get()`? Express feels like magic because it is abstraction done right. It hides the messy parts of handling HTTP requests so we can focus on shipping.

Building a mini Express teaches what frameworks actually do. You'll understand routing, middleware chains, and why abstraction layers matter. Think of it this way a framework is just structured orchestration sitting on top of `http.createServer`.

## 2**. Designing the Mini Framework API**

```javascript
const app = miniExpress();

app.get("/users", (req, res) => { res.send("Users"); });

app.listen(3000);
```

We're building an abstraction layer that feels like Express, our own mini express.

## **3\. Routing System**

The router is just a registry that matches incoming requests to handlers -

```javascript
const routes = [];

app.get = (path, handler) => {
  routes.push({ method: "GET", path, handler });
};

// when the request comes in 

const match = routes.find(
  r => r.method === req.method && r.path === req.url
);
```

Simple O(n) lookup. Express uses fancy trie structures for speed. For learning purposes, a loop works fine. The concept match method and path, then execute is what matters.

## 4\. Middleware System

This is where things get interesting. Middleware is just a function that runs before your route handler, with the power to continue or stop the chain.

```javascript
const middlewares = [];

app.use = (fn) => {
  middlewares.push(fn);
};

//
//
//

let i = 0;

function next() {
  const middleware = middlewares[i++];
  if (middleware) {
    middleware(req, res, next);
  }
}
```

Each middleware calls `next()` to pass control to the next one. This creates a linear execution chain where any middleware can modify the request, send a response early, or pass it along. It's control flow inversion, instead of you calling functions, the framework calls you and asks "what next?"

## **5\. Enhancing responses (res)**

```javascript
res.send = (data) => {
  res.setHeader("Content-Type", "application/json");
  res.end(JSON.stringify(data));
};
```

Frameworks enhance primitives. We can add anything in our mini express. i.e. res.json, res.status, whatever solves our purpose.

## **6\. Order of Execution**

```javascript
app.use(authMiddleware);
app.get("/profile", handler);
```

The auth check runs first. If it fails, the profile handler never sees the request. Route matching typically happens after global middleware. That's a design decision Express made, and it affects how you structure apps. Order is architecture.

## **7\. Handling 404 and Fallback**

What happens when no route matches? Lets see what can we do here

```javascript
if (!match) {
  res.statusCode = 404;
  res.end("Not Found");
}
```

Express has a default 404 handler, but in production we usually override it. Defining fallback behavior is part of framework design.

## **8\. Handling Errors**

```javascript
if (err) {
  errorHandler(err, req, res);
}
```

Error middleware takes four arguments `(err, req, res, next)` and centralizes failure handling. Instead of try-catch blocks scattered everywhere, you bring all errors to one place.

## **9\. Comparing to Real Express Internals**

Oue mini express works, but real Express has more moving parts. It uses the `connect` middleware engine internally, with a `Layer` abstraction that wraps each middleware. The `Router` object handles nested routes and params.

## **10\. Production Limitations of Your Mini Framework**

Here are somethings that we did’nt really touch upon in this one, you try some of them on your own, it would be a fun ride

* **No async error handling** try-catch won't catch errors in async middleware
    
* **No route params** `/users/:id` won't work, just exact matches
    
* **No body parsing** `req.body` is undefined; you'd need to stream and parse
    
* **No query parsing** `?foo=bar` stays a string
    
* **No performance optimization** that O(n) route lookup breaks at scale
    
* **No security hardening** no helmet, no cors, no protection
    

My only goal with this one was to convey that frameworks aren’t magic, Its just someone’s organized code, and express has really organised our way of writing code.
