Doodle Code is a type of barcode: a machine-readable optical label. Similar to QR codes, it can be used to store data. Although it is less information-dense than QR codes, it has more flexibility in its appearance. It can be hand-drawn and is easy to learn using a few simple rules. It is designed to be robust so that photos of a Doodle Code can be correctly decoded under various angles or lighting conditions.

Doodle Code was created by Byron Knoll in 2021. You can email me at for any questions or comments. In particular, let me know if you create a Doodle Code which follows all of the instructions below but doesn't decode correctly. The JavaScript used for decoding Doodle Codes is open source and released into the public domain.

I have created two other projects similar to Doodle Code: Turing Paint and Bitlog.


  1. Doodle Code uses black paths on a white background. The paths should be at least two pixels wide.

  2. Data is stored in binary, using a sequence of 0s and 1s. There should be a single path connecting all of the symbols in a sequential order. Since this path has two "ends", the following system is used to label the direction of the path: an extra "0" is used at the start and an extra "1" is used at the end. For example, to encode the data "10", after adding the start/end labels the final sequence will be "0101".

  3. A "0" symbol is made by splitting the path into two paths and then re-joining later:

    The distance between the split and the join should be approximately the same on both paths. This example violates this rule:

  4. A "1" symbol is made by splitting the path into three paths and then re-joining later:

    There should be a single point where the path splits into three. This example violates this rule because there are two separate split points on the left side:

  5. The path connecting two symbols should be sufficiently long: at least twice the "width" of the path.

  6. Black paths should be made as solid as possible, without any gaps or holes. Any hole in a black path could potentially be interpreted as a symbol. To make Doodle Codes more robust, black pixels are sometimes expanded outwards to fill in small gaps (potentially caused by noise in photos). As a consequence, the inner white regions for the "0" and "1" symbols need to be sufficiently large: at least the width of the black path. In addition, separate black paths should not get too close to each other: they should be separated by at least the width of the black paths.

  7. Doodle Codes which follow all of the above instructions should always be decoded correctly. However, it is also possible to create Doodle Codes which violate some of the above instructions but still be correctly decoded. For example, the path lengths for the "0" symbol can actually be substantially different, as long as the path connecting to neighboring symbols is sufficiently long. Any Doodle Code which successfully decodes using the JavaScript implementation on this webpage is technically valid. The implementation uses the flood fill algorithm to follow paths and the marching squares algorithm to label borders (the green and red pixels).