DEV Community

Cover image for Sequence Diagrams in Markdown with Mermaid.js
Matt Eland
Matt Eland Subscriber

Posted on • Originally published at newdevsguide.com

Sequence Diagrams in Markdown with Mermaid.js

I've been really enjoying seeing how Mermaid.js lets you generate technical diagrams from simple markdown. Previously I've shown how Mermaid.js allows you to create entity relationship diagrams and class diagrams, but in this article we'll cover a far more complex diagram: the sequence diagram.

I distinctly remember working on sequence diagrams in my undergraduate computer science education and having so many issues trying to get the various boxes and arrows to look standard, rearrange shapes as I needed to expand the diagram, and generally focusing on anything but the logic the diagrams intended to create.

Mermaid.js is the solution I needed 20 years ago.

With Mermaid.js you can write a few lines of text and use its JavaScript library to generate a professional sequence diagram like the one below:

A Sequence Diagram

This means your time is focused on actually writing the interaction logic instead of generating a visual. It also means that the diagram source is easily version-controlled and anyone on your team can modify it without special tooling or licenses.

Mermaid.js is available in a variety of tools, but I most frequently use it in GitHub markdown files and in Polyglot Notebooks.

What are Sequence Diagrams?

For those of you who haven't been exposed, sequence diagrams describe a series of messages in a sequence between different objects.

Sequence diagrams represent systems and individuals as vertical columns and messages between these parts as horizontal lines that move across the various lanes to show how data flows between different pieces of the system.

This can help explain complex logic and interactions with a technical diagram and identify areas of confusion or misunderstanding.

If you're curious about sequence diagrams in general, a good starting point might be Visual Paradigm's Guide to Sequence Diagrams.

Over the course of this article, we'll create and expand a sequence diagram to explain JSON Web Token (JWT) authentication. However, the focus of the article's text will be on the diagrams themselves, not the process of JWT authentication. If you're curious about this, however, I do have an article and video on understanding JWT authentication.

Basic Sequence Diagrams

Let's start with a simple sequence diagram representing a message from the client to the server and the server's response back.

sequenceDiagram
    Client->>Server: Login (Username, Password)
    Server-->>Client: 200 OK & JWT
Enter fullscreen mode Exit fullscreen mode

Simple Sequence Diagram

Here we start by specifying that the Mermaid diagram we want to use is a sequence diagram.

Next, we declare a message from a Client to the Server. The ->> arrow indicates that the message is intended to be synchronous. The value after the : describes the contents of the message.

Note: for asynchronous messages you would indicate them with -). This will not appear in the examples in this article

The -->> arrow (note the two dashes instead of one) indicates a dotted line return value


Now that we've seen a simple message between two systems, let's show the database's role in fulfilling the request:

sequenceDiagram
    Client->>Server: Login (Username, Password)
    Server->>Database: Select User Info
    Database-->>Server: Salt & Hash
    Server-->>Client: 200 OK & JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

Here by adding the Database node and illustrating the message was sent from the server to the database, our diagram automatically expands.

Also note that systems appear in the order in which they're first mentioned, with the first system on the left and the last being at the right.

Aliases and Actors

Because typing Client and Server can get tedious, Mermaid.js gives us a way of creating aliases for our systems by declaring them at the top of the sequenceDiagram block.

This also gives us an opportunity to tweak the order of the systems shown, if we wanted to swap the order of the Database and Server, for example:

sequenceDiagram
    participant C as Client
    participant DB as Database
    participant S as Server
    C->>S: Login (Username, Password)
    S->>DB: Select User Info
    DB-->>S: Salt & Hash
    S-->>C: 200 OK & JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

Here C, S, and DB are all aliases used in the actual message lines while their full names still show up in the generated diagram.

If you wanted to indicate that a system is actually an actor (typically something involving a human user), you can use the word actor instead of participant and the diagram will update.

sequenceDiagram
    actor C as Client
    participant S as Server
    participant DB as Database
    C->>S: Login (Username, Password)
    S->>DB: Select User Info
    DB-->>S: Salt & Hash
    S-->>C: 200 OK & JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

Notes and Sequence Numbers


Often you'll want to annotate your diagrams with notes.

Notes allow you to show the reader helpful text and can be placed over a single system or over two different systems using the note syntax:

sequenceDiagram
    actor C as Client
    participant S as Server
    participant DB as Database
    C->>S: Login (Username, Password)
    S->>DB: Select User Info
    note over DB: Password is not stored in database
    DB-->>S: Salt & Hash
    S-->>C: 200 OK & JWT
    note over C, S: Subsequent requests include JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

The placement of notes does matter and trying a few different approaches when using notes may be necessary to get the effect you're looking for.


It can be helpful to include sequence numbers in your diagram. This aids in verbal communication and helps novice sequence diagram readers understand the sequence you're trying to communicate.

Adding numbers is as simple as adding the autonumber line to the beginning of your sequenceDiagram in Mermaid.

sequenceDiagram
    autonumber
    actor C as Client
    participant S as Server
    participant DB as Database
    C->>S: Login (Username, Password)
    S->>DB: Select User Info
    note over DB: Password is not stored in database
    DB-->>S: Salt & Hash
    S-->>C: 200 OK & JWT
    note over C, S: Subsequent requests include JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

Note: despite the name autonumber, I've not seen a way of manually assigning sequence numbers (not that I'd want to: autonumber works great!)

Self-Referential Messaging

