Q:

Is it possible to guarantee delivery of messages using UDP on Node.js?

How is it possible to guarantee delivery of messages using UDP on Node.js? For example, I could just resend the packet if it failed - but is there a way to identify when it failed? Also, how common is the loss of a packet?

A:

If what you're really wondering is "how do I detect lost packets"? Then the general technique is to have the receiver send an acknowledgement for each packet sent. If the transmitter does not receive an acknowledgement then it must resend the packet. If the receiver gets duplicate packets then it should discard the duplicate.
The basic scheme is this:
TX                               RX
 ╷           data
 ╰──────────────────────────────▶

              ack               ╷
 ◄──────────────────────────────╯

 ╷           data
 ╰────────────────────── - - -         loss of data packet
               .
               .
               . timeout
               .
 ╷       data retransmit
 ╰──────────────────────────────▶

              ack               ╷
 ◄──────────────────────────────╯

 ╷           data
 ╰──────────────────────────────▶

              ack               ╷
      - - - ────────────────────╯      loss of ack packet
               .
               . timeout
               .

 ╷       data retransmit
 ╰──────────────────────────────▶

              ack               ╷
 ◄──────────────────────────────╯

This is essentially the basis of all forms of packet loss detection. There are several refinements that can be implemented to improve the technique but the basics is generally the same: if the receiver does not tell you that the packet has arrived then the packet is lost.
One of the first improvement generally done to the algorithm is to check that the ack is really the appropriate ack and not just some echo sent by the router or by signal cross inteference or by a software bug. The solution is to implement a toggle bit. The data packet is transmitted with the toggle bit set to a value and the ack packet needs to reply with the appropriate value (usually the same value). If the toggle bit is wrong then it means that the ack packet doesn't match the last data packet which implies that it matches the previous data packet. This implies that the last data packet hasn't been acknowledged which means that something has seriously gone wrong and the packet should be retransmitted until the correct ack is received.
TX                               RX
 ╷           data[0]
 ╰──────────────────────────────▶

              ack[0]            ╷
 ◄──────────────────────────────╯

 ╷           data[1]
 ╰──────────────────────────────▶

              ack[0]            ╷
 ◄──────────────────────────────╯     ack mismatch!

 ╷       data[1] retransmit
 ╰──────────────────────────────▶

Several real world protocols use this technique including most protocols used to control industrial equipment and robots.
The next step is actually an expansion of the above idea. Instead of sending just a bit why not send a number. That way you can more definitely match the ack to the data packet and so more accurately detect which packet was lost and needs retransmission. This technique is often referred to as the sliding window technique because at some point the number rolls over and slides back to zero. And so the maximum number of packets you can transmit before you're unable to detect packet loss is the sliding window size.
The big advantage of the sliding window technique is that you can send lots of data packets without waiting for the ack. This significantly improves throughput:
TX                             RX
 ╷           data[1]
 ╰──────────────────────────────▶
 ╷           data[2]
 ╰──────────────────────────────▶
 ╷           data[3]
 ╰──────────────────────────────▶

              ack[1]            ╷
 ◄──────────────────────────────╯
              ack[2]            ╷
 ◄──────────────────────────────╯

 ╷           data[4]
 ╰──────────────────────────────▶
 ╷           data[5]
 ╰──────────────────────────────▶

              ack[3]            ╷
 ◄──────────────────────────────╯
              ack[5]            ╷
 ◄──────────────────────────────╯     ack[4] missing!
               .
               . timeout
               .

 ╷       data[4] retransmit
 ╰──────────────────────────────▶

So the above is a short summary of the basic technique for detecting packet loss. That's what you need to implement if you want all your UDP packets to arrive at their destination.
You should know though that TCP already implements this so you should really use TCP if you don't want to reinvent the wheel. UDP was created because in some cases packet loss is OK (think audio/video streaming).

