Unique

morningprint

A thermal receipt printer that publishes one edition a day, to an audience of one

Two thermal receipts pinned to a corkboard with wooden pegs. The left, dated Friday July 3 2026, shows a single firework rocket climbing a dotted trail through a sparse starfield above a solid-black city skyline. The right, dated Saturday July 4 2026, shows the same skyline under a sky full of bursts.

A receipt printer in a kitchen wakes before its owner and prints one piece of block art with a verse under it — 80mm wide, one copy, no way to subscribe. When the cutter drops, the day’s edition is out.

The medium is the whole argument. The canvas is 203 dpi, one bit of colour, 48 monospace columns, and a character set frozen in 1981: CP437, the original IBM PC glyphs. Tone comes from ░ ▒ ▓ █ ramps, edges from half-blocks, solid black from inverted runs where even the spaces print. The trick that makes any of it possible is line spacing — by default the printer leaves a white seam between rows, and an ESC 3 value calibrated by hand makes the block rows fuse into continuous fields.

Each morning a Google Apps Script assembles a brief — the date, the season, the weather, and a rolling archive of the last fourteen pieces — and asks Claude for one committed idea sharply unlike everything in that archive. The reply comes back as a declarative spec: styled text operations plus a verse. A fifty-line renderer turns that into ESC/POS and POSTs it to a Raspberry Pi Zero W, which writes it straight to the printer’s character device.

The pair on the corkboard above is the exception that makes the rest work. A continues field sits empty almost every day, but when the day itself hands over a thread — a holiday arriving after its eve — the piece may answer an earlier one and record which. July 3 sends up a single scout rocket, testing the dark. Tomorrow, the whole sky; July 4 answers, the scout kept its word.

The most useful section of the README is the failure. Structured output guarantees the shape of the JSON, not the size of the strings in it, and one run in July 2026 returned a valid spec with a 3,155-character title of repeated filler. The archive kept it, every later prompt replayed it, and within a week the printer was producing a page of the model talking to itself instead of artwork. Specs are now length-checked before printing and the archive is sanitised on read, so a poisoned entry is dropped once rather than fed back for a fortnight.

You will need an Epson TM-T20III or another ESC/POS printer with CP437, a Pi, and an API key; the Pi-side script isn’t in the repo. MIT-licensed. What you get for that is a daily thing with no feed, no archive to scroll and nothing to refresh — yesterday’s goes on the corkboard.

github.com ↗

← back