A modern, web-based label editor for the Phomemo D30 thermal label printer. This application uses Web Bluetooth to connect directly to your printer from the browser, eliminating the need for the official app and its paywalls.
-
Multiple Label Types
- Text labels with customizable fonts and sizes
- Icons from built-in library
- Barcodes (CODE128)
- QR codes
- Custom images
-
Direct Browser Printing
- Web Bluetooth connection
- No drivers or apps required
- Works in Chrome and Edge browsers
-
Advanced Calibration
- Adjustable DPI/scaling
- Test pattern printing
- Real-time preview
-
Fixed Printing Issues
- Solved the 120mm extra feed problem
- Proper ESC/POS command sequences
- Based on reverse-engineered protocol from phomemo-tools
- Node.js 18+ and npm
- Chrome or Edge browser (for Web Bluetooth support)
- Phomemo D30 printer
-
Clone or download this repository
-
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Open your browser to
http://localhost:3000
- Enable Bluetooth on your computer
- Turn on your Phomemo D30 printer
- Open the application in Chrome or Edge
- Click "Connect & Print"
- Select your printer from the Bluetooth pairing dialog
- Select the "Text" tab
- Enter your text in the textarea
- Adjust font size with the slider
- Preview updates automatically
- Select the "Icons" tab
- Choose an icon from the grid
- Optionally add a text label below the icon
- Select the "Barcode" tab
- Enter barcode data (numbers/text)
- CODE128 format is used
- Select the "QR Code" tab
- Enter URL or text data
- Adjust label size for better scanning
- Select the "Image" tab
- Upload an image file
- Image will be automatically scaled and rotated
If your labels are printing too long or too short:
- Scroll to the "Printer Calibration" section
- Print a test pattern first:
- Click "Test Pattern"
- Print it
- Measure the ruler marks
- Adjust the "DPI / Scaling Factor" slider:
- If 40mm prints as 50mm, decrease the value
- If 40mm prints as 30mm, increase the value
- Default is 8 px/mm (203 DPI)
The original implementation had a bug where printing a 40mm label would result in 120mm of feed (80mm wasted). This has been fixed with corrected ESC/POS commands.
If you still experience extra feeding:
- Check the "Use No-Feed Footer" checkbox
- Try printing again
- This uses an alternative footer command sequence
Based on reverse-engineered ESC/POS commands from the phomemo-tools project:
Header:
0x1b 0x40 // ESC @ - Initialize printer
0x1b 0x61 0x01 // ESC a 1 - Center justification
0x1f 0x11 0x02 0x04 // Phomemo-specific init
Block Marker (per image block):
0x1d 0x76 0x30 // GS v 0 - Print raster bit image
0x00 // Mode: 0 (normal)
[width_low] [width_high] // Width in bytes (16-bit LE)
[height_low] [height_high] // Height in pixels (16-bit LE, max 255)
Footer:
0x1b 0x64 0x02 // ESC d 2 - Feed 2 lines
0x1b 0x64 0x02 // ESC d 2 - Feed 2 lines (repeated)
0x1f 0x11 0x08 // Phomemo-specific end sequence
0x1f 0x11 0x0e
0x1f 0x11 0x07
0x1f 0x11 0x09
Alternative No-Feed Footer:
0x1f 0x11 0x08 // Only Phomemo end sequence
0x1f 0x11 0x0e // No ESC d commands
0x1f 0x11 0x07
0x1f 0x11 0x09
- Corrected header dimensions: Now uses actual pixel dimensions instead of mm
- Fixed footer commands: Reduced feed from indefinite to 2 lines
- Proper byte alignment: Canvas width is always a multiple of 8
- Block-based sending: Images are sent in 255-line blocks as per protocol
phomemo-d30/
├── src/
│ ├── lib/
│ │ ├── PhomemoD30Printer.ts # Printer protocol & Bluetooth
│ │ ├── CanvasRenderer.ts # Canvas drawing utilities
│ │ └── icons.ts # Icon library
│ ├── App.tsx # Main React component
│ ├── App.css # Styles
│ └── main.tsx # Entry point
├── index.html
├── package.json
├── vite.config.ts
└── tsconfig.json
npm run buildThe built files will be in the dist/ directory. Deploy them to any static hosting service.
- ✅ Chrome 56+ (recommended)
- ✅ Edge 79+
- ❌ Firefox (no Web Bluetooth support)
- ❌ Safari (no Web Bluetooth support)
- Ensure Bluetooth is enabled on your computer
- Make sure the printer is turned on
- Try turning the printer off and on again
- Refresh the browser page
- Use the calibration slider to adjust pixels per mm
- Print a test pattern to measure accurately
- Default is 8 px/mm, try values between 7-9
- Enable "Use No-Feed Footer" checkbox
- This may indicate the printer is using different commands
- Try different label size settings
- Make sure you've entered content (text, selected icon, etc.)
- Check browser console for errors
- Try refreshing the page
- Based on the original HTML example from the community
- Protocol information from phomemo-tools by vivier
- ESC/POS command reference from EPSON and Star Micronics documentation
MIT License - feel free to use and modify for your needs.
Contributions are welcome! If you've found other solutions to the feed issue or discovered additional Phomemo D30 commands, please share.
Potential features to add:
- Label templates library
- Print history
- Multi-label printing
- Export labels as images
- Cloud sync for designs
- Support for other Phomemo models (M02, M110, M120)