A lightweight HTTP API server for thermal receipt printers using ESC/POS protocol. SimplePrint provides a simple REST interface to control thermal printers for receipt printing, QR codes, barcodes, and images.
- 🖨️ Thermal Printer Support - Works with ESC/POS compatible thermal printers via USB
- đź“„ Multiple Content Types - Print text, QR codes, barcodes, and images
- đź”§ Flexible Formatting - Control fonts, sizes, alignment, and styling
- đź”’ Thread-Safe - Handles concurrent print requests safely
- 🚀 Easy Integration - Simple HTTP REST API
- Go 1.23.5 or later
- ESC/POS compatible thermal printer connected via USB
bash -c "$(curl -fsSL https://raw.githubusercontent.com/codaea/simpleprint/main/install.sh)"
git clone https://github.com/codaea/simpleprint.git
cd simpleprint
go mod download
go build -o simpleprint
SimplePrint uses environment variables for configuration. You can set these in a .env file in the project root.
Variable | Default | Description |
---|---|---|
GIN_MODE |
release | Gin server mode (release or debug ) |
PORT |
3000 | Port for the HTTP server |
PRINTER_PATH |
(empty) | USB path to the printer (optional, Linux only) |
Copy .env.sample
to .env
and adjust as needed.
./simpleprint
The server will start on port 5010
by default.
http://localhost:5010
Endpoint: POST /print
Description: Sends a print job to the thermal printer. The request contains an array of print commands that will be executed sequentially.
Request Body:
{
"quantity": 2,
"receipt": [
{
"type": "line",
"content": "Restaurant Name",
"font_size": 4,
"font": "A",
"alignment": "center",
"underline": false
},
{
"type": "qr",
"code": "https://example.com/receipt/12345",
"size": 8
}
]
}
Parameters:
quantity
(integer, optional): Number of copies to print. Defaults to 1 if not specified.receipt
(array): Array of print command objects. Each command represents a different element to print.
Prints a single line of text with formatting options.
{
"type": "line",
"content": "Hello World",
"font_size": 2,
"font": "A",
"alignment": "center",
"underline": false
}
Parameters:
content
(string): The text to printfont_size
(integer): Font size multiplier (1-8)font
(string): Font type -"A"
,"B"
, or"C"
alignment
(string): Text alignment -"left"
,"center"
, or"right"
underline
(boolean): Whether to underline the text
Prints text that can span multiple lines (supports \n
newlines).
{
"type": "text",
"content": "Multi-line text\nwith newlines\nSupported here",
"font_size": 1,
"font": "A",
"alignment": "left",
"underline": false
}
Parameters: Same as line
type, but content
can contain newline characters.
Advances the paper by the specified number of lines.
{
"type": "feed",
"lines": 3
}
Parameters:
lines
(integer): Number of lines to feed
Prints a QR code with the specified data.
{
"type": "qr",
"code": "https://example.com/order/12345",
"size": 8
}
Parameters:
code
(string): The data to encode in the QR codesize
(integer): QR code size (1-16, where larger numbers create bigger codes)
Prints a barcode with the specified data and format.
{
"type": "barcode",
"code": "123456789012",
"barcode_type": "CODE128"
}
Parameters:
code
(string): The data to encode in the barcodebarcode_type
(string): Barcode format -"UPCA"
,"UPCE"
,"EAN13"
,"EAN8"
,"CODE39"
, or"CODE128"
Prints an image from base64-encoded data.
{
"type": "image",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSU...",
"alignment": "center",
"dither_mode": "floydsteinberg"
}
Parameters:
data
(string): Base64-encoded image data (PNG format recommended)alignment
(string): Image alignment -"left"
,"center"
, or"right"
dither_mode
(string): Dithering algorithm to apply to the image. Available options:- Error Diffusion Algorithms:
"floydsteinberg"
- Floyd-Steinberg dithering (classic, good general purpose)"atkinson"
- Atkinson dithering (popular in retro Mac applications)"burkes"
- Burkes dithering (reduces artifacts)"jarvisjudiceninke"
- Jarvis-Judice-Ninke dithering (high quality, more processing)"sierra"
- Sierra dithering (good balance of quality and speed)"sierralite"
- Sierra Lite dithering (faster version of Sierra)"stucki"
- Stucki dithering (high quality, similar to Jarvis-Judice-Ninke)"stevenpigeon"
- Steven Pigeon dithering (experimental algorithm)"simple2d"
- Simple 2D dithering (basic algorithm)"tworowsierra"
- Two Row Sierra dithering (variation of Sierra)"falsefloydsteinberg"
- False Floyd-Steinberg (simplified version)
- Ordered Dithering Algorithms:
"clustereddot4x4"
- 4x4 clustered dot pattern (creates dot patterns)"clustereddot6x6"
- 6x6 clustered dot pattern (finer dot patterns)"clustereddot8x8"
- 8x8 clustered dot pattern (finest dot patterns)
- No Dithering:
"none"
- No dithering applied (direct conversion to black/white)
- Error Diffusion Algorithms:
Dithering is a technique used to convert grayscale or color images to black and white (monochrome) for thermal printers. Since thermal printers can only print black dots, dithering algorithms determine how to represent different shades of gray using patterns of black and white pixels.
When to use different algorithms:
- Floyd-Steinberg - Best general-purpose choice, good for most images
- Atkinson - Great for images with fine details and text
- Sierra/Stucki - Excellent for photographs and smooth gradients
- Ordered dithering (ClusteredDot) - Best for images that should maintain a "halftone" newspaper-like appearance
- None - Use when you want sharp, high-contrast black and white conversion
Status Code: 200 OK
{
"success": true
}
Status Code: 400 Bad Request
{
"error": "Invalid JSON format or missing required fields"
}
Status Code: 503 Service Unavailable
{
"error": "Printer is busy",
"message": "Another print job is currently in progress. Please try again later."
}
Here's a complete example that demonstrates printing a receipt with multiple elements:
{
"quantity": 1,
"receipt": [
{
"type": "line",
"content": "RECEIPT",
"font_size": 4,
"font": "A",
"alignment": "center",
"underline": true
},
{
"type": "feed",
"lines": 1
},
{
"type": "line",
"content": "Coffee Shop",
"font_size": 2,
"font": "A",
"alignment": "center",
"underline": false
},
{
"type": "line",
"content": "123 Main St, City",
"font_size": 1,
"font": "A",
"alignment": "center",
"underline": false
},
{
"type": "feed",
"lines": 2
},
{
"type": "text",
"content": "Order #12345\nDate: 2025-08-20\nTime: 14:30",
"font_size": 1,
"font": "A",
"alignment": "left",
"underline": false
},
{
"type": "feed",
"lines": 1
},
{
"type": "line",
"content": "--------------------------------",
"font_size": 1,
"font": "A",
"alignment": "center",
"underline": false
},
{
"type": "text",
"content": "1x Latte $4.50\n1x Croissant $3.25\nTax $0.62",
"font_size": 1,
"font": "A",
"alignment": "left",
"underline": false
},
{
"type": "line",
"content": "--------------------------------",
"font_size": 1,
"font": "A",
"alignment": "center",
"underline": false
},
{
"type": "line",
"content": "TOTAL: $8.37",
"font_size": 2,
"font": "A",
"alignment": "center",
"underline": false
},
{
"type": "feed",
"lines": 2
},
{
"type": "qr",
"code": "https://coffeeshop.com/receipt/12345",
"size": 6
},
{
"type": "feed",
"lines": 1
},
{
"type": "image",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSU...",
"alignment": "center",
"dither_mode": "sierra"
},
{
"type": "feed",
"lines": 1
},
{
"type": "line",
"content": "Thank you for your visit!",
"font_size": 1,
"font": "A",
"alignment": "center",
"underline": false
}
]
}
curl -X POST http://localhost:5010/print \
-H "Content-Type: application/json" \
-d '{
"receipt": [
{
"type": "line",
"content": "Hello World!",
"font_size": 2,
"font": "A",
"alignment": "center",
"underline": false
}
]
}'
If you see "No Printa Found!!" when starting the server, ensure:
- Your thermal printer is connected via USB
- The printer is powered on
- You have the necessary permissions to access USB devices
- The printer uses ESC/POS protocol
If print jobs seem to hang:
- Check that the printer has paper
- Ensure the printer is not in an error state (paper jam, cover open, etc.)
- Restart the SimplePrint server
- gin-gonic/gin - HTTP web framework
- mect/go-escpos - ESC/POS printer library
- makeworld-the-better-one/dither - Image dithering
This project is open source. Please check the license file for details.
Contributions are welcome! Please feel free to submit a Pull Request.