Printer Hacks for Fun

4shub profile image Shubham Naik ・2 min read

Earlier today I was playing around with the web usb api.

Ended up making a typewriter-like tool!

If you have an epson printer lying around, the code below will work. Though I've only tested this on Chrome.

<!DOCTYPE html>
    <meta charset="UTF-8">
    <title>Garbage Typewriter</title>
    <div>Requires an epson printer to work</div>
    <form id="form-container">
            Type in a sentence <br/>
            <input type="text" id="typewriter-input"/>
            <button type="button" id="find-printer">Find Printers</button>
            <button  type="button" id="connect-printer">Connect Printer</button>
            <button  type="button" id="cut-printer">Cut Page</button>

        // Epson printer specific codes
        const INIT_PRINT = '\x1B' + '\x40';
        const LINE_BREAK = '\x0A';
        const CUT_PAPER = '\x1B' + '\x69';

        // USB devices can have 1-16 possible endpoints that can be connected to
        // we don't know what endpoint we need to connect to to send a successful print command
        // so we just start at endpoint 1, and we shuffle until 16 to see which endpoint the printer is using
        let endpointNumber = 1;

        const getDevices = async () => navigator.usb.getDevices().then(([printer]) => Promise.resolve(printer));

        const sendMessageToPrinter = (device, content) => {
            const encoder = new TextEncoder();

            const data = encoder.encode(content);

            console.log('trying ', endpointNumber)

            return device.transferOut(endpointNumber, data);

        const startPrint = async  (device, content) => sendMessageToPrinter(device, content.join('')).catch(e => {
            if (e.message.includes('The specified endpoint is not part of a claimed and selected alternate interface')) {
                if (endpointNumber < 15) {
                    endpointNumber = endpointNumber + 1;
                    startPrint(device, content);


            console.error('Send Error:', e);
        }).then(e => console.log(e))

        let device;

        const requestPrinter = () => {
                filters: [],

        const initPrinter = async () => {
            device = await getDevices();

            await device.open();
            await device.selectConfiguration(1);


            endpointNumber = 1;

        const cutPrinter = () => {

        document.getElementById('form-container').onsubmit = (e) => e.preventDefault();

        let buffer = '';
        document.getElementById('typewriter-input').addEventListener('keydown', (e) => {
            const code = (e.keyCode ? e.keyCode : e.which);

            if  (code === 13) { //Enter keycode
                startPrint(device, [INIT_PRINT, buffer, LINE_BREAK]);
                setTimeout(() => document.getElementById('typewriter-input').focus(), 100)
                buffer = '';


            buffer += String.fromCharCode(code);

        document.getElementById('find-printer').onclick = requestPrinter;
        document.getElementById('connect-printer').onclick = initPrinter;
        document.getElementById('cut-printer').onclick = cutPrinter;


Posted on by:

4shub profile

Shubham Naik


I'm a software engineer who's passionate about optimization and accessibility.


markdown guide

thank u for sharing with us! looks great! wow! it is really interesting and useful hacks! thank u a lot for sharing this information with us! but unfortunately, my old printer was broken and I had to buy a new one in a few days. The solvation for me was this website mrdepot.ca where is provided a bunch of quality office supplies at a reasonable price. They claim that they have a quality and durable models from trusted brands such as Samsung, Canon, HP and etc. Try to look over this site, if u have time!