Text QR Code Generator

Encode any snippet of text into a code. Unlike link codes, a text code needs no internet at all when scanned — the words are inside the image, which makes it the right tool for asset tags, instructions, and anything that must work in a basement with no signal.

Shows a snippet of text when scanned.

Plain text details

Style & export options

A logo hides part of the code, so it is capped at 16% of the code area (a decode-tested limit) and error correction is forced to level H.

Fill in the form — the code appears as you type.

Codes render on light backgrounds for reliable scanning.

What the code contains
 

Keep this code

Optional — the downloads above already work without saving anything.

Device saves stay in this browser; account saves need a free account. Both appear in My codes.

Save this code to an account

A free account keeps your codes in one library you can open from any device. Your code is ready — sign up or sign in, and it will be saved automatically.

Sign up free Sign in

Before this leaves your device

What a text code contains

Every code on this site has two layers. The payload is the text encoded inside the symbol; the symbol is the matrix of dark and light modules, produced to ISO/IEC 18004 by a vendored copy of the reference encoder (Project Nayuki's qrcodegen). For the other generators the payload follows a convention — a WIFI: string, a vCard, a mailto: URI (RFC 6068) — and that convention is what lets a scanning phone offer to join the network or save the contact. A plain-text code is the one type with no convention at all. The payload is the text you typed, byte for byte: no prefix, no field separators, no escaping. The engine's text builder does exactly one thing before handing the string to the encoder — it refuses an empty box, with the message “Enter some text to encode.” — and everything else passes through unchanged.

That is what makes a text code the right tool wherever the information itself, rather than a web page, is the point:

  • Asset and equipment tags: serial number, install date, and service notes on the machine itself, readable by any phone with no app, no database, no connectivity.
  • Instructions at the point of need: reset steps taped inside a cabinet, dosing instructions on a container, the "which breaker is which" list inside the panel door.
  • Inventory and logistics: box contents that warehouse staff scan instead of reading tiny handwriting.
  • Geocaching and puzzles: the classic — a message that reveals itself only to someone who scans.

The symbol layer — how the encoder picks a version, what the error-correction level buys, and why payload mistakes outnumber symbol mistakes — is the subject of the guide How a QR code encodes data. This page stays on the payload, and on reading the facts the engine reports for each example. The tags, notes and numbers on this page are invented; none describe real equipment, places or people.

Worked example

An equipment tag encodes the text exactly as typed:

Boiler #B-2041 — service due 2026-11. Manual: shelf 3, red folder.

When scanned, the phone displays the text (with copy and search actions) — no browser, no network round trip.

Reading the symbol facts. The engine encodes that tag as version 5, a symbol 37×37 modules a side, at error-correction level M. The version is chosen by the encoder from the versions the standard defines, numbered 1 to 40 — longer payloads need higher versions — and the module count follows from the version alone, so two payloads that land on the same version produce symbols of the same size however different their text. Error correction is requested at M for every example on this page; the level printed is the one actually encoded, which the reference encoder raises when a higher level fits without increasing the version, and never lowers.

No prefix, no escaping: the same text in three formats

The clearest way to see what the text builder does not do is to run the same string through the builders that do. Punctuation that a payload convention uses as a separator has to be escaped inside that convention. The WIFI: format, per the ZXing Barcode Contents reference the engine follows, reserves \ ; , " : and prefixes each with a backslash; vCard 3.0 (RFC 2426) escapes backslash, semicolon and comma, and writes a line break as the two characters \n. A text payload has no separators, so none of this applies — and nothing has to be undone by the phone that reads it.

Worked example: punctuation

A spares note that uses every character the WiFi convention reserves — Spares: shelf C; bin 12, "4 of 6" — path \stock\fuses — encodes as itself:

Spares: shelf C; bin 12, "4 of 6" — path \stock\fuses

The same string placed in a WIFI: password field would be carried as Spares\: shelf C\; bin 12\, \"4 of 6\" — path \\stock\\fuses. Here it is untouched: version 4, 33×33 modules, error correction M.

Worked example: line breaks

A breaker list typed on 5 lines is encoded with its line breaks intact:

Breaker panel — flat 3
B1: kitchen sockets
B2: hallway lights
B3: boiler
Trip test: hold T for 5 s

A line break is a byte like any other. Inside a vCard field the same text would read Breaker panel — flat 3\nB1: kitchen sockets\nB2: hallway lights\nB3: boiler\nTrip test: hold T for 5 s, each break written out as \n; in a text code it stays a real line break, so the note displays as typed. 98 characters, 100 bytes — version 6, 41×41 modules, error correction M.

The common misreading runs the other way. Because the text builder encodes anything, people paste a web address, a phone number, or even a hand-typed WIFI: string into it and expect the phone to act on it. Sometimes the bytes are identical to what the dedicated generator would have produced — https://example.com/menu is the same payload from either box, and the build checks that it is — but the dedicated builders validate, and some normalise, while the text builder normalises nothing and validates nothing beyond refusing an empty box. The URL builder refuses example.com/menu with “Include the protocol (e.g. https://) so scanners recognize the link.” The text builder accepts it without comment, and without a protocol scanners are not guaranteed to recognise it as a link. The phone builder turns +1 555 013 2000 into tel:+15550132000, a tel: URI (RFC 3966) with the number in E.164 international format; the text builder keeps +1 555 013 2000, spaces and all. If the scanning phone should do something with the content, build it with the generator for that content type: links, phone numbers, contact cards, WiFi.

Characters, bytes and the version

The text builder hands the encoder the string unchanged, so the only measure of a text payload is its length — and length can be counted two ways. The characters column counts what was typed; the bytes column counts the same text in UTF-8, where the letters, digits and punctuation of ASCII are one byte each and a character outside that range costs more. The table lists every example on this page ordered by payload bytes, with the facts the engine reports for each. Read down it, the version never falls as the byte count rises — the build checks that it does not — and the module count follows the version.

Example Characters UTF-8 bytes Version Modules EC
Serial tag 10 10 1 21×21 H
Multilingual label 21 30 3 29×29 Q
Spares note 53 55 4 33×33 M
Boiler tag 66 68 5 37×37 M
Breaker list 98 100 6 41×41 M
Pump service note 301 301 13 69×69 M

The multilingual label Küche · 厨房 · Cocina ✨ has 21 characters but 30 bytes: every character outside ASCII costs more than one byte of UTF-8, and the label has 6 of them — ü (2 bytes), · (2 bytes each, twice), 厨 (3 bytes), 房 (3 bytes), ✨ (3 bytes). Its 15 ASCII characters account for 15 bytes and the 6 others for 15, which together make the 30. The em dash in the spares note, the boiler tag and the breaker list does the same, which is why those byte counts exceed their character counts; the serial tag and the pump service note, which are pure ASCII, have as many bytes as characters.

Some of the shortest payloads carry an error-correction level above the M that was requested — the serial tag (H) and the multilingual label (Q) — because the encoder found that the higher level fitted in the same version. Nothing is lost by it: error correction is what helps a damaged code scan, and a higher level is more of it.

There is an upper limit, and the engine states it rather than guessing at it: the reference encoder refuses data past the capacity of version 40, and the generator reports the refusal. Stacking 40 copies of the pump service note into the box produces the message “This content is too long for a QR code. Shorten it or lower the error correction level.” Below that limit the practical question is not whether the code can be made but how dense it is — which is a print-size question.

Worked example: a long note

A full service note of 301 characters:

Pump P-7 (loop 2). Installed 2024-03. Seal kit: SK-410. Grease nipples: both sides, quarterly. If the panel shows E04, close valve V-12, wait two minutes, reset at the breaker, then reopen V-12 slowly. Vibration above 4 mm/s: stop and tag out. Log every service on the card in the pocket of this door.

Version 13, 69×69 modules, error correction M. With the 4-module quiet zone on each side, the rendered image is 77 modules across.

What the print-size readout means

The PNG download offers 3 sizes, and the generator shows a print-size readout for each: it divides the pixel count by a print resolution of 300 DPI to get inches, and converts to millimetres. The readout describes the whole image, quiet zone included. For the service note above, which renders 77 modules across, one module is therefore:

PNG size Print size at 300 DPI One module
512 px 1.71 in × 1.71 in (43.3 mm × 43.3 mm) at 300 DPI 0.56 mm
1024 px 3.41 in × 3.41 in (86.7 mm × 86.7 mm) at 300 DPI 1.13 mm
2048 px 6.83 in × 6.83 in (173.4 mm × 173.4 mm) at 300 DPI 2.25 mm

The readout is geometry, not a verdict: it tells you how large each module will be on paper at that resolution, which is the figure print-size questions are really about. A shorter payload at the same pixel size has fewer, larger modules; the long note has more and smaller ones. Three things the renderer settles so that they cannot go wrong by accident:

  • The quiet zone is always there. The 4-module light border the standard requires is rendered into every download and cannot be switched off. Cropping it afterwards — trimming the image to the dark modules, or printing the code flush against artwork — is the most common self-inflicted scan failure.
  • Contrast is computed, not guessed. The style panel evaluates your colour pair with the WCAG relative-luminance formula and warns below 4.5:1.
  • Inverted codes get a warning of their own. Light modules on a dark background are flagged separately, because many scanners reject them. Prefer dark modules on a light background.

Error correction helps a damaged code scan, but print size and contrast still matter. Treat a freshly generated code as untested until a real device has scanned it.

What the generator cannot verify

The engine validates format, not truth — and for a text code there is almost no format to validate, so there is almost nothing it can catch. A serial number with two digits transposed encodes as cleanly as the right one. Instructions that were correct when printed stay in the code after the procedure changes. A wrong password typed as plain text encodes without complaint; so does a right one, in the clear, for anyone who scans it. The code is a faithful carrier of whatever you gave it, and the round-trip test suite checks exactly that: each payload type is rendered, rasterised and decoded with an independent decoder, and the decoded text must match the payload byte for byte. What no test can check is whether the words were the right words.

Two properties follow from the data living in the image. Nothing is routed through our servers, so the code cannot expire and cannot be held hostage; and nothing can be changed after printing, so a corrected note means a new code, and scans cannot be counted. Where that trade-off is wrong for you — a document that will be revised — put the content at an address you control and print a link code instead, unless offline access is the whole point.

Read next: How a QR code encodes data — the symbol layer this page only summarises — and the rest of the guides.

Text QR code FAQ

Does scanning a text code open anything automatically?

No — the phone just shows the text. That predictability is a feature: nothing to tap through, nothing that can be a malicious link, nothing that needs connectivity.

Are line breaks preserved?

Yes. Whatever you type in the box — including line breaks — is encoded verbatim and shown the same way after scanning.

Is the text encrypted?

No. A QR code is an encoding, not encryption — anyone who scans it reads it. Never put secrets in a printed code; for WiFi credentials use the purpose-built WiFi code and treat the printout itself as the secret.

Do I need to escape semicolons, commas or quotation marks?

No. A text payload has no separators, so there is nothing to escape: the characters go in exactly as typed. The WIFI: and vCard conventions do escape them because they use those characters as separators — inside a WIFI: field the spares note above becomes Spares\: shelf C\; bin 12\, \"4 of 6\" — path \\stock\\fuses. A text code never rewrites anything.

Can I put a web address in a text code?

You can, and it is encoded exactly as typed. The difference is validation: the URL generator checks for a protocol and refuses example.com/menu with “Include the protocol (e.g. https://) so scanners recognize the link.” The text generator accepts the same string without comment. If the scanning phone should treat the content as a link, build it with the URL generator.

Why does the error-correction letter sometimes differ from M?

Every example on this page requests level M. The reference encoder may raise the level when a higher one fits without increasing the version, so a short payload can come out at Q or H — the serial tag above is encoded at H. The level is never lower than requested.

What happens when the text is too long?

The generator refuses the input rather than producing a symbol it cannot encode. Stacking 40 copies of the pump service note into the box produces the message “This content is too long for a QR code. Shorten it or lower the error correction level.”

Can I change the text after printing?

No. Every code here is static: the text lives in the image, with no redirect through our servers. It never expires and cannot be held hostage, but it also cannot be edited after printing — a corrected note needs a new code — and scans cannot be counted.

If the text you keep encoding is really an address, a phone number, or an email, the dedicated vCard, phone, and email codes trigger the right action on the scanning phone instead of showing plain words.