Just File Tools

QR Code Reader

Scan a QR code with your camera or decode from an image — no app install

How to QR Code Reader Online

Decode a QR code with your camera or by uploading an image — runs entirely in your browser.

  1. Pick a mode: 'Live camera' scans in real-time from your webcam; 'Upload image' decodes a still photo or screenshot.
  2. Live camera: click Start, grant browser camera permission (one-time), point the camera at the QR code. The tool scans every frame and decodes the instant a code is found.
  3. Upload image: drop a photo or screenshot of a QR code. Phone photos work best — they're high-resolution and well-lit.
  4. The decoded payload appears below. For URLs, mailto, tel, sms, and other standard schemes, an 'Open in new tab' shortcut is offered.

About QR Code Reader

QR codes solved one problem perfectly: getting a URL from physical space into a phone without typing. A printed code on a poster, a screen in a store, a business card — point your camera, get the link. Every iPhone and Android phone has this built into the camera app, which is the right place for it. So why a QR reader on a website?

Because sometimes you have a QR code in a place that isn't your phone's camera. A screenshot someone sent you. A QR code embedded in a PDF or in an email. A photo of a code your phone's native scanner couldn't read because the lighting was bad. Or you're on a desktop without an easy way to point a phone at the screen and you just want to know what the code says without typing the URL manually. That's the niche this tool covers.

The implementation uses **jsQR**, a JavaScript QR decoder that runs entirely in your browser. It's small (about 50 KB minified) and fast. For live scanning, the tool grabs your camera stream via `getUserMedia`, draws each frame to a canvas, extracts the raw pixel data, and feeds it to jsQR. When a code is detected, the camera stops automatically and the decoded payload appears. For image scanning, the same pipeline runs on a single still image you upload.

A QR code's payload can be:

