diff --git a/docs/reference/aop/handler-aspect.svg b/docs/reference/aop/handler-aspect.svg
new file mode 100644
index 0000000000..596ebf2d6d
--- /dev/null
+++ b/docs/reference/aop/handler-aspect.svg
@@ -0,0 +1,249 @@
+
+
+
+
\ No newline at end of file
diff --git a/docs/reference/aop/handler_aspect.md b/docs/reference/aop/handler_aspect.md
index bed8cd66bf..a31e9f42f8 100644
--- a/docs/reference/aop/handler_aspect.md
+++ b/docs/reference/aop/handler_aspect.md
@@ -9,6 +9,14 @@ A `HandlerAspect` is a wrapper around `ProtocolStack` with the two following fea
- It is specialized to work with an output context `CtxOut` that can be passed through the middleware stack. This allows each layer to add its output context to the transformation process. So the `CtxOut` will be a tuple of all the output contexts that each layer in the stack has added. These output contexts are useful when we are writing middleware that needs to pass some information, which is the result of some computation based on the input request, to the handler that is at the end of the middleware stack.
+The diagram below illustrates how `HandlerAspect` works:
+
+
+
Now, we are ready to see the definition of `HandlerAspect`:
```scala
diff --git a/docs/reference/aop/middleware.md b/docs/reference/aop/middleware.md
index b22ce59445..50fd26cbcc 100644
--- a/docs/reference/aop/middleware.md
+++ b/docs/reference/aop/middleware.md
@@ -17,6 +17,14 @@ trait Middleware[-UpperEnv] { self =>
This abstraction allows middleware to engage with the `Routes` environment, and also the ability to tweak existing routes or add/remove routes as needed.
+The diagram below illustrates how `Middleware` works:
+
+
+
+![Middleware Diagram](middleware.svg)
+
+
+
## Usage
The `@@` operator attaches middleware to routes and HTTP applications. The example below shows a middleware attached to an `Routes`:
diff --git a/docs/reference/aop/middleware.svg b/docs/reference/aop/middleware.svg
new file mode 100644
index 0000000000..a16841a716
--- /dev/null
+++ b/docs/reference/aop/middleware.svg
@@ -0,0 +1,244 @@
+
+
+
+
\ No newline at end of file
diff --git a/docs/reference/aop/multiple-protocol-stack.svg b/docs/reference/aop/multiple-protocol-stack.svg
new file mode 100644
index 0000000000..269918a20c
--- /dev/null
+++ b/docs/reference/aop/multiple-protocol-stack.svg
@@ -0,0 +1,194 @@
+
+
+
+
\ No newline at end of file
diff --git a/docs/reference/aop/protocol-stack.md b/docs/reference/aop/protocol-stack.md
index cb92757524..e57bede3db 100644
--- a/docs/reference/aop/protocol-stack.md
+++ b/docs/reference/aop/protocol-stack.md
@@ -27,12 +27,35 @@ The `ProtocolStack` data type has 5 type parameters, one for the ZIO environment
- **Incoming Output**: This refers to the data leaving the middleware and heading towards the server or the next middleware in the chain. This could include modified request data or additional metadata added by the middleware.
-**Outgoing Input**: This refers to data coming into the middleware from the handler or the previous middleware in the chain. It typically includes the HTTP response from the server, including headers, status codes, and the response body.
+- **Outgoing Input**: This refers to data coming into the middleware from the handler or the previous middleware in the chain. It typically includes the HTTP response from the server, including headers, status codes, and the response body.
-**Outgoing Output**: This refers to data leaving the middleware and heading back to the client. It could include modified response data, additional headers, or any other transformations applied by the middleware.
+- **Outgoing Output**: This refers to data leaving the middleware and heading back to the client. It could include modified response data, additional headers, or any other transformations applied by the middleware.
A `ProtocolStack` can be created by combining multiple middleware functions using the `++` operator. Using the `++` operator, we can stack multiple middleware functions on top of each other to create a composite middleware that applies each middleware in the order they are stacked.
+The diagram below illustrates how `ProtocolStack` works:
+
+
+
+Here is the flow of data through the `ProtocolStack`:
+
+1. The incoming input `II` is transformed by the first layer of the protocol stack to produce the incoming output `IO`.
+2. The incoming output `IO` is passed to the next layer of the protocol stack (if exists) to produce a new incoming output. This process continues until all layers have been applied.
+3. The incoming output `IO` is passed to the handler, which is the last layer where the actual processing of the request takes place. The handler processes the incoming output and produces the outgoing input `OI`.
+4. The outgoing input `OI` is passed to the last layer of the protocol stack to produce the outgoing output `OO`.
+5. The outgoing output `OO` is passed to the previous layer of the protocol stack (if exists) to produce a new outgoing output. This process continues until all layers have been applied.
+6. The outgoing output `OO` is returned as the final result of the protocol stack.
+
+
+
## Creating a ProtocolStack
There are several ways to create a `ProtocolStack`. One simple way is to start with an `identity` stack, which is a protocol stack that does nothing and simply passes the inputs to the outputs unchanged. Then, we can modify it by mapping over the inputs and outputs to apply transformations:
diff --git a/docs/reference/aop/protocol-stack.svg b/docs/reference/aop/protocol-stack.svg
new file mode 100644
index 0000000000..46acbc1ab0
--- /dev/null
+++ b/docs/reference/aop/protocol-stack.svg
@@ -0,0 +1,254 @@
+
+
+
+
\ No newline at end of file