The basics
What is an XBM file?
XBM is the bitmap format of the X Window System, the graphics system of most Unix and Linux desktops since the 1980s. It stores a black-and-white image as C source code, so a programmer can #include an icon or a cursor and have it compiled into the program, with no image library and no file to load at run time.
Xlib, the C library for writing X programs, has had functions to read and write the format from the start: XReadBitmapFile, XWriteBitmapFile and XCreateBitmapFromData. X also came with a bitmap editor that saves XBM files. For pictures with colour, X programs moved to XPM, which first appeared in 1989 and keeps the same idea of an image written as C code.
Today you'll meet XBM files:
- In X11 programs and window managers, for cursors, small icons and button images. The Openbox window manager, for example, draws its title-bar buttons from XBM files in its themes.
- In microcontroller projects, where a display library takes a 1-bit image as a C array; XBM is ready to paste in.
- In old websites, from the early web, when browsers displayed XBM and simple hit counters were served as XBM images.
For anything else, use PNG: it can also store 1-bit images, compresses them, and opens everywhere.
Anatomy
What's inside an XBM file
An XBM file is C code: two #define lines with the width and height, two optional lines with a hotspot, and an array of bytes holding the pixels, 1 bit each. Here is a complete XBM file we wrote for this page and checked in five decoders and a C compiler: a 10 × 7 arrow cursor pointing left, with its hotspot at the tip. Below it, the same bytes drawn out as pixels.
#define arrow_width 10
#define arrow_height 7
#define arrow_x_hot 0
#define arrow_y_hot 3
static unsigned char arrow_bits[] = {
0x08, 0x00, 0x0c, 0x00, 0xfe, 0x03, 0xff, 0x03, 0xfe, 0x03, 0x0c, 0x00,
0x08, 0x00 };
The same bits drawn out (# is 1, . is 0):
row 0 0x08 0x00 ...#......
row 1 0x0c 0x00 ..##......
row 2 0xfe 0x03 .#########
row 3 0xff 0x03 ########## ← hotspot at x 0, y 3
row 4 0xfe 0x03 .#########
row 5 0x0c 0x00 ..##......
row 6 0x08 0x00 ...#......- 1
#define arrow_width 10Width
The width in pixels, as a C preprocessor constant. Every name in the file starts with the image's name, here
arrow, taken from the file name when it was written. A program can#includetwo XBM files without the names clashing. - 2
#define arrow_height 7Height
The height in pixels: 7 rows.
- 3
#define arrow_x_hot 0Hotspot
Optional. The
_x_hotand_y_hotlines are only there if the bitmap has a hotspot: for a cursor, the pixel that marks where you're pointing. Here it's the tip of the arrow, x 0, y 3. Plain icons leave these lines out. - 4
static unsigned char arrow_bits[] = {The pixel array
A C array of bytes in hexadecimal. The X11 specification says
static unsigned char; ImageMagick and Netpbm writestatic char, and readers accept both. - 5
0x08, 0x00,The first row
Each row takes whole bytes: a 10-pixel row needs 2. The least significant bit of the first byte is the leftmost pixel.
0x08is binary00001000, so bit 3 is set: pixel 3 is black, the tip of the arrowhead's top edge. - 6
0xfe, 0x03,Padding bits
Row 2:
0xfesets pixels 1 to 7,0x03sets pixels 8 and 9. The other 6 bits of0x03would be pixels 10 to 15, which don't exist. They're padding, and readers ignore them. - 7
0x08, 0x00 };The end
14 bytes: 7 rows of 2. Nothing marks where a row ends; a reader works it out from the width. There's no checksum, colour or metadata.
- 8
row 3 0xff 0x03 ##########The bits drawn out
Read each byte from its lowest bit to its highest, then the next byte, and you get the picture: an arrow pointing left. The hotspot sits on this row, at its left end.
Under the hood
How XBM stores pixels
The format is defined by what Xlib writes. In the X11 documentation it's five lines, with the hotspot lines optional:
#define name_width width
#define name_height height
#define name_x_hot x
#define name_y_hot y
static unsigned char name_bits[] = { 0xNN,... }- 1 bit per pixel. 1 is the foreground, normally drawn black; 0 is the background. Many programs show 0 as transparent, so an XBM icon takes on the colour behind it.
- Rows top to bottom, pixels left to right, unlike BMP, which stores rows bottom-up.
- Least significant bit first. The leftmost pixel of a byte is its lowest bit. That's the opposite of PBM, where the leftmost pixel is the highest bit, and a common mistake in hand-written XBM code.
- Each row is padded to whole bytes. A row of 10 pixels takes 2 bytes; the unused bits are ignored.
- No compression and no colour. A 64 × 64 icon is 512 bytes of pixels, written out as about 3 KB of text.
X10 bitmaps
Before X11, the X version 10 format stored the pixels as 16-bit short values instead of bytes. GIMP can still export it (the "X10 format bitmap" option), but Xlib's documentation leaves reading anything other than the standard format up to the implementation, so prefer the X11 form.
History
Why browsers stopped showing XBM
In the early web, XBM was the simplest image format that wasn't owned by anyone, and graphical browsers, especially those on X, displayed it inline. It was used for small symbols and for hit counters, which a server script could write as text without an image library.
Support went away as the web settled on GIF, JPEG and PNG:
- Internet Explorer dropped XBM in version 6.
- Firefox removed its XBM decoder around Firefox 3.6. A side effect of the old decoder: a local text file starting with
#define, such as C source code, could be mistaken for an XBM image. - WebKit removed its open-source XBM decoder in January 2010, noting that Mozilla and Internet Explorer had already done so. Chrome, then built on WebKit, lost XBM with it.
Treat XBM as unsupported on the web. To show a 1-bit image on a page, convert it to PNG or SVG.
Comparison
XBM vs XPM, PBM and PNG
| XBM | XPM | PBM | PNG | |
|---|---|---|---|---|
| Colours | 2 | Any, via a colour table | 2 | Up to 16 bits per channel |
| Stored as | C source, hex bytes | C source, one or more characters per pixel | Text or binary, with a short header | Binary chunks, compressed |
| Transparency | Background bits are often shown as transparent | Yes, colour None | No | Full alpha |
| Hotspot for cursors | Yes | Yes | No | No |
| Compiles into a C program | Yes | Yes | No | No |
| Opens in a browser | No | No | No | Yes |
XPM is XBM's colour successor. PBM, from the Netpbm family, stores the same 1-bit pixels with the opposite bit order and is the usual go-between when converting. PNG is what to keep or share.
How to
How to open, create and convert an XBM file
- Look at it: it's text, so any text editor shows the code. To see the picture, open it in GIMP, XnView or IrfanView (Windows).
- Draw one: GIMP opens and exports XBM. Its export dialog can write hotspot values, a comment, a different name prefix and, since XBM has no transparency, a separate mask file made from the alpha channel. On X11 systems, the classic
bitmapeditor edits XBM files pixel by pixel. - Convert with ImageMagick:
magick arrow.xbm arrow.png, ormagick logo.png -resize 32x32 logo.xbmthe other way (convertin ImageMagick 6). A colour image is reduced to black and white; add-threshold 50%and adjust the percentage to choose where the cut falls. - Convert with Netpbm:
xbmtopbm arrow.xbm > arrow.pbmandpbmtoxbm arrow.pbm > arrow.xbm. - In Python: Pillow reads and writes XBM, including the hotspot:
Image.open("arrow.xbm").info["hotspot"]gives(0, 3)for the example above. - Use it in C:
#include "arrow.xbm"and passarrow_bits,arrow_widthandarrow_heighttoXCreateBitmapFromData, or to a display library on a microcontroller. Check the library's bit order first: some expect the most significant bit first.
Troubleshooting
Common XBM problems
- The picture looks scrambled in groups of 8 pixels. The bit order is reversed: the reader or the display library expects the most significant bit first. Reverse the bits in each byte, or convert with a tool rather than by hand.
- The image comes out inverted. Some programs draw 1 as white. Invert it (
magick in.xbm -negate out.xbm) or swap the colours where it's drawn. - A C++ compiler rejects the file. ImageMagick and Netpbm write
static char, and in C++ a value such as0xFFdoesn't fit acharthat is signed, which g++ reports as a narrowing error. Change the type tounsigned char. - Two XBM files clash when included together. They share a name prefix, often because both were saved under the same file name. Rename the
#defineconstants and the array. - It doesn't show in a browser. No current major browser decodes XBM. Convert it to PNG.
Security
Is an XBM file safe?
An image viewer reads an XBM file as text and never runs it, so opening one is as safe as the viewer's parser. Bugs have happened: in 2008 Mozilla fixed a low-severity flaw in Firefox 2's XBM decoder that could reveal small pieces of uninitialised memory.
The real care point is the C compiler. When you #include an XBM file, the compiler doesn't know it's meant to be an image: any C code in it is compiled into your program. Only include XBM files you've read or generated yourself.
Sample files
There are no sample XBM files on this page yet. The arrow in the anatomy is a complete XBM file: copy it into a text editor and save it as arrow.xbm, or make one from any image with ImageMagick (magick input.png output.xbm, or convert in ImageMagick 6).
Put it online
Have an XBM file? Give it a link.
Drop an XBM file on 99helpers and it gets its own web address. Browsers no longer display XBM, so anyone who opens the link downloads the file, ready for an image editor or a code editor.
Questions
XBM files, frequently asked
What is an XBM file?
A black-and-white image from the X Window System, written as C source code: the width and height as #define lines and the pixels as an array of bytes, one bit per pixel. It's used for icons and cursors.
How do I open an XBM file?
Open it in GIMP, XnView or IrfanView to see the picture, or in a text editor to see the code. Browsers don't display it.
How do I convert XBM to PNG?
Run magick input.xbm output.png with ImageMagick, or open it in GIMP and export as PNG. The result is a 1-bit image; nothing is lost.
Can XBM have colour?
No. Each pixel is one bit: foreground or background. For colour, use XPM or PNG.
What is the hotspot in an XBM file?
An optional point, given by _x_hot and _y_hot lines, that marks where a cursor points. For an arrow cursor it's the tip of the arrow.
Why don't browsers show XBM images any more?
Internet Explorer 6, Firefox (around version 3.6) and WebKit (in 2010) removed their XBM decoders, as the format had little use on the web. Convert XBM images to PNG to put them on a page.
Is an XBM file a C file?
Yes: it's valid C that a compiler accepts with #include. Image programs read the same text without compiling it.
Related formats
Other file types explained
Keep going
Related
Sources
- Xlib manual: Manipulating Bitmaps (X version 11 bitmap file format)
- GIMP 3.2 manual (Spanish edition): Export Image as X BitMap
- Wikipedia: X BitMap
- WebKit bug 27823: Remove XBM support
- Mozilla bug 304521: incorrect xbitmap (xbm) identification
- Mozilla Foundation Security Advisory 2008-45: XBM image uninitialized memory reading
Last reviewed 27 October 2026.