npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

memobirdsdk

v1.0.1

Published

TypeScript SDK for Memobird (咕咕机) thermal printer API

Readme

Memobird SDK

TypeScript SDK for Memobird (咕咕机) thermal printer API. This SDK provides a complete, type-safe interface for controlling Memobird devices with comprehensive error handling and automatic retry capabilities.

Features

  • Full TypeScript support with comprehensive type definitions
  • Automatic GBK encoding for Chinese characters
  • Retry mechanism with exponential backoff
  • Image processing utilities for converting JPG/PNG to monochrome bitmap
  • Complete JSDoc documentation for all functions
  • ESM module format
  • Error handling with custom error classes
  • Promise-based async/await API

Installation

npm install memobirdsdk

For examples, also install dotenv to manage environment variables:

npm install dotenv

Quick Start

import { MemobirdClient } from 'memobirdsdk';

// Initialize the client
const client = new MemobirdClient({
  ak: 'your-access-key-from-open.memobird.cn'
});

// Bind user to device
const bindResult = await client.bindUser('device-id', 'user-123');
const userId = bindResult.showapi_userid!;

// Print text (auto-converts Chinese to GBK)
await client.printText('Hello World! 你好世界!', 'device-id', userId);

Using Environment Variables (Recommended)

For better security, use environment variables to store sensitive information:

  1. Create a .env file in your project root:
MEMOBIRD_AK=your-access-key-here
MEMOBIRD_DEVICE_ID=your-device-id-here
MEMOBIRD_USER_ID=your-user-identifier-here
  1. Use dotenv in your code:
import 'dotenv/config';
import { MemobirdClient } from 'memobirdsdk';

const client = new MemobirdClient({
  ak: process.env.MEMOBIRD_AK!
});

const deviceId = process.env.MEMOBIRD_DEVICE_ID!;
const userId = process.env.MEMOBIRD_USER_ID!;

await client.printText('Hello!', deviceId, parseInt(userId, 10));

Important: Add .env to your .gitignore to avoid committing sensitive credentials!

Testing Your Setup

To quickly test if everything is working, use the built-in test function:

npm test

This will:

  • ✅ Verify your environment variables are set
  • ✅ Test the API connection and user binding
  • ✅ Print a debug slip with system information
  • ✅ Display detailed status and error messages

The printed slip will include:

  • Current date and time
  • System information (hostname, platform, Node.js version)
  • Network status
  • Device and user IDs
  • API call results

Available Scripts

npm test                 # Run test and print debug slip
npm run example:basic    # Run basic usage example
npm run example:text     # Run text printing examples
npm run example:image    # Run image printing examples
npm run example:advanced # Run advanced usage examples

Getting Started

1. Get Your Access Key

  1. Visit open.memobird.cn
  2. Register as a developer
  3. Get your Access Key (ak) from your user dashboard

2. Get Your Device ID

Double-click your Memobird device to print out the device ID.

3. Bind User to Device

const client = new MemobirdClient({ ak: 'your-access-key' });

const bindResult = await client.bindUser('fb93bfff504c020a', 'user-123');
console.log('User ID:', bindResult.showapi_userid);

API Reference

MemobirdClient

Constructor

new MemobirdClient(config: MemobirdConfig)

Parameters:

  • config.ak (required): Access Key from open.memobird.cn
  • config.baseUrl (optional): API base URL (default: 'http://open.memobird.cn/home')
  • config.timeout (optional): Request timeout in milliseconds (default: 30000)
  • config.retry (optional): Retry configuration
    • maxRetries: Maximum retry attempts (default: 3)
    • initialDelay: Initial delay before first retry in ms (default: 1000)
    • backoffMultiplier: Exponential backoff multiplier (default: 2)
    • maxDelay: Maximum delay between retries in ms (default: 10000)
    • retryStatusCodes: HTTP status codes to retry (default: [408, 429, 500, 502, 503, 504])

Example:

const client = new MemobirdClient({
  ak: 'your-access-key',
  timeout: 60000,
  retry: {
    maxRetries: 5,
    initialDelay: 2000
  }
});

Methods

bindUser(memobirdID, useridentifying)

Binds a user identifier to a device.

await client.bindUser(memobirdID: string, useridentifying: string): Promise<BindUserResponse>

Returns: { showapi_res_code, showapi_res_error, showapi_userid }

printText(text, memobirdID, userID)

Prints text content. Automatically converts UTF-8 to GBK encoding for Chinese characters.

await client.printText(text: string, memobirdID: string, userID: number): Promise<PrintResponse>

Returns: { showapi_res_code, showapi_res_error, result, printcontentid, smartGuid }

printImage(base64Image, memobirdID, userID)

Prints monochrome bitmap image.

await client.printImage(base64Image: string, memobirdID: string, userID: number): Promise<PrintResponse>

Note: Image must be converted to monochrome bitmap first using convertImageToMonochrome().

printFromUrl(url, memobirdID, userID)

Prints content from a web URL.

await client.printFromUrl(url: string, memobirdID: string, userID: number): Promise<PrintResponse>

Note: Works best with static or server-rendered pages. Images must use complete URLs.

printFromHtml(html, memobirdID, userID)

Prints content from HTML source.

await client.printFromHtml(html: string, memobirdID: string, userID: number): Promise<PrintResponse>

Note: CSS must be inline, images must use complete URLs.

getPrintStatus(printcontentid)

Gets print status of a submitted job.

await client.getPrintStatus(printcontentid: string | number): Promise<PrintStatusResponse>

