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

prusalink-client

v1.0.1

Published

Unofficial Node.js client for Prusa printers via the PrusaLink API (Core One, MK4, XL, MINI+)

Readme

prusalink-client

Unofficial Node.js client for Prusa printers via the PrusaLink API. Not affiliated with or endorsed by Prusa Research.

A zero-dependency Node.js client for the Prusa Core One, MK4, XL, and MINI+ using the PrusaLink v1 REST API with HTTP Digest authentication.

  • No external packages — uses Node 20+ built-in fetch and crypto
  • Full TypeScript types included
  • Covers the full PrusaLink v1 API: status, jobs, files, storage, cameras, uploads
  • Includes a CLI (prusalink) and an importable PrusaClient class

Requirements

  • Node.js 20.6 or later
  • Prusa Core One (or MK4/XL/MINI+) running PrusaLink firmware 4.7.0+
  • Printer and computer on the same local network

Installation

npm install prusalink-client

Setup

Configure credentials

Copy the example config and fill in your printer's details:

cp .env.example .env

Edit .env:

PRUSA_HOST=192.168.1.x
PRUSA_USERNAME=maker
PRUSA_PASSWORD=your_password_here

Finding your credentials: On the printer touchscreen go to Settings → Network → Login credentials. The username is maker by default.

The .env file is gitignored and will never be committed.


CLI Usage

After installing, credentials are read from environment variables:

# With a .env file (Node 20.6+)
node --env-file=.env $(which prusalink) status

# Or export directly
export PRUSA_HOST=192.168.1.x
export PRUSA_USERNAME=maker
export PRUSA_PASSWORD=yourpassword
prusalink status

When using from this repo directly:

node --env-file=.env bin/prusalink.js <command>
# or via npm scripts:
npm run status

Commands

| Command | Description | |---------|-------------| | status | Printer state, temperatures, fan speeds, current job progress | | job | Active print job details (id, progress, time remaining) | | files | List files on the printer (auto-detects USB/local storage) | | storage | Storage devices with available free space | | info | Printer serial number, nozzle diameter, hostname | | cameras | List connected cameras | | snap | Capture a camera snapshot and save as snapshot.png | | legacy | OctoPrint-compatible printer + job state (fallback) |

Example output

=== Printer Status ===
State        : PRINTING
Nozzle temp  : 205.4°C / target 205°C
Bed temp     : 60°C / target 60°C
Speed        : 100%
Flow         : 100%
Z axis       : 17 mm
Hotend fan   : 8495 RPM
Print fan    : 5129 RPM

=== Current Job ===
File         : (on USB/SD)
Progress     : 79.0%
Time left    : 0h 23m

Using PrusaClient in Your Own Script

Import the client class directly for use in automation, dashboards, bots, etc.

import { PrusaClient } from "prusalink-client";

const printer = new PrusaClient({
  host: process.env.PRUSA_HOST,
  username: process.env.PRUSA_USERNAME,
  password: process.env.PRUSA_PASSWORD,
});

Run your script with:

node --env-file=.env your-script.js

API Reference

printer.version()

Returns PrusaLink API version, firmware version, and server info.

const v = await printer.version();
// { api: "2.0.0", firmware: "6.5.3+12780", server: "2.1.2", hostname: "prusa-core-one", ... }

printer.info()

Returns static printer details.

const info = await printer.info();
// { serial: "4914-...", nozzle_diameter: 0.4, mmu: false, hostname: "prusa-core-one", min_extrusion_temp: 170 }

printer.status()

Main polling endpoint. Returns combined printer state, temperatures, and active job.

const status = await printer.status();

status.printer.state          // "IDLE" | "PRINTING" | "PAUSED" | "FINISHED" | "ERROR" | ...
status.printer.temp_nozzle    // current nozzle temp (°C)
status.printer.target_nozzle  // target nozzle temp (°C)
status.printer.temp_bed       // current bed temp (°C)
status.printer.target_bed     // target bed temp (°C)
status.printer.axis_z         // Z position (mm)
status.printer.speed          // speed multiplier (%)
status.printer.flow           // flow rate (%)
status.printer.fan_hotend     // hotend fan RPM
status.printer.fan_print      // print fan RPM

status.job?.progress          // print progress (0-100)
status.job?.time_remaining    // seconds remaining
status.job?.time_printing     // seconds elapsed
status.job?.id                // job ID (use for pause/cancel)

printer.job()

Returns the active job object, or null if nothing is printing.

const job = await printer.job();
if (job) {
  console.log(`Job #${job.id} — ${job.progress}% complete`);
}

printer.pauseJob(id)

printer.resumeJob(id)

printer.cancelJob(id)

Pause, resume, or cancel a job by its ID.

const status = await printer.status();
const jobId = status.job?.id;

await printer.pauseJob(jobId);
await printer.resumeJob(jobId);
await printer.cancelJob(jobId);

printer.files(storage, path)

List files on the printer. storage is "local", "usb", or "sdcard". Path defaults to "/".

const data = await printer.files("usb", "/");
for (const f of data.children ?? []) {
  console.log(f.name, f.size);
}

printer.printFile(storage, path)

Start printing a file that already exists on the printer.

