Little Printer arrives / © David Somers 2013

Making a Little Printer publication

Little Printer: It’s a small internet-connected receipt printer backed by a robust periodical-oriented web-based publishing platform. Little Printer owners can schedule publications to be printed at a certain time of day, and these publications can be anything: Your best tweet yesterday, word of the day or a short story.

You need some technical know-how but in general it is very easy to create a Little Printer publication and it makes for great weekend projects.

You don’t need a Little Printer to make a publication. BERG Cloud provide a set of tools for previewing and testing your publication. However receipt printers present an interesting design challenge due to the way they print which is difficult to emulate, so you might need one if your design is quite complicated (or you’re a perfectionist). More on this later.

I will not be covering the push API. I have not used it yet. You should try it though, only a handful of publications use it right now (e.g. New York Times Breaking News).

Resources and tools

What makes a good publication?

Fundamentally your publication should provide content that is interesting and engaging. When asked, BERG Cloud suggested avoiding ideas that depend on an extra layer of interaction, e.g. printing a QR code and asking users to scan it with their phones. While this is possible (and some publications do it) ideally your publication should be the complete experience.

Your publication should suit a regular (e.g. daily) printing pattern. “A story a day”, “Word of the day”, “Random photo of the day” and “Your most popular blog post last week” are examples of content that suit Little Printer.

The border on the Daily Puzzle publication looks great; it uses varying shades of dithered grey and diagonal lines to create a subtle 3D effect.

It is possible to produce beautiful publications, but remember this is a receipt printer only capable of black and white printing. Clever use of dithering (more on this later) can provide shades of grey but they will often be murky and it will be difficult to make out details. Your design should make use of blocks of solid grey (which can be dithered effectively) and patterns; 1px diagonal lines look particularly handsome on Little Printer.

Publications should be short (dimensionally). Between 2–4 inches is a good rule and there is a hard limit of 800 pixels (no infinite Nyan cat!). Publications are generally sent alongside other publications; yours is likely to have some above and below it, so it should have clear start and end points.

Key technical points

All communication between your publication and the Little Printer publishing system is done via HTTP requests.

Configuration for your publication — how it works, what its called, configuration options for the user and so on — is done in a meta.json file which you create as part of your publication. Here’s the one for my Spanish Word of the Day.

The Little Printer publishing system will query your publication either on demand for a sample or as-per your user’s subscription settings (at certain times in the day).

Users can request a sample when deciding whether to subscribe to your publication. This is sent to their printer immediately. BERG Cloud prefer this to be the same every time; don’t use live data, use a fixed static snapshot of your publication. This way it matches with their preview image and discourages users from just using the preview functionality instead of subscribing to have the publication automatically delivered.

When your publication is queried for a real ‘edition’ it is expected to respond in one of 3 ways:

  • No content at all (with status code 204); signalling there is nothing to print. This is mainly useful if your publication is less frequent than once a day.
  • If your publication has a finite number of editions (maybe it’s a series of 10 short stories) and they have all been delivered to the user (you can ask BERG to supply the delivery count via a flag in your meta.json configuration) it should respond with status code 410 (GONE) which deletes the user’s subscription — the best use of HTTP 410 ever.
  • With a copy of the publication and an HTTP ETag corresponding to the publication.

The ETag is a commonly forgotten HTTP header (unless you’re a caching-nut) that Little Printer relies on. You must design your content such that it can be defined by a small string (e.g. a hash) that reflects the unique content of the publication at a point in time. When BERG Cloud requests your publication it will compare the ETag you supply with the ETag the last time it was requested. If they are the same nothing will print. Without this, your publication may print the same thing more than once for a subscriber if something goes wrong or if your publication is sporadic or published randomly like “How many people are in space right now?”. The easiest way to achieve this is to supply an ETag corresponding to today’s date. In Sinatra:

etag Digest::MD5.hexdigest(strftime('%d%m%Y'))

