Open source
Self-hosting a QR code generator
By Sam Moreton · updated 13 August 2026
9 min read · Updated 13 August 2026
First, check whether you need to
Most people who go looking for a self-hosted QR generator want one of two things: their data not leaving their control, or a guarantee the tool will still exist next year. Self-hosting solves the second. It often does not change the first, and that surprises people.
A static QR code is generated by pure arithmetic. The encoder turns your text into a bit pattern following ISO/IEC 18004, adds Reed-Solomon error correction, and draws the result. None of that needs a server. A generator written properly does the whole job in your browser, so the Wi-Fi password or private URL you typed was never transmitted anywhere. Self-hosting a tool that already works that way moves nothing off any wire that was carrying it.
Test the tool you have before replacing it
Open your browser's developer tools, switch to the Network tab, then type your content into the generator and watch. If a request fires carrying what you typed, that tool uploads your data and self-hosting would genuinely help. If nothing fires, it is already local. The offline guide walks through this check in detail.
So the honest list of reasons to self-host is narrower than the marketing suggests, but the reasons that survive are good ones:
- An air-gapped or internal-only network where staff cannot reach an external site at all.
- A policy requirement that tooling be owned and auditable, common in healthcare, government and finance. Being able to point at the source you are running is the deliverable.
- Embedding it in your own product, so your users generate codes inside your interface rather than being sent elsewhere.
- Longevity on your terms. A hosted tool can change its pricing, its terms, or stop existing. A copy you run changes when you change it.
- Volume without a rate limit, if you are generating codes in bulk from a build step or an internal script.
If none of those describe you, the free hosted generator does the same job with no server to patch. That is not a sales line: an unmaintained internal deployment is a worse security position than a tool that never receives your data in the first place.
What the public repository actually contains
This is where most open-core projects are vague, so here it is plainly. The public repository at github.com/open-qr/openqr is the generator, licensed AGPL-3.0. It is deliberately small and easy to fork.
| In the AGPL repo | Hosted only | |
|---|---|---|
| Static QR generation (all payload types) | Yes | |
| Styling: colours, gradients, dot and corner styles, logos, frames | Yes | |
| Exports: PNG, JPEG, WebP to 4096px, SVG, PDF | Yes | |
| Runs with no backend at all | Yes | |
| Accounts and the dashboard | Hosted | |
| Dynamic (editable) codes and short links | Hosted | |
| Scan analytics | Hosted | |
| REST API and MCP server | Hosted |
The account layer is not in the public repository, so you cannot self-host dynamic codes from it. That is worth stating before you start rather than discovering after you have provisioned a database. If editable destinations are the reason you are here, read the dynamic QR codes guide first: the feature is a redirect service, and a redirect service is a thing somebody has to keep running.
Deploying it
The generator is a standard Next.js application with no database, no environment variables and no secrets. That is the whole configuration surface, which is the nicest thing about deploying it.
From a clean checkout:
- 1
Clone and install
git clone https://github.com/open-qr/openqr.git, thenpnpm install. - 2
Run it locally first
pnpm devstarts it onhttp://localhost:3011. Generate a code and export it before you deploy anything, so you know the build you are shipping works. - 3
Build
pnpm buildproduces a standalone output, so the built artefact carries what it needs to run. - 4
Serve
pnpm startserves on port 3011. Put it behind whatever reverse proxy you already use, and terminate TLS there as normal.
Because it needs no state, it is comfortable on hardware you would not normally call a server: a small VPS, a Raspberry Pi on an office LAN, a container on an existing host, or any platform that runs Node. There is no migration step, no backup story and no credentials to rotate, because there is nothing to store.
Embedding it instead of hosting a whole site
If what you want is the generator inside your own application rather than a separate site, the Generator component is self-contained and takes an embedded prop plus your own header, so you can drop it into an existing page and brand it as yours.
What AGPL-3.0 asks of you
The AGPL is often treated as frightening. For the ordinary case it asks almost nothing, and it is worth understanding precisely rather than avoiding the project over a rumour.
- Running it unmodified, internally or publicly: use it freely. Keep the licence and copyright notices in place. There is nothing to publish.
- Modifying it for your own private use, never exposed over a network: also fine, and nothing to publish.
- Running a modified version as a network service others use: this is the clause that makes the AGPL different from the GPL. You must offer those users the source of your modified version, under the same licence.
- The codes you generate: entirely yours. A QR code is your data rendered as a pattern. The licence covers the software, not its output, so commercial use of the codes is unrestricted.
In practice, that means an internal deployment for your own staff is unencumbered even if you have changed the colours, and a public fork you have genuinely altered should link back to its source. The copyleft is deliberate: it keeps the tool, and anything built on it, open. If your lawyers need the primary text rather than a summary, the full licence is short by legal standards. Nothing here is legal advice.
Hosted or self-hosted: an honest comparison
| Self-hosted | Hosted at openqr.uk | |
|---|---|---|
| Static codes, all payload types | Yes | Yes |
| Your content stays in the browser | Yes | Yes, generation is client-side either way |
| Works on an isolated network | Yes | No |
| You own uptime and patching | Yes | No |
| Dynamic and editable codes | No | Yes, 3 free |
| Scan analytics | No | Yes |
| REST API and MCP server | No | Yes, free |
| Cost | Your hosting and your time | Free, or £9/month for Pro |
The two are not exclusive. A common arrangement is a self-hosted instance for internal use where the network is closed, and the hosted REST API or MCP server for automation that needs editable codes. Nothing about running your own copy prevents you using either.
Keeping it alive after launch
- Pin what you deploy. Deploy a tag or commit you have tested, not whatever
mainhappens to be the morning you rebuild. - Rebuild for dependency updates, not features. The generator's behaviour is stable because the QR standard is stable. The reason to rebuild is the Node and Next.js security stream underneath it.
- Keep one export as a regression test. Save a known code and its scanned result. After each rebuild, generate the same input and scan it. It takes a minute and it catches the only failure that matters.
- Print-test after any styling change. Screens forgive contrast and size problems that paper does not. The testing guide covers doing this properly.