ExplorInk
GitHub

downloads · firmware and app

Install ExplorInk on your own reader

Two halves: firmware on the e-ink reader, an app on the Android phone. Both are free downloads, both are alpha, and this is a maker’s install: a USB cable, one command line tool, about half an hour. Nothing is hidden about what it overwrites or what is still untested.

What you need Firmware Phone app When it goes wrong

What you need

  • An unlocked Xteink X4, the plain one with the USB-C port. See the device table below.
  • A USB-C cable that carries data, not a charge-only cable.
  • A microSD card, FAT32 formatted. It can be empty: the firmware creates its own directory the first time a map square arrives.
  • A computer with Python 3 for the flashing tool. Linux, macOS or Windows.
  • An Android phone, version 12 or newer. The reader has no GPS receiver, so the phone is the receiver.

Which devices this firmware runs on

DeviceChipThis build
Xteink X4 (plain) ESP32-C3 Verified on real hardware. Every measurement on this site came off one.
Xteink X3 ESP32-C3 Compiled in, and the firmware probes for the X3’s own fuel gauge and clock. Never flashed on a real X3, because we do not have one.
Xteink X4 Pro ESP32-S3 No. Different chip family. This binary will not run on it, and one built for it does not exist yet.

Two facts that decide whether you can flash at all. The plain X4 is the only device in the line with a USB-C port: the X3 and the X4 Pro charge over pogo pins, so flashing them needs the vendor’s USB-C-to-pogo dongle. And the plain X4 was discontinued by Xteink on 2026-08-12, so the unit on sale today is usually a marketplace one.

Units sold locked, mostly the China-market ones on AliExpress, do not enumerate over USB at all: the computer sees no serial port, so there is nothing to flash. CrossPoint, the project this firmware forks, ships an unlock tool for that case: the CrossPoint unlock tool. We have not run it, so treat it as a pointer, not a recommendation.

The one thing to get right: back up first

Flashing writes over Xteink’s own reader firmware. There is no menu entry, no recovery partition and no vendor download that puts it back. What puts it back is a copy of the flash you made before you wrote anything.

So the first command reads the whole 16 MB flash into a file on your computer. It takes a few minutes. Keep that file: it is the reader you paid for, and it is the difference between an experiment and a one-way door.

python3 -m pip install esptool
esptool -p /dev/ttyACM0 read-flash 0 0x1000000 xteink-stock-backup.bin

Port names: /dev/ttyACM0 on Linux, /dev/cu.usbmodem* on macOS, COM5 or similar on Windows. On Linux, confirm you have the reader and not another device: udevadm info -q property -n /dev/ttyACM0 | grep ID_VENDOR_ID answers 303a for this chip. Older esptool releases spell the commands with underscores (read_flash, write_flash).

Putting it back later is the same tool, the other direction: esptool -p /dev/ttyACM0 write-flash 0x0 xteink-stock-backup.bin.

Step 1: the firmware

Three files, three offsets. The offsets are not read off a datasheet: they were checked against a real X4’s own 16 MB flash dump, and the partition table we publish is byte for byte the one that device runs. Getting this wrong bricks a reader, so it was verified rather than assumed.

Firmware 0.1.0-alpha, all three files

esptool -p /dev/ttyACM0 write-flash \
  0x0     explorink-0.1.0-alpha-esp32c3-bootloader.bin \
  0x8000  explorink-0.1.0-alpha-esp32c3-partitions.bin \
  0x10000 explorink-0.1.0-alpha-esp32c3-firmware.bin

Checksums are published next to the files as SHA256SUMS-firmware.txt. The firmware image is the exact build that was confirmed working on an X4 on 2026-08-22, not a rebuild of it: same bytes, same SHA-256.

The reader reboots into ExplorInk on its own. You get a home screen with Explore at the top, and Explore is the map. With no card and no tiles the map has nothing to draw yet, which is what step 2 is for.

Step 2: the card, and where the map comes from