Providing configuration

‘One Down’ — a pair of clues from today’s Times Crossword — uses configuration to allow the user to choose whether they want a puzzle from the Cryptic or Concise crossword.

There is functionality within the Little Printer publishing system to require the user to configure your publication. This configuration is set in the meta.json file and the values the user chooses are sent along with every publication request. The simplest publication is one without a configuration; if you have a configuration you must also provide a `validate_config` endpoint that verifies if a configuration is valid or not.

Third-party authentication

If you need to authenticate the user with a third-party — maybe you need access to their social network profile — you can set a configuration variable in meta.json instructing the system to redirect the user via your app as part of the configuration process. You can also use this for more complex configuration. It’s simplest to start with a publication that doesn’t need this, but it’s not hard. More details are on BERG Cloud’s website.

Two common gotchas

  • Asset URLs (stylesheets, images) must be absolute. The Little Printer rendering system (for the curious, it’s a fork of PhantomJS behind the scenes) does not support relative URLs. In Sinatra this just means using `url()` in your views.
  • You can’t use web fonts. More on this further down.

Testing your publication with BERG Cloud tools

BERG Cloud provide a very feature-rich set of validation and testing tools on their developer website. Make use of them and you won’t really need a printer to create publications. There’s a rapid prototyper which accepts HTML snippets or a URL and will render the exact output that is sent to printers. You can also test that your publication meets all the requirements (meta.json, icon, sample) with their validator and test out any external configuration process you have made. Once you have gone live you can also track the number of subscribers and whether everything is working smoothly. Neat!

Basic design considerations

Black, white, dithered

Pimp My Tweets — a publication we never finished — uses a hand-dithered header that looks awful on screen (pictured here) but beautiful when printed by Little Printer.

Receipt printers can only print black or white however Little Printer has quite a high DPI (~200). This means that dithering is an effective technique for producing the illusion of shades of grey. In some situations you may want to perform dithering yourself in particular if you want to include patterns in your design (e.g. a fancy border) or create something really special but most of the time you should make use of BERG Cloud’s built-in dithering. Add the ‘dither’ class to your images:

<img src='' class='dither' />

This only works for <img> tags, you’ll have to dither CSS background images yourself. This is achievable in Photoshop; I think you change the image to black and white and play with the options during conversion to achieve different dithering styles.


I touched on web fonts earlier — you can’t use them. You can render fonts to an image if you like, but then you miss out on their font rendering optimisation. BERG Cloud spent a lot of time analysing which free fonts worked best with Little Printer and you should take advantage of that by using one of their suggested fonts. Due to the high DPI use a large font size (18–20px minimum).

Paper layout

There is a physical 4.5mm margin on either side of your publication that cannot be removed. In your HTML and CSS design up to the very edge; don’t place additional margins either side of your publication otherwise it will look narrower than others.

Your publication will usually be alongside others in a printout. You should add a simple separator to the bottom of your publication (a thick straight line or border is enough) to help visually identify where your publication ends and the next one begins. Add 10px padding to the top and bottom too — the system won’t do this for you.

Have fun with Little Printer

Hopefully this has given you some ideas for Little Printer publications and shown just how quick and easy it is to create them. There’s so much scope for interesting, quirky and fun ideas perfect for quick code projects that will be enjoyed by lots of people with very little effort on your part.

I put Spanish Word of the Day live just 3 weeks ago and at the time of writing there are 61 Little Printers around the world printing it out every day. ^_^

Seeing Instagrams of people printing your publication just days after creating it is a great feeling!



👨‍💻 Head of Engineering @pixielabs 🎙 Podcast host @octalfm 🖱 Coder @twfall, @riveredapp, @traintrackio 👾 Gamer

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
David Somers

David Somers

👨‍💻 Head of Engineering @pixielabs 🎙 Podcast host @octalfm 🖱 Coder @twfall, @riveredapp, @traintrackio 👾 Gamer