# bitcoinj: a Java Bitcoin protocol library with SPV wallets and a wallet-tool CLI

> bitcoinj is a Java implementation of the Bitcoin protocol that maintains a wallet and sends and receives transactions without a local Bitcoin Core node. It suits JVM and Android developers, and its wallet-tool CLI is the fastest way to see what the library actually does.

**bitcoinj/bitcoinj** — A library for working with Bitcoin

- Repository: https://github.com/bitcoinj/bitcoinj
- Website: https://bitcoinj.org
- Stars: 5,235 · Forks: 2,565
- Language: Java
- License: Apache-2.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/bitcoinj-bitcoinj

## What bitcoinj solves for JVM and Android developers

Running Bitcoin Core means syncing and storing the whole chain. bitcoinj exists so a Java application does not have to. The README states that the library "allows it to maintain a wallet and send/receive transactions without needing a local copy of Bitcoin Core." That is the whole pitch, and it defines the audience: developers writing a wallet, a payment integration, or an application that needs to observe and spend bitcoin from inside a JVM process.

The repository layout backs this up. The build is split into base, core, tools, wallettool, wallettemplate, examples, examples-kotlin, integration-test and test-support modules. The split is not cosmetic: it separates the low-level protocol and cryptography code from the parts that need newer Java. If you are targeting Android, the base and core modules are the ones that matter, and the README pins them to Java 8 API or Android 8.0 API, compiling to Java 8 bytecode. Everything else can move faster.

The topics listed for the repository read like a specification checklist rather than marketing: bech32, bip141, bip143, bip144, bip173, bip32, bip37, bip70, segwit, taproot. Those are address formats, signature hashing, transaction formats, segwit and taproot support. A team that needs to construct, sign or parse modern Bitcoin transactions in Java is the target user.

## How the library is structured and where the wallet state lives

Two things are being managed at once, and the README names them together: "the HD keychain and SPV blockchain state." The HD keychain is the BIP32 derivation tree that produces your addresses and private keys. The SPV blockchain state is the simplified-payment-verification view of the chain, the headers and the filters and the matched transactions that let the wallet know its balance without downloading every block.

That distinction matters in practice because they fail differently. A corrupted keychain means lost funds. A corrupted or stale SPV state means a wrong balance and a wallet that needs to resync. The wallet-tool exposes both through a single wallet file, which is why the dump command is useful: it prints the state of the wallet rather than just a balance number.

The dependency list is short and worth reading before you commit. Google Protocol Buffers is used "for use with serialization and hardware communications." That means wallet files and hardware wallet messages are protobuf-encoded, so a protobuf runtime ends up in your dependency tree. For an Android app this is a real consideration, not a formality.

There are also separate modules for Kotlin examples and a JavaFX template, which tells you the project expects to be embedded in someone else's application rather than run as a standalone service. There is no daemon, no RPC server, no HTTP endpoint in the repository layout.

## Building bitcoinj and creating a testnet wallet with wallet-tool

The README recommends the latest JDK and Gradle installed. Official builds use JDK 17, and CI runs on JDK 17, 21 and 25. A full build including tests is a single Gradle invocation:

```bash
gradle clean build
```

Outputs land under the build directory. If you want to skip unit and integration tests, the README gives a separate target:

```bash
gradle clean assemble
```

For the command-line wallet, build the wallettool distribution. This produces an executable shell script:

```bash
gradle bitcoinj-wallettool:installDist
```

Run the tool with no arguments to get help on its operation:

```bash
./wallettool/build/install/wallet-tool/bin/wallet-tool
```

Now create a testnet wallet. The README's example puts it in ~/bitcoinj/bitcoinj-test.wallet, and the directory has to exist first:

```bash
mkdir ~/bitcoinj
./wallettool/build/install/wallet-tool/bin/wallet-tool --net=TESTNET --wallet=$HOME/bitcoinj/bitcoinj-test.wallet create
```

Syncing is a separate step, and on testnet it is the step where you find out whether SPV is actually working for your environment:

```bash
./wallettool/build/install/wallet-tool/bin/wallet-tool --net=TESTNET --wallet=$HOME/bitcoinj/bitcoinj-test.wallet sync
```

To inspect the result, dump the wallet state:

```bash
./wallettool/build/install/wallet-tool/bin/wallet-tool --net=TESTNET --wallet=$HOME/bitcoinj/bitcoinj-test.wallet dump
```

On Windows the README points to wallettool/build/install/wallet-tool/bin/wallet-tool.bat with equivalent options. The README explicitly recommends testnet for learning, which is the right instinct: the same commands against mainnet move real value.

## The JavaFX template is a starting point, not a product

The wallettemplate subproject is described as a template JavaFX wallet application that "can be used as a starting point for building a JavaFX-based bitcoinj wallet application." Read that literally. It is scaffolding, and the README does not present it as anything else.

Building it follows the same pattern as wallettool:

```bash
gradle bitcoinj-wallettemplate:installDist
```

Then launch it:

```bash
./wallettemplate/build/install/bitcoinj-wallettemplate/bin/bitcoinj-wallettemplate
```

The README also documents a jlink path that bundles a JVM runtime, which is the more interesting option if you ever ship this to a machine without a JDK:

```bash
gradle bitcoinj-wallettemplate:jlink
./wallettemplate/build/image/bin/bitcoinj-wallettemplate
```

Here is the constraint worth noticing. The template requires Java 25+, while base and core need only Java 8. If your organization standardizes on an older JDK, the template is closed to you even though the library is not. That is a deliberate split, and it means the most visible demo in the repository is also the least portable part of it.

## Where bitcoinj is the wrong tool