Put a FAT32 microSD card in. It can be blank. Map squares arrive over Bluetooth from the phone: the reader lists the squares it does not have, the app fetches them from our tile server and pushes them across, and the firmware creates the directories as they land.

Coverage is not the whole world yet. What is built today is visible on the live coverage map. Ride onto ground that has no tiles and the reader draws a hatched square instead of a map, and that miss is logged on the server, which builds the area and publishes it, usually within minutes. It works inside a Europe-shaped box today (roughly 34 to 72 north, 12 west to 42 east), and outside it nothing is built.

How the tiles are built, and why they are a custom format rather than an existing one.

Step 3: the phone app

ExplorInk GPS, Android 12 or newer, sideloaded. It sends the position, brings the missing map squares, records the ride and manages the reader’s pins.

ExplorInk GPS 0.2.0-alpha, APK

Two things to know before you tap it, because both stop an install dead if they are a surprise:

  • It is debug-signed. This alpha carries the shared Android debug key, which identifies nobody. When a properly signed build arrives it cannot update this one: Android refuses an update across a different signing key, so you will have to uninstall first. That break is known, and it is the price of shipping something now.
  • It is not on Google Play. Your phone will ask to allow installing unknown apps from whatever you tapped the file in, and Play Protect may warn once. Both are normal for a self-signed APK.

With a cable it is one command and no permission dance:

adb install -r explorink-gps-0.2.0-alpha-debug.apk

On first launch it asks for nearby devices (Bluetooth scan and connect), location, and notifications, which is the foreground service that keeps the link alive. Then you pair with one reader once, through Android’s own companion device dialog. After that the operating system watches for that reader: open Explore on the bars and the app wakes up on its own, with the phone locked and nothing tapped.

What the app does on a ride, and what it spends.

When it goes wrong

What you seeWhat it is
Invalid head of packet (0x0D) Almost always the wrong serial port, not a bad cable. A phone and the reader both show up as /dev/ttyACM* and they swap places. Check the vendor id is 303a.
No serial port appears at all A charge-only cable, or a locked unit. See the unlock tool above.
Explore opens but the map is blank or hatched No tiles for that place yet. Check the card is in, then the coverage map.
The reader is frozen after flashing Plug it in and write the firmware again, or write your stock backup back. The chip’s own boot ROM answers the flashing tool even when the firmware on top of it is hung, which is why the backup is always reachable.
Play Protect blocks the app Expected for a self-signed APK. More details, then install anyway.
The app installs but never connects Open Explore on the reader first. The link is started from the map screen, and a force-stopped app cannot be woken by anything.

What is verified, and what is not

Verified on a real X4: the map render off the card, place names, track-up, a route overlay, pins, the phone link and tile transfer over Bluetooth. That is where every number on this site comes from.

Not verified, said plainly:

  • A real X3. The code is built for it and probes its hardware. Nobody has flashed one.
  • The X4 Pro. Different chip. No build exists.
  • This exact three-file write onto a stock device. Every flash so far went onto a reader that already ran this firmware. The offsets are confirmed against a real device’s flash, and the step itself has not been done from stock by us.
  • Battery life for a full ride. Ride draws of 17 to 46 mA are measured, the capacity behind the runtime claim is the vendor’s number, and nobody has run a cell down on a bench.

Security, before you carry it

The reader answers commands over Bluetooth with no pairing, no bonding and no authentication, and the same commands over the USB serial port. Anyone in radio range can ask it where it is. A lost or stolen reader is not private, and this is a known open item rather than a solved one. Do not put anything on it you would mind a stranger reading.

The one exception is the document wallet: what the phone writes to the card is encrypted, and the reader only ever holds ciphertext plus the key material it needs to show a page.

No account, no telemetry from the device

There is no login and no cloud service. The reader talks to your phone. The phone talks to a static tile server, which sees a request for a map square and nothing else. Your recordings are files on your phone.

Both halves are open source: the firmware and the Android app. A one click installer in the browser, so none of this needs a command line, is the next thing on the list.

The questions people ask before trying it · what landed when, with the measurements