Web Direct POS Print

Print receipts instantly from any web POS โ€” no dialog, no delay. A desktop bridge app that connects your web-based POS directly to a local printer (dot matrix LPT or thermal POS) over a local HTTP server at http://localhost:3535.

Your web app sends a single fetch POST and the receipt prints immediately โ€” no browser print dialog, no driver pop-ups. The app minimizes to the system tray when closed โ€” the HTTP server keeps running in the background.

Contents
  1. Features
  2. GET /status
  3. GET /printers
  4. POST /print โ€” Field Reference
  5. Integration Examples

Features

Web Direct POS Print โ€” menu bar UI

Menu bar interface โ€” endpoint, printer selector, and live print log

API Reference

GET /status

Check if the app is running.

{
  "status": "ok",
  "app": "printer-bridge",
  "version": "0.1.0"
}

GET /printers

List available printers and the current default.

{
  "printers": ["EPSON_LX310", "POS58"],
  "default": "POS58"
}

POST /print โ€” Field Reference

Send a JSON body with Content-Type: application/json. A non-JSON body (text/plain / application/octet-stream) is sent as-is to the default printer.

Field Type Description
printer string Printer name. Omit to use the default printer.
data string Text to print (alias: text).
base64 string Raw bytes encoded as base64 (logos, barcodes, binary ESC/POS commands).
feed number Number of extra line feeds appended at the end.
cut boolean Cut paper (ESC/POS GS V) โ€” for thermal POS printers.
drawer boolean Open cash drawer (ESC/POS ESC p).
formfeed boolean Send form feed 0x0C โ€” for dot matrix continuous form.
qr string Text/URL printed as an ESC/POS QR code (center-aligned).
qr_size number QR module size 1โ€“16 (default 6, โ‰ˆ3 cm on 80 mm paper).
logo string PNG/JPEG image URL โ€” downloaded and printed as a bitmap at the top.
logo_width number Logo print width in pixels (default 300, max 576 for 80 mm paper).
logo_text string Text to the right of the logo (use \n for line breaks). When set, the logo is scaled small and layout becomes [logo โ”‚ text].
logo_size number Logo box size when displayed beside text, in pixels (default 88).
Note: HTTPS pages may call http://localhost โ€” browsers treat localhost as a secure context, so there is no mixed-content block. Safari is not supported โ€” it blocks these local requests. Use Chrome, Firefox, Edge, or another Chromium-based browser.

Integration Examples

// Minimal โ€” print to default printer, cut & open drawer

await fetch("http://localhost:3535/print", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    data: "receipt text...\n",
    cut: true,
    drawer: true,
  }),
});

// Full receipt โ€” logo, QR code, cut & drawer

await fetch("http://localhost:3535/print", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    logo: "https://example.com/logo.png",
    logo_text: "Example Company\nExample Subtitle",
    logo_size: 88,
    data: "================================\n"
        + "   EXAMPLE COMPANY\n"
        + "   123 Example Street\n"
        + "================================\n"
        + "No  : INV/2026/06/00001\n"
        + "Date: 15-06-2026  10:32:45\n"
        + "--------------------------------\n"
        + "Name   : JOHN DOE\n"
        + "--------------------------------\n"
        + "Service Charge:    45,000\n"
        + "TOTAL DUE     :    47,500\n"
        + "================================\n"
        + "  Thank you for your payment.\n",
    qr: "https://example.com",
    qr_size: 6,
    feed: 3,
    cut: true,
    drawer: true,
  }),
});

// Thermal POS โ€” feed before cut so last line isn't cut off

await fetch("http://localhost:3535/print", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    data: "receipt text...\n",
    feed: 4,
    cut: true,
  }),
});

// Dot matrix LPT โ€” feed to tear bar (calibrate once per printer)

LX-310 is typically 5โ€“7 lines from print head to tear bar.

await fetch("http://localhost:3535/print", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    printer: "LPT1",
    data: "receipt text...\n",
    feed: 6,
  }),
});

// Dot matrix โ€” continuous form with fixed page length

await fetch("http://localhost:3535/print", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    printer: "LPT1",
    data: "receipt text...",
    formfeed: true,
  }),
});

Questions? Contact the developer at [email protected]