
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
qr-local-dev
Advanced tools
Display a QR code in your terminal that points to your machine's local network URL, so you can open your dev server on a phone or another computer instantly.
npm i -D qr-local-dev
Or use it globally:
npm i -g qr-local-dev
qr-local -p 3000
Options:
-p, --port <number>: Port to include in the URL (e.g., 3000)--ports <list>: Comma list of ports to try (e.g., 3000,5173,8080)--http/--https or --protocol <p>: http | https | auto--path <path>: Optional path to append (e.g., /app)-H, --host <ip>: Override detected host/IP-s, --small: Use smaller terminal QR variant-d, --detect: Try common ports and pick a running dev server-c, --copy: Copy the resolved URL to your clipboard--mdns: Broadcast via mDNS/Bonjour (if available)--mdns-name <n>: Custom mDNS service name--force-qr: Print QR even if not a TTY-w, --wait: Wait for the server to become available--wait-timeout <ms>: Max wait time in ms (default 15000)--wait-interval <ms>: Probe interval in ms (default 500)--square: Render square-style QR (uses qrcode-terminal)const { printLocalhostQR } = require("qr-local-dev");
await printLocalhostQR({ port: 3000 });
// Auto-detect server and protocol (useful across frameworks)
await printLocalhostQR({
protocol: "auto",
detect: true,
small: true,
square: true,
copy: true,
mdns: true,
wait: true,
waitTimeout: 15000,
waitInterval: 500,
});
TypeScript users: this package ships .d.ts types. Import as:
import { printLocalhostQR } from "qr-local-dev";
const express = require("express");
const { printLocalhostQR } = require("qr-local-dev");
const app = express();
const port = process.env.PORT || 3000;
app.get("/", (_req, res) => {
res.send("Hello from Express");
});
app.listen(port, async () => {
await printLocalhostQR({ port });
});
Add an instrumentation file so the QR shows right after npm run dev:
instrumentation.js or instrumentation.ts at your project root:// instrumentation.(js|ts) (Next.js App Router)
export async function register() {
// Only run in Node.js runtime (skip Edge) and only in dev
if (process.env.NEXT_RUNTIME !== "nodejs") return;
if (process.env.NODE_ENV === "production") return;
// Prevent duplicate prints during Fast Refresh
const shownKey = "__qr_local_dev_shown__";
if ((globalThis as any)[shownKey]) return;
(globalThis as any)[shownKey] = true;
const { printLocalhostQR } = await import("qr-local-dev");
const envBool = (v?: string) => v === "1" || v === "true";
const portsEnv = process.env.QR_LOCAL_PORTS;
const ports = portsEnv
? portsEnv
.split(",")
.map((p) => Number(p.trim()))
.filter(Boolean)
: undefined;
const delay = Number(process.env.QR_LOCAL_DELAY ?? 300);
setTimeout(() => {
printLocalhostQR({
protocol: process.env.QR_LOCAL_PROTOCOL || "auto",
detect: envBool(process.env.QR_LOCAL_DETECT ?? "1"),
wait: envBool(process.env.QR_LOCAL_WAIT ?? "1"),
waitTimeout: Number(process.env.QR_LOCAL_WAIT_TIMEOUT ?? 15000),
waitInterval: Number(process.env.QR_LOCAL_WAIT_INTERVAL ?? 500),
small: envBool(process.env.QR_LOCAL_SMALL ?? "1"),
square: envBool(process.env.QR_LOCAL_SQUARE ?? "0"),
copy: envBool(process.env.QR_LOCAL_COPY ?? "0"),
mdns: envBool(process.env.QR_LOCAL_MDNS ?? "0"),
mdnsName: process.env.QR_LOCAL_MDNS_NAME,
forceQr: envBool(process.env.QR_LOCAL_FORCE_QR ?? "0"),
host: process.env.QR_LOCAL_HOST,
path: process.env.QR_LOCAL_PATH || "",
port: process.env.PORT ? Number(process.env.PORT) : undefined,
ports,
}).catch(() => {});
}, delay);
}
{
"scripts": {
"dev": "next dev -p 3000"
}
}
npm run dev
Optional HTTPS:
next dev -p 3000 --experimental-https
If you use HTTPS, set protocol: "https" in printLocalhostQR.
Troubleshooting:
instrumentation.js or instrumentation.ts in your project root (or app/).--wait/detect or pin the port with -p.--protocol auto --detect --ports 5173,4173concurrently with next dev -p 3000--protocol auto --detect --ports 3000,4000--protocol auto --detect --ports 4321--protocol auto --detect --ports 5173--protocol auto --detect --ports 4200--protocol auto --detect --ports 8080General advice:
--protocol auto will probe and pick it.-c/--copy so you can paste the URL quickly on your device.Install helpers once:
npm i -D concurrently wait-on
Add one of these to your app's package.json scripts.
{
"scripts": {
"dev": "concurrently -k -s first \"next dev -p 3000\" \"wait-on http://localhost:3000 && qr-local --protocol auto --detect --wait\""
}
}
{
"scripts": {
"dev": "concurrently -k -s first \"vite\" \"wait-on http://localhost:5173 && qr-local --protocol auto --detect --ports 5173,4173 --wait\""
}
}
{
"scripts": {
"dev": "concurrently -k -s first \"nuxi dev -p 3000\" \"wait-on http://localhost:3000 && qr-local --protocol auto --detect --wait\""
}
}
{
"scripts": {
"dev": "concurrently -k -s first \"astro dev\" \"wait-on http://localhost:4321 && qr-local --protocol auto --detect --ports 4321 --wait\""
}
}
{
"scripts": {
"dev": "concurrently -k -s first \"vite\" \"wait-on http://localhost:5173 && qr-local --protocol auto --detect --ports 5173 --wait\""
}
}
{
"scripts": {
"dev": "concurrently -k -s first \"ng serve --host 0.0.0.0 --port 4200\" \"wait-on http://localhost:4200 && qr-local --protocol auto --detect --ports 4200 --wait\""
}
}
{
"scripts": {
"dev": "concurrently -k -s first \"vue-cli-service serve --host 0.0.0.0 --port 8080\" \"wait-on http://localhost:8080 && qr-local --protocol auto --detect --ports 8080 --wait\""
}
}
{
"scripts": {
"dev": "concurrently -k -s first \"remix dev\" \"wait-on http://localhost:3000 && qr-local --protocol auto --detect --ports 3000 --wait\""
}
}
Notes:
--square for a square-looking QR: append --square to the QR command.--copy to copy URL to clipboard automatically.--protocol auto (it will probe) or pass --https.os.networkInterfaces() inside the current runtime.qr-local -H 192.168.x.y -p 3000.0.0.0.0.--network host allows containers to use the host network (QR will point to the host IP).--force-qr to print anyway or rely on the URL line.--force-qr in non-TTY contexts.FAQs
Print a QR code for your local dev server in the terminal
We found that qr-local-dev demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.