Open source
Making QR codes offline and privately
By Sam Moreton · updated 13 August 2026
8 min read · Updated 13 August 2026
The two meanings of offline
| What you mean | What you actually need | Does openqr.uk do it? |
|---|---|---|
| My data must not be uploaded | A generator that encodes in the browser | Yes. Nothing you type is sent anywhere. |
| I have no internet connection at all | A tool installed on your machine | No. The page has to load first. |
Most people want the first. It is the one that matters when you are encoding a Wi-Fi password, a private link or someone's phone number, and it is satisfied by any generator that does its work client-side. The second is a smaller group with a real problem, and it needs a local tool. Both are covered below.
Why it matters what you are encoding
A QR code is not automatically sensitive. A link to your public homepage is fine wherever you make it. But several of the most common payloads are things you would not paste into a random website if the question were put to you plainly:
- Wi-Fi credentials. A Wi-Fi QR code contains your network name, security type and the password in plain text. This is the highest-stakes payload there is, and it is the single most common reason to care about where encoding happens.
- Personal contact details. A vCard carries a name, mobile number, email and often a home or office address.
- Unlisted or private URLs. An internal document, a staff portal, a client preview link, a patient booking page. Unlisted only stays unlisted if it is not collected.
- Anything under a data-protection obligation. If you would have to record it in a processing register when a third party receives it, that includes the QR generator you pasted it into.
How to check whether a generator uploads your data
You do not have to take anyone's word for this, including ours. Every mainstream browser ships the tool to check, and the whole test takes under a minute.
In Chrome, Edge, Firefox or Safari:
- 1
Open developer tools
Press F12, or Ctrl+Shift+I on Windows and Linux, or Cmd+Option+I on a Mac. In Safari, enable the Develop menu in Settings first.
- 2
Go to the Network tab
Then reload the page once so it starts recording from a clean state.
- 3
Clear the log
Use the clear button so that only what happens next is listed. Everything currently there is just the page loading.
- 4
Type your content into the generator
Use something distinctive you can search for, like a fake password such as
needle12345, rather than your real one. - 5
Watch the list, then search it
If the code appears in the preview and no new request has appeared, encoding happened locally. If requests did appear, use the search box to look for
needle12345across them. Finding it in a request body means your content was transmitted.
Analytics requests are not the same as uploading your payload
Most sites, this one included, fire some requests while you use them: page views, fonts, error reporting. That is why the search step matters more than the presence of requests. The question is not whether the page talks to a server. It is whether what you typed is in any of it.
Run that test on OpenQR and your content will not appear, because the encoder runs on your device. It is also why the tool needs no account: there is nothing arriving at a server that would need to belong to anybody. The privacy policy says the same thing in prose, and because the generator is open source, you can go a step further than the network tab and read the code that does it.
Generating with no connection at all
If you are on a plane, in a facility with no outside network, or on an air-gapped machine, you need something installed locally. Being straight about it: openqr.uk will not help you here. It is a website, it has to load, and it does not register a service worker, so an offline reload will fail like any other page. These will work:
| Option | Good for | How |
|---|---|---|
qrencode on the command line | One-off codes, and generating thousands from a script | Install libqrencode from your package manager, then qrencode -o code.png 'your text' |
A Python script with segno | Batch generation, spreadsheets, automated documents | pip install segno, then a handful of lines. See the libraries guide |
| A self-hosted copy of the generator | A team on an internal network who want a real interface, not a terminal | Deploy it on the LAN. See self-hosting |
For a whole team on a closed network, the self-hosted route is usually the right one. It needs no database and no secrets, so it is closer to serving a static site than running an application, and everyone gets a normal interface rather than a command they have to remember.
Scanning offline is a different question, and the answer is better
This is the part people most often have backwards, and it decides whether your printed code works in a basement, a rural venue or a plane cabin.
- A static QR code needs no connection to be read. The data is in the pattern. The phone's camera decodes it locally, so the content appears with no signal at all.
- What happens next may still need a connection. A static code containing a URL decodes offline, then the browser needs the network to open the page. A code containing plain text, a phone number or Wi-Fi credentials needs nothing further, which is why Wi-Fi codes work in a dead spot.
- A dynamic code always needs a connection. It contains a short link that must be resolved by a redirect service before anything happens. No signal, no destination.
Where this catches people out
Conference basements, festival fields, lifts, aircraft and rural venues. If your audience may scan somewhere with no signal, put the essential information in a static code, and do not rely on a dynamic one. This is a real trade-off against editability, not a reason to avoid dynamic codes everywhere.
The full comparison, including what you give up in each direction, is in static vs dynamic QR codes.
A short checklist
- Decide which offline you need: private encoding, or no connection.
- For privacy, run the network-tab test above on whatever tool you are considering. Thirty seconds, and it settles the question for good.
- Never paste a live Wi-Fi password into a tool that uploads it. Use a client-side generator, a local one, or change the password afterwards.
- For no connection, install
qrencodeor self-host. Do not rely on a website having cached itself. - If scanners may have no signal, choose a static code so the payload survives without a network.
- Test the finished code on a real phone before printing. The testing guide covers doing it properly.