Quick comparison
| Feature | Code 39 | Code 128 |
|---|---|---|
| Character set | Uppercase letters, digits and selected symbols in basic form | Full ASCII through Code Sets A/B; efficient numeric pairs through Code Set C |
| Density | Relatively low | High |
| Check character | Optional in many uses | Mandatory internal symbol check |
| Legacy industrial support | Excellent | Excellent on modern equipment |
| GS1 carrier? | No | Basis of GS1-128 |
Why Code 39 remains common
Code 39 is conceptually simple and has decades of installed use in manufacturing, defense-related labeling, asset identification and legacy software. Human-readable values often correspond directly to the encoded characters, and many older scanners support it.
The cost of that simplicity is space. Code 39 normally produces a much wider symbol than Code 128 for the same value.
Why Code 128 is often the modern default
Code 128 was designed for higher density and supports three code sets. Code Set C is especially efficient for long even-length numeric data because it encodes two digits per symbol character. Code sets can switch within a barcode, allowing compact encoding of mixed values.
Compatibility and migration
If a customer, regulatory program or installed system specifically requires Code 39, keep using it. If you control both ends of a new internal system, Code 128 is often more flexible and space-efficient. Before migration, inventory scanners, printer firmware and software parsers to make sure no hard-coded symbology assumptions exist.
Label-space example
On a narrow label, a long Code 39 value may force you to reduce X-dimension below a comfortable size just to fit. Code 128 can often encode the same data more compactly, allowing a larger X-dimension and potentially better scanning margin.