Returns: { showapi_res_code, showapi_res_error, printflag, printcontentID }

  • printflag === 1: Printed successfully
  • printflag === 0: Pending or failed
convertImageToMonochrome(base64Image)

Converts JPG/PNG to monochrome bitmap for printing.

await client.convertImageToMonochrome(base64Image: string): Promise<ConvertImageResponse>

Returns: { showapi_res_code, showapi_res_error, result }

Examples

Print Text

import { MemobirdClient } from 'memobirdsdk';

const client = new MemobirdClient({ ak: 'your-ak' });

// Simple text
await client.printText('Hello World!', 'device-id', userId);

// Chinese text (auto-converts to GBK)
await client.printText('你好世界!', 'device-id', userId);

// Multiline text
await client.printText(`Line 1
Line 2
Line 3`, 'device-id', userId);

Print Image

import { MemobirdClient, imageFileToBase64 } from 'memobirdsdk';

const client = new MemobirdClient({ ak: 'your-ak' });

// Load image from file
const jpgBase64 = await imageFileToBase64('./image.jpg');

// Convert to monochrome bitmap
const converted = await client.convertImageToMonochrome(jpgBase64);

// Print the image
await client.printImage(converted.result!, 'device-id', userId);

Print HTML

const html = `
  <!DOCTYPE html>
  <html>
    <head>
      <style>
        body { font-family: Arial; }
        h1 { font-size: 24px; }
      </style>
    </head>
    <body>
      <h1>Receipt</h1>
      <p>Total: $10.00</p>
    </body>
  </html>
`;

await client.printFromHtml(html, 'device-id', userId);

Error Handling

import { MemobirdClient, APIError, NetworkError } from 'memobirdsdk';

const client = new MemobirdClient({ ak: 'your-ak' });

try {
  await client.printText('Hello', 'device-id', userId);
} catch (error) {
  if (error instanceof APIError) {
    console.error('API Error:', error.resError);
    console.error('Code:', error.resCode);
  } else if (error instanceof NetworkError) {
    console.error('Network Error:', error.message);
  } else {
    console.error('Unknown Error:', error);
  }
}

Poll Print Status

const printResult = await client.printText('Test', 'device-id', userId);
const printId = printResult.printcontentid!;

// Poll until printed
let printed = false;
while (!printed) {
  const status = await client.getPrintStatus(printId);

  if (status.printflag === 1) {
    console.log('Printed successfully!');
    printed = true;
  } else {
    await new Promise(resolve => setTimeout(resolve, 2000));
  }
}

Utility Functions

Text Encoding

import { textToGBKBase64, gbkBase64ToText } from 'memobirdsdk';

// Convert to GBK Base64
const encoded = textToGBKBase64('你好');

// Decode back to UTF-8
const decoded = gbkBase64ToText(encoded);

Content Formatting

import { formatTextContent, formatImageContent, formatMixedContent } from 'memobirdsdk';

// Format text with T: prefix
const textContent = formatTextContent('Hello');
// Returns: 'T:SGVsbG8='

// Format image with P: prefix
const imageContent = formatImageContent('base64-image-data');
// Returns: 'P:base64-image-data'

// Format mixed content
const mixed = formatMixedContent([
  { type: 'text', content: 'Hello' },
  { type: 'image', content: 'image-data' },
  { type: 'text', content: 'World' }
]);
// Returns: 'T:SGVsbG8=|P:image-data|T:V29ybGQ='

Image Utilities

import {
  imageFileToBase64,
  stripDataUrlPrefix,
  isValidBase64Image
} from 'memobirdsdk';

// Load image from file
const base64 = await imageFileToBase64('./image.jpg');

// Strip data URL prefix
const clean = stripDataUrlPrefix('data:image/png;base64,iVBORw0...');

// Validate Base64
if (isValidBase64Image(base64)) {
  console.log('Valid Base64');
}

Timestamp

import { generateTimestamp, isValidTimestamp } from 'memobirdsdk';

// Generate timestamp in Memobird format
const timestamp = generateTimestamp();
// Returns: '2025-12-29 14:30:45'

// Validate timestamp format
if (isValidTimestamp('2025-12-29 14:30:45')) {
  console.log('Valid format');
}

Error Types

MemobirdError

Base error class for all SDK errors.

APIError

Thrown when API returns an error response (showapi_res_code !== 1).

Properties:

  • resCode: The API response code
  • resError: The API error message

NetworkError

Thrown when network request fails.

Properties:

  • originalError: The original error that caused the failure

ValidationError

Thrown when input validation fails.

Properties:

  • field: The field that failed validation

Image Printing Tips

For best results with image printing:

  1. Image width: Use 384 pixels (Memobird paper width)
  2. High contrast: Black and white images work best
  3. Simple designs: Complex images may not render well on thermal printers
  4. Conversion required: Always convert JPG/PNG to monochrome bitmap using convertImageToMonochrome()

HTML/URL Printing Tips

For HTML and URL printing:

  1. Inline CSS: Don't use external stylesheets
  2. Complete URLs: Use absolute URLs for images (not relative paths)
  3. Static content: AJAX-rendered pages may not work properly
  4. Server-rendered: Works best with server-rendered pages
  5. Content size: Keep content size reasonable

TypeScript Support

This SDK is written in TypeScript and provides complete type definitions. All functions, parameters, and return values are fully typed.

import type {
  MemobirdConfig,
  PrintResponse,
  BindUserResponse
} from 'memobirdsdk';

License

ISC

Links

Support

For issues and feature requests, please create an issue on the GitHub repository.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.