Sometimes you want to indicate logic that goes on inside of a system.

For example, the server is responsible for verifying the user's login credentials and generating a JWT. These are both complex operations that should be represented on the diagram, yet do not involve other systems.

In cases like this, you can indicate that a system communicates with itself or does something computationally complex by adding a message from the system to itself as shown below:

sequenceDiagram
    autonumber
    actor C as Client
    participant S as Server
    participant DB as Database
    C->>S: Login (Username, Password)
    S->>DB: Select User Info
    note over DB: Password is not stored in database
    DB-->>S: Salt & Hash
    S->>S: Check Computed Hash using Salt
    S->>S: Generate JWT
    S-->>C: 200 OK & JWT
    note over C, S: Subsequent requests include JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

If / Else with Alt Blocks

The sequence diagram is coming along nicely and now shows us the "happy path" of our system where nothing went wrong.

However, sometimes you need to be able to illustrate more complex logic such as if statements, loops, error handling, or other special cases.

Mermaid.js gives us different syntax for special blocks, but the code below will use the alt and else keywords to illustrate what happens when a user gives valid credentials and invalid credentials:

sequenceDiagram
    autonumber
    actor C as Client
    participant S as Server
    participant DB as Database
    C->>S: Login (Username, Password)
    S->>DB: Select User Info
    note over DB: Password is not stored in database
    DB-->>S: Salt & Hash
    S->>S: Check Computed Hash using Salt
    alt Computed Hash Matches
        S->>S: Generate JWT
        S-->>C: 200 OK & JWT
    else No user or wrong password
        S-->>C: 401 Unauthorized
    end
    note over C, S: Subsequent requests include JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

Here alt is equivalent to an if statement in programming while else and end are generally understandable to various concepts in conditional logic.

Also note that I am using indentation to help clarify statements as part of the alt or else blocks. This indentation is optional, but significantly helps readability in my experience.

Indicating Activation

Finally, our sequence diagram is missing one thing common to the UML Sequence Diagrams I created back in college: activation boxes.

Typically, you draw boxes around objects while they are actively working to solve your task. This helps illustrate which systems are active or waiting at any given time.

Mermaid.js gives us the activate and deactivate keywords that govern the scope of these box shapes as shown below:

sequenceDiagram
    autonumber
    actor C as Client
    participant S as Server
    participant DB as Database
    C->>S: Login (Username, Password)
    activate S
        S->>DB: Select User Info

        activate DB
            note over DB: Password is not stored in database
            DB-->>S: Salt & Hash
        deactivate DB

        S->>S: Check Computed Hash using Salt
        alt Computed Hash Matches
            S->>S: Generate JWT
            S-->>C: 200 OK & JWT
        else No user or wrong password
            S-->>C: 401 Unauthorized
        end
    deactivate S
    note over C, S: Subsequent requests include JWT
Enter fullscreen mode Exit fullscreen mode

Sequence Diagram

Here again I use indentation to help make the scopes more explicit.

Warning: in Mermaid.js invalid diagrams can be hard to diagnose and I've found activation and deactivation to be particularly finnicky, especially when working with scopes like the alt and else blocks. I recommend you work iteratively and frequently test your diagrams as you expand them or make refinements.

Mermaid.js sequence diagrams allow you to skip the activate and deactivate lines to keep your diagrams condensed by adding a + and - syntax to messages.

For example, the following code activates the server with a login call:

    C->>S: Login (Username, Password)
    activate S
Enter fullscreen mode Exit fullscreen mode

We can combine these two lines instead by writing the code as C->>+S: Login (Username, Password) . (Note the + after the >> and before the :)

In a similar manner, we can replace code to deactivate a node such as the following:

    DB-->>S: Salt & Hash
    deactivate DB
Enter fullscreen mode Exit fullscreen mode

This code can be replaced with a more concise DB-->>-S: Salt & Hash line.

This transforms our earlier logic to the final logic below:

sequenceDiagram
    autonumber
    actor C as Client
    participant S as Server
    participant DB as Database
    C->>+S: Login (Username, Password)
        S->>+DB: Select User Info
            note over DB: Password is not stored in database
        DB-->>-S: Salt & Hash

        S->>S: Check Computed Hash using Salt
        alt Computed Hash Matches
            S->>S: Generate JWT
            S-->>C: 200 OK & JWT
        else No user or wrong password
            S-->>C: 401 Unauthorized
        end
        note over C, S: Subsequent requests include JWT
    deactivate S
Enter fullscreen mode Exit fullscreen mode

Ultimately, I don't think I like this shorthand and instead prefer to use the activate / deactivate syntax for more readable sequence diagrams, but the option is there for you if you want it.

Next Steps

While sequence diagrams aren't necessarily beginner friendly, working with Mermaid.js sequence diagrams is exponentially less painful than trying to control a diagramming tool to generate and maintain these diagrams.

Personally, I find Mermaid.js diagrams so convenient to use that I now find myself making sequence diagrams where I normally wouldn't have before due to the time and frustration required to build one.

Ultimately, I think Mermaid.js Sequence Diagrams are a good strategic tool for diagramming complex interactions or communicating complex concepts in a visual way in your documentation.

If you'd like to learn more and see a few features I didn't cover, I recommend you check out Mermaid.js' sequence diagram documentation.

And finally, I'm not done exploring what modern software engineers can do with Mermaid.js so stay tuned for more content!

Top comments (0)