Thompson's construction, transforming a regular expression into an equivalent NFA
You can do concatenation with an epsilon transition, but it is not necessary. Many implementations avoid it because concatenations are common and the epsilon transitions significantly increase the machine size.

There is some​ nice code in Russ Cox's famous essay on regular expressions, which implements a common strategy: fragment machines are built without any endpoint. Instead, the fragment descriptor contains a list of states in the fragment which would have a transition to the endpoint if there were one. In this way, two fragments can be concatenated by backpatching the second fragment's start state number as the head (target) of all outgoing transitions from the states in the first fragment's endpoint list.

You will find real code (in C) in the linked essay; search for the heading starting "Implementation"