qrcode.show: QR codes as a curl call, with a Rust service behind it
Generate QR code easily for free - QR Code Generation as a Service
At a glance
- What is it?
- qrcode.show turns a URL into a QR code with a single curl invocation, either by putting the payload in the path or by posting it, with output format, size, colors and error correction selected through request headers. The service is Rust, deployed on Cloudflare Workers with an Axum server as the alternative, and it states that it collects and retains no data.
- Who is it for?
- Adopt qrcode.show if you want QR codes generated from a script, a terminal alias or a chat message without installing a client library or running a local encoder, and you are comfortable sending short payloads over the network to a third party. Do not adopt it as a dependency for production systems that must not send data outside your infrastructure, since the service is a remote call by design, and note the AGPL-3.0 licence if you intend to host your own copy and modify it.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 114 days ago.
- What is it written in?
- Mainly HTML, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The payload goes in the path or in the request body
The usage section is four commands long, and the difference between them is where the input lives.
curl qrcode.show/INPUTcurl qrcode.show -d INPUTcurl qrcode.show -d @/PATH/TO/INPUTecho INPUT | curl qrcode.show -d @-The first form appends the payload to the path, which is the form most people reach for first and the one that works in a browser as well as in a terminal. The second posts the payload as the request body. The third posts the contents of a file, with the `@` prefix meaning read from that path. The fourth reads the payload from standard input, with `@-` meaning read from standard input, which is the form that pipes naturally into other commands.
The examples repeat the same four shapes with a real payload, which is a good way to remember them:
curl qrcode.show/https://example.comcurl qrcode.show -d https://example.comcurl qrcode.show -d @/path/to/input.txtecho https://example.com | curl qrcode.show -d @-Supporting both GET and POST is listed as a feature, and the practical reason for having both is length. A URL in a path is bounded by what a browser and a server will accept, while a request body has a much higher ceiling, so a longer payload goes in the body.
One thing the README is careful about is the privacy claim. The features list says no data collection or retention, alongside a fast and simple API that works on both web and terminal and support for the `accept` header to control the output format.
Everything is configured through headers, not query parameters
The parameters table is unusual in a good way. Instead of query string options, the configuration is carried in request headers, with an `x-qr-` prefix for everything that is specific to this service.
The `accept` header sets the output type, with the options `application/octet-stream`, `text/plain`, `text/html`, `image/svg+xml`, `image/png` and `image/jpeg`. The size is controlled by `x-qr-width` and `x-qr-height` for the default dimensions, and `x-qr-min-width`, `x-qr-min-height`, `x-qr-max-width` and `x-qr-max-height` for the bounds.
The colors are `x-qr-dark-color` and `x-qr-light-color`, both given as rrggbb hex. The `x-qr-version-type` chooses between `normal` and `micro`, and `x-qr-version-number` picks the version, from 1 to 40 for normal and 1 to 4 for micro. The `x-qr-ec-level` sets the error checking level to one of `L`, `M`, `Q` or `H`, and `x-qr-quiet-zone` toggles the quiet zone with `true` or `false`.
The example in the README shows how a header reads on the command line:
curl qrcode.show/INPUT -H accept:image/svg+xmlThe header approach has a practical consequence that is easy to miss. Because the options are headers rather than path segments, the same URL with a different `accept` header is a different representation, which means the same URL works in a browser and in a terminal without the caller needing to know the query syntax. It also means these options are not cacheable by a naive proxy that keys on the URL alone, since the URL does not vary with the output format.
The `accept` header is the one that matters most in practice. `image/svg+xml` is the useful one to reach for, because a vector image scales to whatever the terminal or document needs, and the shell functions below use it as a separate command for exactly that reason.
Three shell functions turn a terminal into a QR code generator
The README includes shell functions that can be added to `.bashrc` or `.bash_profle`, and they are the most immediately usable part of the project. The command takes the argument as input or reads from stdin if none was supplied, and outputs the QR code to stdout.
qrcode () {
local input="$*"
[ -z "$input" ] && local input="@/dev/stdin"
curl -d "$input" https://qrcode.show
}
qrsvg () {
local input="$*"
[ -z "$input" ] && local input="@/dev/stdin"
curl -d "${input}" https://qrcode.show -H accept:image/svg+xml
}
qrserve () {
local port=${1:-8080}
local dir=${2:-.}
local ip="$(ifconfig | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | fzf --prompt IP:)" \
&& echo http://$ip:$port | qrcode \
&& python -m http.server $port -b $ip -d $dir
}The `qrcode` function posts the argument, defaulting to stdin when there is none. The `qrsvg` function does the same but asks for SVG output, which is the version you want when the code is going somewhere that will be scaled. Both use the `@/dev/stdin` convention rather than the `@-` form, which is the same idea expressed as a file path.
The `qrserve` function is the cleverest of the three and the one with the most assumptions. It picks an IP address with `ifconfig` and a regular expression, presents the choices through `fzf` with the prompt IP, prints a URL containing that IP and the port, pipes that URL into the `qrcode` function so a scannable code appears, and then serves the current directory over HTTP with the Python http.server module bound to that address.
So scanning the code with a phone opens a directory listing of the machine on your local network, and you can put files in that directory for the phone to fetch. That is a genuinely useful trick for moving a file to a phone without a cable.
It also means the function depends on `ifconfig`, which is not present on current Linux by default, on `fzf` for the address picker, and on `python` being the Python 2-era name rather than `python3`. Those are the sharp edges of a snippet that reads as portable but is written for a particular machine.
The service is Rust, and it runs in two different ways
The credits section names three dependencies that map onto the repository structure.
The main library is qrcode-rust by kennytm, which does the actual encoding. The Cloudflare Worker is workers-rs, and the alternate web server is axum from tokio-rs. The top level of the repository shows those pieces: a `cf-worker/` directory, an `axum-server/` directory, a `libs/` directory, `static/` and `templates/` for the web front end, and a `Cargo.toml` that defines a workspace with the resolver set to 3 and three members, `libs`, `axum-server` and `cf-worker`.
So there is one core library and two ways to serve it, which is a sensible design. The Cloudflare Worker is the deployment that gives the service its edge presence and its effectively free hosting, and the Axum server is the alternative for running it as a normal long-lived process. The README notes that only the direct dependencies for the core logic are listed, and asks people to contact the maintainer if something is missing from the list.
The `Cargo.lock` is committed, which means the build is reproducible. Other top level files point at the deployment story: a `Procfile` for a platform-as-a-service style process declaration, an `app.json` which is the manifest format used by platforms that deploy from a repository, an `.envrc` for direnv, and a `shell.nix` for a Nix shell environment.
The homepage is qrcode.show itself, and the repository is hosted on GitHub with the maintainer's own site at arijitbasu.in. The copyright line reads Arijit Basu 2026, and the licence is AGPL-3.0.
The AGPL choice is worth a second look for anyone planning to run their own instance. It is a strong copyleft licence, and self-hosting a modified copy and offering it over a network is the case it was written for. The README does not discuss the licence in any detail, and this is not legal advice, but the obligations attach to the service operator rather than to the person who simply calls the public instance.
Compared with a local encoder and with a hosted API with an account
There are two other ways to get a QR code, and each is better in a different way.
A local encoder, whether a command line tool or a library, keeps the payload on your machine. That is the decisive advantage when the payload is sensitive, a license key, a Wi-Fi password, a connection string, or anything else you would not want to write into an access log on a third party's server. It is also faster, since there is no network round trip, and it works offline. The cost is an install and, for the common library implementations, a native dependency or a compiled binary.
qrcode.show inverts both of those. There is nothing to install, the payload can be piped in from another command, and the output format and styling are controlled without touching the encoder's API. For a shell alias that turns a URL into something you can paste into a chat message, that convenience is the whole point.
A hosted API with an account, of the kind you would find in a SaaS QR code generator, adds accounts, quotas, saved projects and a dashboard, and typically a paid tier. qrcode.show is the opposite of that. There is no account, no dashboard and no state, because the features list says no data collection or retention, which means the URL you generate is not tied to a project you created. A service that stores your QR codes can also link them to a landing page that you edit later; this one cannot, because it does not remember anything.
The trade is that the styling and version controls here are the only ones on offer, and the practical constraint on all of them is QR capacity. The version number and error correction level are exposed as headers, and a payload that does not fit the version you asked for is a payload the encoder cannot represent, so the version and error correction choices are a capacity budget rather than a preference.
Editorial conclusion
Adopt qrcode.show if you want QR codes generated from a script, a terminal alias or a chat message without installing a client library or running a local encoder, and you are comfortable sending short payloads over the network to a third party. Do not adopt it as a dependency for production systems that must not send data outside your infrastructure, since the service is a remote call by design, and note the AGPL-3.0 licence if you intend to host your own copy and modify it. Verify first that the payload you intend to encode is short enough for the QR version and error correction level you select, because the service exposes those limits directly through headers.
Frequently asked questions
How do I generate a QR code with qrcode.show from the terminal?
Put the payload in the path with `curl qrcode.show/INPUT`, or post it with `curl qrcode.show -d INPUT`. You can also post a file with `-d @/path/to/input.txt` or read the payload from standard input with `echo INPUT | curl qrcode.show -d @-`.
How do I get an SVG QR code from qrcode.show?
Send the `accept` header. The README gives `curl qrcode.show/INPUT -H accept:image/svg+xml` as the parameter example, and the supported accept values are `application/octet-stream`, `text/plain`, `text/html`, `image/svg+xml`, `image/png` and `image/jpeg`.
Does qrcode.show store the QR codes I generate?
The features list states no data collection or retention, that the API works on both web and terminal, and that it supports GET and POST requests. The payload is sent to the service in order to be encoded, so it does transit the network even though it is not kept.
What can I configure in a qrcode.show request?
The parameters are carried in headers: `accept` for output type, `x-qr-width` and `x-qr-height` for default size, min and max width and height variants, `x-qr-dark-color` and `x-qr-light-color` as rrggbb hex, `x-qr-version-type` for normal or micro, `x-qr-version-number` from 1 to 40 or 1 to 4 for micro, `x-qr-ec-level` for L, M, Q or H, and `x-qr-quiet-zone` to add the quiet zone.
What technology does qrcode.show run on and what licence does it use?
It is Rust, with the main library being qrcode-rust, served through a Cloudflare Worker written with workers-rs, and an alternate Axum server from tokio-rs. The repository is a Cargo workspace with members libs, axum-server and cf-worker, and the licence is AGPL-3.0.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sayanarijit-qrcode-show)Was this useful?