Polygon offsetting is certainly possible to do yourself. It is not nearly as involved as Bezier or B-spline offsetting is. First you want to decide how to deal with:
Areas with no info, in essence how to deal with the joins. Do you just extend the line to the common intersection (miter join) or do you just connect the endpoints (bevel). You could also use round, parabolic or other join styles if you wish. Options here are unlimited.
For the purposes of this discussion I will assume you will want a miter or bevel join.
How do you want to deal with sidedness. Is an open curve's offset closed or just on the other side. Other than that the convention is usually in 2D that outside is on the clockwise side of the path
So lets look at what happens when 2 straight lines join and they are offset.

Image 1: Situation in 2D.
For a beveled corner join vector, from any point to its offset is magnitude of $a$. Take the direction of the segment rotated counterclockwise 90 degrees then multiply that with the length of offset. Or in the case of the picture in mathematical notation
$$
A' = A + a\bigg(\big|B-A\big| \begin{bmatrix}
0 & 1\\
-1 & 0
\end{bmatrix}\bigg)
$$
Where $a$ is the amount of offset. This assumes lines go from $A$ to $B$ to $C$. Connecting segments must be processed on both sides separately. The same formula can be used for all the points. Then just connect $B'^1$ to $B'^2$ with a line. In case you are matrix illiterate, the matrix says swap x and y coordinate and invert the x value.
For a miter join the following applies:

Image 2: Situation of miter.
$$
B^{B-B'^{1}} = a\bigg(\big|B-A\big| \begin{bmatrix}
0 & 1\\
-1 & 0
\end{bmatrix}\bigg)
$$
$$
B' = B+\dfrac{ B^{B-B'^{1}}}{B^{B-B'^{1}} \cdot (|B-A|-|C-B|)}
$$
The above can be heavily simplified but I'll leave that to the reader.
Now the reason to use a library is that when the curves start to self intersect it gets a bit tedious to manage this. So just find a library that does this for you and you'll save a lot of time.