Tearline is one custom element that wraps any HTML you have already written and prints it out as a thermal receipt, then saves that receipt as a picture your users can post. It is for a developer building the share image at the end of something: a listening history, an order summary, a year in review.
What you get is a tag you put around your existing headings, tables and lists, and three ways to hand a reader the file: save it, take the raw file, or take an address you can drop straight into an image. It is free. MIT licence, no dependencies, no build step, installed either as a single script tag or with npm i @kynth/tearline.
Watch the Tearline — Any HTML, printed as a receipt — one custom element, zero dependencies demo
The rule of the medium
Saving a receipt works by handing the browser a drawing of the paper with every word and every style written inside it. That drawing is sealed off, and it cannot reach out over the network for anything. A photograph pulled in by address never arrives.
That rule is not Tearline's, and it is not negotiable. It applies to every share-image feature that goes through the same door.
The browser does not tell you
Measured on the live product on 2026-08-23, the browser does not refuse the drawing when a photograph cannot be fetched. Not for a photograph from the same site, not for one from another site, not for one served with permission to share, not even for an address that returns nothing. It finishes the drawing and paints its own small broken-image icon where the photograph should be. A receipt carrying a photograph 654 pixels tall came back with a 16 pixel icon in its place, and the whole card was 600 pixels shorter than the one on screen. No error appeared anywhere.
That is the expensive version of this. Someone looks at a receipt, saves it, posts it, and the thing they posted is not the thing they were looking at.
What exports, and what is refused
| What is on the paper | What the export does | Why |
|---|---|---|
| A photograph from the same site | Refuses, and names the address | The sealed drawing reaches nothing, not even its own site |
| A photograph from another site | Refuses, and names the address | Same |
| A photograph served with permission to share | Refuses | Permission to share does not put the file inside the drawing |
| An address that returns nothing | Refuses | It would paint the browser's icon instead |
| A picture embedded directly in the page | Exports | The picture travels inside the receipt |
| No picture at all | Exports | Nothing to lose |
| A picture tag with no address | Exports | It paints nothing on screen either, so the file still matches |
The refusal is made before the drawing is built
Any picture inside the receipt whose address is not embedded in the page stops the export up front, carrying the same sentence a reader was always meant to get plus the address that caused it. We ran that against five pictures that have to be refused and three that must not be, and the browser's own failure handler stays behind it as a second line.
The seed does the rest: the same seed always draws the same torn edge and the same barcode, so the saved file is the receipt the reader was shown.
Play with it here: https://tearline.kynth.studio/kd
One shipped product, taken apart, once a month. What it does, what it cost to build, what the pipeline behind it looks like, and what the numbers did — read off the repository and the live site, not written from memory. Join the list.



Top comments (0)