SPV is a trust model, not a free lunch. A bitcoinj wallet does not validate the whole chain the way Bitcoin Core does; it verifies what it can from headers and matched data. If your application needs full validation, or needs to serve other peers, or needs to enforce consensus rules over arbitrary transactions, this library is not that. The README frames the project against needing "a local copy of Bitcoin Core," which is the trade you are making.

The second limitation is release discipline. The README states plainly that "the HEAD of the master branch contains the latest development code and various production releases are provided on feature branches." If you clone master and build it, you are building development code. The release list shows v0.17.1 in May 2026, v0.17 in February 2025, and v0.17-rc3 just before it, so the gap between the 0.17 line and its patch release is over a year. Plan your dependency on tagged releases, not on master.

The third is the build itself. The reference build runs in a container with Buildah 1.26+, Podman 4.1+ or Docker with BuildKit, and it uses Debian Gradle with settings-debian.gradle. The README notes Gradle 9.1+ for the whole project but Debian Gradle 4.4 for just base, core, tools, wallettool and examples. Two different Gradle floors in one repository is a real source of confusion for anyone setting up CI, and the README does not hide it.

Finally, wallet file compatibility is your problem, not the project's. The README does not document a migration path between wallet file versions, so if you ship a wallet and the serialization format changes, verifying upgrade behavior is on you.

## bitcoinj versus running Bitcoin Core

The honest alternative to bitcoinj is not another Java library. It is Bitcoin Core itself, plus whatever binding you need. The difference is architectural, not stylistic.

Bitcoin Core is a full node. It downloads and validates the entire chain, enforces consensus rules, and exposes an RPC interface your application calls. You get the strongest correctness guarantees available, at the cost of disk, bandwidth and sync time. Your Java process becomes a client, not a participant.

bitcoinj is the opposite arrangement. Your process is the participant. It holds keys, tracks the chain via SPV, and talks to peers directly. There is no separate daemon to operate, which is exactly what makes it viable inside an Android app where no daemon can run. The price is that you inherit the SPV trust assumptions and the responsibility for wallet file safety.

A middle option the README implies but does not name: use bitcoinj for key management and transaction construction while relying on an external service for chain data. Nothing in the library prevents that, but the README does not describe such a configuration, so treat it as your own design decision rather than a documented mode.

## Licence, maintenance and upgrade cost

bitcoinj is Apache-2.0. That is a permissive licence, and for most commercial Java and Android products it is the easy case: you can link it, ship it, and modify it, subject to the usual notice and attribution conditions. The repository carries a COPYING file and an AUTHORS file at the top level. I am not a lawyer and this is not legal advice; if you are redistributing a modified library or bundling it into a product with its own licence terms, have counsel read the actual text in COPYING rather than a summary.

Maintenance looks current rather than dormant. The repository is not archived, and the last push was on 2026-09-21, two days before today. The most recent tagged release is v0.17.1 from 2026-05-04. So the project is being pushed to, and there is a recent release to depend on.

Upgrade cost is where you should budget time. The 0.17 line has been stable since early 2025, which cuts both ways: fewer breaking changes, but also a long wait if you need something from master. The README offers Jitpack builds of master and release-0.17 for testing snapshots, which is the documented way to try unreleased code without vendoring it. The README does not document a rollback procedure if a snapshot build breaks your application, so keep your release-based dependency pinned and treat Jitpack as a test channel only.

## Conclusion

Adopt bitcoinj if you are building a JVM or Android application that needs a wallet without running Bitcoin Core, and start by building the wallettool subproject and creating a TESTNET wallet rather than touching mainnet. Do not adopt it if you expect a maintained desktop wallet or a drop-in replacement for Bitcoin Core's validation; it is a library, and the wallettemplate is explicitly a starting point. Before committing, verify that the Java version requirements match your toolchain (Java 8+ for base and core, Java 17+ for tools, wallettool and examples, Java 25+ for wallettemplate) and confirm which branch you are pulling from, because the README states that master carries development code while production releases sit on feature branches.

## FAQ

### What is bitcoinj and what is it used for?

bitcoinj is a Java implementation of the Bitcoin protocol that maintains a wallet and sends and receives transactions without needing a local copy of Bitcoin Core. It is used as a library inside JVM and Android applications that need wallet functionality.

### How do I install or build bitcoinj?

The README recommends the latest JDK and Gradle, and says official builds use JDK 17. Clone the repository and run gradle clean build, or gradle clean assemble to build without running unit and integration tests. Outputs are placed under the build directory.

### How do I create a bitcoinj wallet from the command line?

Build the wallettool distribution with gradle bitcoinj-wallettool:installDist, then run the generated wallet-tool script with --net=TESTNET and --wallet pointing at your wallet file, followed by the create subcommand. The README shows create, sync and dump as separate invocations against the same wallet file.

### Which Java versions does bitcoinj require?

The README states Java 8+ for the base and core modules, Java 17+ for tools, wallettool and examples, and Java 25+ for the JavaFX-based wallettemplate. The base and core modules compile to Java 8 bytecode and need the Java 8 API or Android 8.0 API.

### Does bitcoinj need Bitcoin Core installed?

No. The README says the library maintains a wallet and sends and receives transactions without needing a local copy of Bitcoin Core. It tracks SPV blockchain state instead of downloading the full chain.

## Sources

- [bitcoinj/bitcoinj on GitHub](https://github.com/bitcoinj/bitcoinj)
- [License: Apache-2.0](https://github.com/bitcoinj/bitcoinj/blob/master/LICENSE)
- [Project website](https://bitcoinj.org)
- [README](https://github.com/bitcoinj/bitcoinj/blob/master/README.md)
- [Releases](https://github.com/bitcoinj/bitcoinj/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bitcoinj-bitcoinj
