Introduction
LZW is the dictionary-based compression algorithm that Terry Welch published in 1984 as a refinement of LZ78. It became the backbone of the GIF image format, the Unix compress utility, and PDF's LZWDecode filter. Unlike Huffman coding, LZW does not need to send the dictionary to the decoder: both sides build it identically from the data stream. This lzw compression online tool compresses text into variable-width codes and decompresses them back, all in your browser. No data leaves your device.
What this tool does
- Compresses text into LZW codes using a dictionary seeded with all 256 byte values, growing as new byte sequences appear.
- Uses variable-width codes from 9 to 16 bits, matching the classic GIF and Unix compress behavior.
- Outputs the code list (decimal), the packed hex bitstream, and the compression ratio versus 8-bit fixed encoding.
- Decompresses hex LZW data back to the original text, rebuilding the dictionary on the fly without needing it sent separately.
- Operates on UTF-8 bytes so Unicode input round-trips correctly.
- Updates in real time as you type. All processing happens client-side.
How this tool works
In compress mode, the tool encodes your input as UTF-8 bytes and seeds a dictionary with all 256 single-byte strings. It reads bytes one at a time, extending the current sequence w as long as w + next_byte is in the dictionary. When it hits a sequence not in the dictionary, it emits the code for w, adds w + next_byte to the dictionary with the next available code, and starts a new sequence. Codes start at 9 bits and grow to 10, 11, up to 16 bits as the dictionary fills.
In decompress mode, the tool reads the hex bitstream, extracts codes at the same variable widths, and rebuilds the dictionary in lockstep with the encoder. The decoder handles the special case where a code refers to an entry that has not been added yet (which happens when the encoder emits a code for a sequence that is being defined right now). The output is the original UTF-8 text.
How LZW compression works
LZW is a descendant of the LZ78 algorithm that Abraham Lempel and Jacob Ziv published in 1978. Terry Welch simplified it in his 1984 paper "A Technique for High-Performance Data Compression". The key insight is that the dictionary can be reconstructed by the decoder without being transmitted, because every code the decoder receives corresponds to a sequence it has already seen plus one new byte.
The algorithm: initialize the dictionary with one entry per byte value (codes 0-255). Maintain a current sequence w. For each input byte c, if w + c is in the dictionary, set w = w + c. Otherwise, output the code for w, add w + c to the dictionary with the next code, and set w = c. At end of input, output the code for w.
The decoder mirrors this: it reads codes, looks them up in its dictionary, and adds a new entry for each code it processes. The one tricky case is when the encoder emits a code for a sequence that is being defined in the same step; the decoder handles this by observing that the new entry is always w + w[0], where w is the previous sequence.
GIF uses LZW with a fixed starting code width tied to the image's color depth (typically 8 bits, so codes start at 9 bits). Unix compress used variable-width codes up to 16 bits. PDF's LZWDecode filter is similar. The algorithm is covered by US Patent 4,558,302 (filed 1983, now expired), which caused the PNG format to be created as a patent-free alternative to GIF.
How to use this tool
- Select mode: Compress or Decompress.
- For compression: type or paste text. Output shows the code list, packed hex, and compression ratio.
- For decompression: paste hex LZW data. The tool rebuilds the dictionary and returns the original text.
- Use the Swap button to switch between modes.
- Copy the result with the Copy button.
Real-world examples
Compressing repetitive text
LZW shines on input with repeated phrases. Paste "TOBEORNOTTOBEORTOBEORNOT" (the example from Welch's 1984 paper) and watch the dictionary build up: after the first "TOBEORNOT" the encoder starts emitting single codes for "TO", "BE", "OR", and "NOT". The compression ratio on this input is strongly positive because the dictionary captures every repeated substring.
Decoding a GIF LZW stream
A developer inspecting a GIF file extracts the LZW-compressed image data as hex and pastes it into the decompress mode. The tool rebuilds the dictionary and returns the raw index stream, which is the sequence of color table indices that the GIF renderer would draw. This is useful for debugging GIF encoders and understanding the format.
Comparing LZW to DEFLATE
A student compresses the same text with this LZW tool and with the Gzip tool (which uses DEFLATE). DEFLATE typically wins because it combines LZ77 back-references with Huffman entropy coding, while LZW is a single-stage dictionary coder. The comparison makes the trade-off between algorithmic simplicity and compression ratio concrete.
Comparison with similar methods
| Method | Complexity | Typical use |
|---|---|---|
| LZW | O(n), single-pass dictionary coder | GIF, Unix compress, PDF LZWDecode |
| LZ77 / LZSS | O(n) with sliding window | DEFLATE, gzip, zlib |
| LZMA | O(n), range coding + large dictionary | 7z, xz archives |
| Huffman coding | O(n log n), entropy coder | DEFLATE entropy stage, JPEG |
Limitations or considerations
LZW is a single-stage dictionary coder. It does not combine its output with an entropy coder the way DEFLATE does, so it typically compresses 10-20% worse than gzip on the same input. The dictionary grows up to 2^16 entries; once it fills, this implementation stops adding new entries (matching classic compress behavior). Some variants clear the dictionary at that point, which can improve ratio on long inputs. The variable-width code packing assumes the decoder knows the starting width; this tool always starts at 9 bits, which matches GIF and compress but may not match every LZW variant.
Frequently asked questions
Why does the decoder not need the dictionary?
Because the dictionary is built deterministically from the code stream. Every code the decoder receives corresponds to a sequence it has already seen, plus one new byte that it adds as the next dictionary entry. The encoder and decoder stay in lockstep, so the dictionary is implicit in the data.
What is the special case in LZW decoding?
When the encoder emits a code for a sequence that is being defined in the same step, the decoder receives a code that is not yet in its dictionary. The decoder handles this by observing that the new entry is always the previous sequence plus its first character. This case only happens when the input has a pattern like abcabcabc where the encoder defines and uses a sequence in one step.
Why did PNG replace GIF?
GIF uses LZW, which was covered by US Patent 4,558,302 (filed 1983, granted 1985, expired 2003). In the 1990s Unisys began enforcing the patent against GIF users, which motivated the creation of PNG as a patent-free alternative using DEFLATE. The patent has since expired, but PNG had already won on technical merits like alpha channels and better compression.
How does LZW compare to gzip?
gzip uses DEFLATE, which is LZ77 followed by Huffman coding. DEFLATE typically compresses 10-20% better than LZW on the same input because the Huffman stage squeezes out redundancy in the LZ77 output. LZW is simpler and was historically faster, but modern hardware makes the DEFLATE advantage worth the complexity.
Conclusion
LZW is a classic dictionary compression algorithm that builds its dictionary on the fly, so the decoder needs no side channel. This tool compresses and decompresses LZW data in your browser with variable-width codes matching GIF and Unix compress. For better compression ratios, try the Gzip, Brotli, or Zstandard tools. For the entropy stage that LZW lacks, see the Huffman Coding Visualizer.