# Generate a QR code in Java

> ZXing is the standard: MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, 512, 512, hints) returns a BitMatrix, and MatrixToImageWriter (in the javase artifact) writes the PNG. Set ERROR_CORRECTION and MARGIN through the EncodeHintType map. Or skip dependencies entirely and download from the keyless API with HttpClient.

Source: https://useqr.app/docs/developers/generate-a-qr-code-in-java · Last reviewed 2026-08-21 · UseQR is free forever, no signup.

---

## ZXing in two artifacts

ZXing ("zebra crossing") is the JVM's standard barcode library, and it ships split in two:
`com.google.zxing:core` holds the encoder and decoder, while `com.google.zxing:javase`
holds the desktop I/O helpers, including `MatrixToImageWriter`, which you need to actually
write a PNG. Forgetting `javase` is the classic first compile error.

```xml
<dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.3</version></dependency>
<dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.5.3</version></dependency>
```

## Encode, hint, write

```java
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
hints.put(EncodeHintType.MARGIN, 4);

BitMatrix matrix = new MultiFormatWriter()
    .encode("https://example.com", BarcodeFormat.QR_CODE, 512, 512, hints);
MatrixToImageWriter.writeToPath(matrix, "PNG", Path.of("qr.png"));
```

The hint map is where correctness lives. `MARGIN` is the
[quiet zone](/glossary/quiet-zone) in modules: keep it at **4**; `ERROR_CORRECTION` takes
the four [levels](/docs/spec/error-correction-levels-explained) L, M, Q, H. For in-memory
use, `MatrixToImageWriter.toBufferedImage(matrix)` returns a `BufferedImage` you can hand
to `ImageIO` or a servlet response.

## The zero-dependency route: HttpClient

Java 11's built-in `java.net.http` client makes the
[keyless API](/docs/developers/free-qr-code-api-no-key) a no-dependency option: useful
when you want styled output or typed payloads (WiFi, vCard, UPI) without renderer code:

```java
String data = URLEncoder.encode("https://example.com/sale?src=poster",
    StandardCharsets.UTF_8);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(
    URI.create("https://useqr.app/api/v1/qr?data=" + data + "&size=1024&ec=Q")).build();
client.send(request, HttpResponse.BodyHandlers.ofFile(Path.of("qr.png")));
```

`URLEncoder.encode` is not optional: a raw `&` inside the payload starts a new query
parameter and the encoded data is silently truncated. Add `format=svg` when the output is
headed to [print](/docs/print/qr-code-size-for-print): ZXing itself has no SVG writer.

## Decode-verify with the library you already have

ZXing decodes too, so a Java test can round-trip its own output:

```java
BufferedImage img = ImageIO.read(new File("qr.png"));
LuminanceSource source = new BufferedImageLuminanceSource(img);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap);
assertEquals("https://example.com", result.getText());
```

For styled or logo-carrying codes generated via the API, `GET /api/v1/verify` runs the
render-rasterise-decode loop server-side and reports `scannable` with issues: the
reasoning is in [why verify that your QR code decodes](/docs/developers/why-verify-that-your-qr-code-decodes),
and how ZXing's decoder compares with quirc and ZBar is in
[zxing vs quirc vs zbar](/docs/developers/zxing-vs-quirc-vs-zbar). On Android, the
idiomatic wrapper is different: see the
[Kotlin page](/docs/developers/generate-a-qr-code-in-kotlin).

## FAQ

### What is the standard Java library for QR codes?
ZXing. Use MultiFormatWriter to encode into a BitMatrix and MatrixToImageWriter, from the separate javase artifact, to write image files.

### Why can't Java find MatrixToImageWriter?
It lives in com.google.zxing:javase, not core. Add the javase artifact alongside core and the import resolves.

### How do I set error correction and margin in ZXing?
Pass an EnumMap of EncodeHintType entries to encode: ERROR_CORRECTION with an ErrorCorrectionLevel, and MARGIN with the quiet-zone width in modules: keep it at 4.

### Can ZXing produce SVG?
No, it renders to a BitMatrix and raster images. For SVG output, call the keyless API with format=svg or render the matrix yourself.

## Try it

- https://useqr.app/url
- https://useqr.app/json
- https://useqr.app/validate