- **A plain URL** (`https://example.com/path`). The most common case. The tool detects the URL scheme and offers an 'Open in new tab' link. - **A short text** (anything that doesn't start with a URL scheme). Displayed verbatim, copyable with one click. - **A structured payload** that follows one of the QR conventions: Wi-Fi credentials (`WIFI:T:WPA;S:network;P:password;;`), vCard contacts (`BEGIN:VCARD...END:VCARD`), calendar events (`BEGIN:VEVENT...`), email composition (`mailto:address?subject=&body=`), SMS composition (`sms:number?body=text`), telephone dialing (`tel:+1234567890`), geolocation (`geo:37.78,-122.40`), cryptocurrency payments (`bitcoin:address?amount=0.01`). The tool shows the raw payload — your phone or OS knows how to handle each format if you copy and paste it into the right app.

A few practical notes.

**Live scanning is faster than image upload for most cases.** The frame-by-frame approach finds codes quickly under good lighting (typically under a second from camera-start to decoded). Image upload is slower per-attempt because you have to take the photo, switch to the browser, drop the file. But upload is more reliable for tricky codes — bad lighting, low resolution, weird angles — because you can pick the best frame yourself.

**The 'environment' camera is requested.** On phones this is the back camera, which is what you usually want — it's higher quality and points away from you. On laptops there's only one camera typically, so this hint is ignored. If you specifically want the front camera (selfie camera) on a phone, the OS's native QR scanner is the better tool — this page doesn't expose a camera-switch UI to keep the surface minimal.

**Camera permission is one-time per origin.** Modern browsers remember the permission grant for justfiletools.com (or your domain). The next visit doesn't prompt again. You can revoke the permission in your browser's site settings if you want.

**Privacy is core.** This is the whole reason the tool exists in this browser-only form. Online QR scanners that upload your image to a server have a clear failure mode: your QR code could contain a Wi-Fi password, a session token, a private payment request, a private vCard — none of which you want sitting in someone else's logs. This tool's jsQR runs in your browser, full stop. The camera stream is a local HTMLMediaStream; the image you upload is a local Blob; the decoding is a JS function in this page's bundle. Verify in DevTools — the network panel stays empty during operation. The camera light turns off as soon as you stop the scan or a code is found.

**Edge cases handled correctly.**

- **No camera available**: the tool detects `NotFoundError` and tells the user to use the Image Upload tab instead. - **Permission denied**: the tool detects `NotAllowedError` and points to the Image Upload fallback with a clear message about how to grant permission later. - **Code not found in image**: the tool says so explicitly and suggests retrying with a higher-resolution or less-skewed image. It doesn't silently fail. - **Page unmount / mode switch**: the camera stream is stopped and the animation-frame loop is cancelled, so no memory leaks and no zombie camera light after navigation.

**What this tool deliberately doesn't do**:

- **Decode non-QR barcodes** (Code 128, EAN, UPC, ITF, etc.). For those, a different library is needed; jsQR is QR-only. If users want general barcode reading, a separate tool is the right answer — bundling ZXing into the QR reader would be wasteful for the typical user. - **Generate QR codes**. The existing QR Code Generator tool on this site covers that direction. - **Continuously scan after finding one code.** The first code stops the camera. If you want to scan a sequence, click Start again. This is intentional — most users are scanning one thing and want a clear 'done' state.

In a world where every phone has a built-in QR scanner, the niche use cases — screenshots, embedded codes, no-phone scenarios — are the reason this exists. It's small, it's fast, it stays in your tab.

Frequently Asked Questions

Why does the page need camera access?

Because live scanning requires a video feed from your camera. The video stream is processed frame-by-frame in your browser via jsQR to find and decode a QR code. The image data **never leaves your tab** — it's not uploaded, recorded, or sent anywhere. The camera turns off the instant a code is detected (or when you click Stop). If you'd rather not grant camera access, use the 'Upload image' tab to scan a photo or screenshot of a QR code instead.

Which camera does it use?

On phones and tablets, it requests the **back camera** (the higher-quality one most QR codes are scanned with) using `facingMode: 'environment'`. On laptops with only a front-facing camera, it uses whatever is available. If you want to switch cameras on a device with multiple, do so in your OS's camera settings before granting permission, or use the Upload Image fallback.

Why does scanning sometimes fail?

Three common causes. **Lighting** — QR codes need adequate contrast between the dark and light modules; very dim or harshly back-lit scenes confuse the decoder. **Distance and angle** — hold the camera roughly perpendicular to the code, with enough distance that the whole code fits in frame but close enough that each module is at least a few pixels wide. **Resolution** — older laptop webcams cap at 720p; tiny QR codes printed on receipts may not be readable from arm's length. If live scanning struggles, take a clear photo with your phone and use the Upload Image tab — the still image gives jsQR more time and pixels to work with.

What kinds of QR data does it decode?

Every standard QR payload: plain URLs (`https://...`), email links (`mailto:`), phone links (`tel:`), SMS links (`sms:`), Wi-Fi credentials (`WIFI:T:WPA;S:network;P:pass;;`), vCard contacts (`BEGIN:VCARD...`), calendar events (`BEGIN:VEVENT...`), geolocation (`geo:lat,lon`), Bitcoin payment requests (`bitcoin:address?amount=`), magnet links, and plain text. The decoded payload appears verbatim. URLs and known scheme links get a clickable 'Open in new tab' shortcut.

Can it scan multiple QR codes at once?

Not in this version — jsQR returns the first code it detects in the frame. If your image has multiple codes side-by-side, crop or screenshot each one separately and run them through the Upload Image tab one at a time. Most real-world scenarios (a poster, a receipt, a business card) have exactly one code per image, so this isn't a limitation in practice.

Does it support other barcode formats like Code 128 or EAN?

No, only QR codes. jsQR is focused on QR specifically and is small and fast. For one-dimensional barcodes (UPC, EAN, Code 128, ITF), you'd need a different library like ZXing — which is much heavier and would slow the page down for everyone. If demand is high we can add a separate Barcode Reader tool that lazy-loads ZXing only when needed.

Is anything sent to a server?

No. The camera stream is rendered to a `<video>` element in your browser. Each frame is drawn to a canvas, the pixel data is read out, and jsQR (a JS library bundled with this page) decodes it locally. Same for image uploads — the photo is read with `URL.createObjectURL` and decoded in the browser. The network panel stays empty during operation. Verify in DevTools.