await printer.printFile("usb", "/my-model.bgcode");

printer.uploadFile(storage, remotePath, data, options)

Upload a .bgcode or .gcode file to the printer.

import { readFileSync } from "fs";

const file = readFileSync("./my-model.bgcode");

await printer.uploadFile("usb", "/my-model.bgcode", file, {
  printAfterUpload: true,  // start printing immediately (default: false)
  overwrite: true,         // overwrite if file exists (default: false)
});

printer.deleteFile(storage, path)

Delete a file from the printer.

await printer.deleteFile("usb", "/old-model.bgcode");

printer.storage()

Returns available storage devices with capacity info.

const data = await printer.storage();
for (const s of data.storage_list) {
  console.log(s.type, s.path, s.available);
}

printer.transfer()

Returns the current file transfer progress, or null if no transfer is active.

const t = await printer.transfer();
if (t) console.log(`Transfer: ${t.progress}%`);

printer.cameras()

Returns a list of connected cameras and their configuration.

const cams = await printer.cameras();

printer.snapshot(cameraId?)

Returns an ArrayBuffer containing a PNG image from the camera. Omit cameraId to use the default camera.

import { writeFileSync } from "fs";

const buf = await printer.snapshot();
writeFileSync("snapshot.png", Buffer.from(buf));

printer.reboot()

printer.restartLink()

Reboot the printer or restart the PrusaLink service only.

await printer.restartLink(); // restarts PrusaLink, not the full printer
await printer.reboot();      // full printer reboot

Legacy OctoPrint-compatible endpoints

These mirror the OctoPrint API and are useful as a fallback or for compatibility with existing OctoPrint tooling.

await printer.legacyPrinter(); // GET /api/printer
await printer.legacyJob();     // GET /api/job
await printer.legacyFiles();   // GET /api/files/local

Example: Poll until print finishes

import { PrusaClient } from "./src/client.js";

const printer = new PrusaClient({
  host: process.env.PRUSA_HOST,
  username: process.env.PRUSA_USERNAME,
  password: process.env.PRUSA_PASSWORD,
});

async function waitForFinish(intervalMs = 10000) {
  console.log("Watching print job...");
  while (true) {
    const status = await printer.status();
    const state = status.printer.state;
    const progress = status.job?.progress ?? 0;
    const remaining = status.job?.time_remaining;

    const mins = remaining != null ? Math.ceil(remaining / 60) : "?";
    console.log(`[${new Date().toLocaleTimeString()}] ${state} — ${progress}% — ${mins}m remaining`);

    if (state === "FINISHED" || state === "STOPPED" || state === "ERROR") {
      console.log(`Print ended with state: ${state}`);
      break;
    }

    await new Promise(r => setTimeout(r, intervalMs));
  }
}

waitForFinish();

Run with:

node --env-file=.env poll.js

Example: Upload and print a file

import { readFileSync } from "fs";
import { PrusaClient } from "./src/client.js";

const printer = new PrusaClient({
  host: process.env.PRUSA_HOST,
  username: process.env.PRUSA_USERNAME,
  password: process.env.PRUSA_PASSWORD,
});

const file = readFileSync("./my-model.bgcode");

await printer.uploadFile("usb", "/my-model.bgcode", file, {
  printAfterUpload: true,
  overwrite: true,
});

console.log("Uploaded and started printing.");

Project Structure

prusa-core-one-api/
├── src/
│   ├── client.js     # PrusaClient class — all API methods
│   ├── digest.js     # HTTP Digest auth (native fetch + crypto)
│   └── index.js      # CLI runner
├── .env              # Your credentials (gitignored)
├── .env.example      # Safe template to share/commit
├── .gitignore
└── package.json

Authentication Notes

The Prusa Core One uses HTTP Digest (MD5) authentication — not Basic auth or API keys. This client implements Digest auth from scratch using Node's built-in crypto module, so no third-party packages are required.

The legacy /api/* endpoints technically support an X-API-Key header, but Digest is the recommended and more compatible method for firmware 6.x+.


Supported Printers

This client targets the Prusa Core One but works with any PrusaLink-enabled printer running API v2.0.0+:

| Printer | Min Firmware | |---------|-------------| | Core One | 6.x | | MK4 / MK4S | 4.7.0 | | XL | 4.7.0 | | MINI / MINI+ | 5.1.0 | | MK3.9 | 4.7.0 |


Credits & Resources

This client was built using the following resources:

Official Prusa Sources

  • prusa3d/Prusa-Link-Web — Official Prusa repository containing the OpenAPI specifications (spec/openapi.yaml and spec/openapi-legacy.yaml) that define all PrusaLink v1 and legacy API endpoints, schemas, and authentication requirements.
  • Prusa Connect Camera API — Prusa help article documenting the camera streaming and snapshot API.

Community & Reference Implementations

  • jamesgopsill/prusa-link — Community TypeScript/Node.js client for PrusaLink, used as a reference for API method structure and authentication patterns. MIT license.
  • PrusaLinkPy — Python client for PrusaLink, used as a reference implementation for endpoint behavior and response handling.

Integration Documentation


This is an unofficial project. Prusa, PrusaLink, and Prusa Connect are trademarks of Prusa Research a.s.