RaspiBolt: a guide to a Bitcoin and Lightning node, and a docs site with unusual rigour
RaspiBolt v3: Bitcoin & Lightning full node on a Raspberry Pi
At a glance
- What is it?
- RaspiBolt is the published guide for running a self sovereign Bitcoin and Lightning node on a Raspberry Pi, and since the v4 rewrite it is also a Next.js documentation site with version tokens, a remark plugin, a Debian container test harness and seven pre-commit hooks. The guide is the product; the site is the tooling that keeps the guide honest.
- Who is it for?
- RaspiBolt fits a person setting up their own Bitcoin and Lightning node who wants a guide that pins exact versions and gives one paste ready command at a time, and it fits a technical writer who wants to see what a documentation site with real verification looks like.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly MDX, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Three guides on three URLs, and only one of them is current
RaspiBolt is a guide, not a program. The README says it plainly: build your own self-sovereign Bitcoin and Lightning node on a Raspberry Pi.
What is published now is a three way split, and understanding it saves a lot of confusion. The published guide is at raspibolt.org. A v4 staging preview is at next.raspibolt.org, and it auto deploys from the feature/v4-rewrite branch. A v3 archive is at v3.raspibolt.org, which is read only and noindex, so it will not appear in search results.
The release history in the repository explains the sequence. v3-final is dated 2026-06-15, the original 3.0 came in 2021-12-07, and 2.1 in 2020-03-26. So the guide has been through a v2, a v3 and now a v4 rewrite, and the v4 work is still in a staging preview while the final v3 remains the published guide.
Two supporting documents are linked from the README and are the ones to read before you start. DECISIONS.md holds the project history and decisions, described as why the stack, content and tooling choices are what they are. TODO.md holds open decisions and deferred work.
That pair is unusual and it is the most useful thing in the repository for a reader who wants to understand the guide rather than just follow it. A guide that tells you the version numbers but not why they were chosen is a list of instructions. A guide that records the decisions is teaching you the constraints.
Version tokens, and one file that changes every page
The mechanism that keeps the guide consistent is a custom remark plugin and a pair of files, and it is the most transferable idea in the repository.
Versions and download URLs are written in the content as tokens, in the form %versions.bitcoin_core% and %files.bitcoinArchive% and %urls.bitcoinDownload%. The definitions live in lib/versions.json for the raw versions and lib/versions.ts for the derived filenames and URLs, and a remark plugin resolves them at build time, even inside code fences.
That last clause is the important one. If a page shows a command that downloads Bitcoin Core, and the version in that command comes from a token, then bumping the version in one file updates the download link in the command, the checksum elsewhere on the page, and any prose that mentions the version number, and the page cannot drift.
The current values are a single table.
| Software | Version | |----------|---------| | Bitcoin Core | 31.1 | | LND | 0.21.2-beta | | Electrs | 0.11.1 | | RTL | 0.15.11 | | Mempool | 3.3.1 | | Node.js | 24 LTS |
And the instruction is simply to edit lib/versions.json to update, after which every page re-renders on the next build.
For a technical writer building documentation about software that ships new versions, this is the pattern that solves the problem that documentation usually has, which is that a guide ages badly because the numbers in it are wrong within a month. Here the numbers are wrong in one place and one command fixes them.
One command per code block, and why that rule exists
The writing conventions section is short and one of its rules is unusually strict.
Code blocks always specify a language, bash, text, ini and so on, and hold one shell command each, so the copy button hands the reader exactly one paste ready command. Heredocs, pipelines and reference lists stay together, and the exceptions live in CLAUDE.md.
That rule is a decision about the reader's hands. A reader on a Raspberry Pi over SSH is copying commands into a terminal one at a time, and a block containing a pipeline or a multi line heredoc is a block that gets pasted badly, with the paste ending in the middle of the construct. One command per block means the copy button is always safe.
The other conventions are equally practical. Callouts use the Fumadocs Callout component with a type of info, warn, success or error. Internal links use bare paths such as /docs/raspberry-pi/preparations, with no file extension. And when a reader facing guide change is published, the v4 Updated Month YYYY badge in src/app/(home)/page.tsx has to be updated too, which is a small rule that keeps the homepage honest about how fresh the guide is.
The content itself lives in guide/ as .mdx files, standard Markdown with a few React components, Callouts and Cards. The README says you can edit any page directly in the GitHub UI and that no Next.js knowledge is required, which is a deliberate choice for a guide that expects non-programmers to contribute corrections.
The structure under guide/ has a meta.json for root sidebar order, an index.mdx landing page, and section directories with their own meta.json for page order, including raspberry-pi/, bitcoin/, lightning/ and bonus/.
Seven pre-commit hooks, and a container that runs the guide for you
The quality tooling in this repository is the part that most distinguishes it from a typical documentation site, and it comes in two halves.
The first half is pre-commit. The full suite runs in CI too, and it consists of npm run lint for ESLint, npm run types:check for TypeScript, npm run format:check for Prettier, npm test for vitest on the remark plugin, and npm run build, which the README notes also catches MDX syntax issues. Then there is the pre-commit run --all-files pass, which covers gitleaks, typos, markdownlint, yamllint, actionlint and vale.
The hook table says which of them block. gitleaks checks for secrets and credentials and blocks. shellcheck checks shell script issues and blocks. typos checks spelling and blocks. markdownlint checks Markdown formatting on .mdx files and blocks. yamllint checks YAML syntax and blocks. actionlint checks GitHub Actions workflows and blocks. vale checks prose style and terminology and is advisory, never blocks.
That single advisory exception is a good sign, because it means the project separates what must be correct from what a human should look at.
The second half is the test harness under testing/. The vm/ directory is a Debian 13 Trixie systemd in docker harness, so the commands in the guide can be executed in a container that looks like the target system. The extract/ directory is an MDX step extractor that parses the shell blocks out of guide/**. The run-walk.sh script is an end to end autonomous walkthrough runner, and REPORT.md holds the latest walk report with a per page PASS or FAIL.
That is the part of this project worth studying. A guide of shell commands for setting up a node is only as good as the commands, and this project has built a way to actually execute them.
Running the site locally, which is four commands
The local development path is short enough to reproduce, and it doubles as a way to see the guide without a Raspberry Pi.
The prerequisites are Linux, macOS or WSL, Node.js 20 or newer, Python 3.10 or newer which is only for the pre-commit and yamllint tooling, and Git. Then the first time setup is a clone, a change into the directory, and a setup script.
git clone https://github.com/raspibolt/raspibolt.git
cd raspibolt
bash scripts/setup-dev.shThe script installs the development tools to ~/.local/bin with no root required, runs npm ci, and registers the pre-commit hook. If that directory is not already on your PATH, the README gives the one line to add.
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrcAfter that, npm run dev opens a live reload Next.js development server on http://localhost:3000 and the site rebuilds on every save. For a production bundle there are two more scripts.
npm run build # static export to out/
npm run start # serve out/ locallyThe npm run build script is next build followed by a post-build script, and the export lands in the out/ directory, which npm run start then serves locally with serve.
The stack, and why the site is Next.js at all
The stack is listed in full, and the choices are not obvious for a Bitcoin guide.
Content is MDX, Markdown plus React components, in the guide/ directory. The framework is Next.js 16 with static export. The docs theme is Fumadocs, the styling is Tailwind CSS 4, and deployment is GitHub Pages, with production through .github/workflows/site-publish-prod.yml and staging through .github/workflows/site-publish.yml. Variable resolution is a custom remark plugin in lib/remark-variables.ts.
The package.json confirms the versions. Next is 16.3.1, React and React DOM are 19.2.8, fumadocs-core and fumadocs-ui are 16.14.4, fumadocs-mdx is 14.3.1, Tailwind is 4.2.2, TypeScript is 6.0.3, vitest is 4.1.10 and mermaid is 11.16.1, with remark-gfm for the GitHub flavoured Markdown that the guide needs.
Static export is the point. The build produces an out/ directory, npm run build runs next build followed by a post-build script, and npm run start serves out locally. The site is a static bundle on GitHub Pages, which means the guide is readable without a server, and the .env.example file explains that every environment variable is consumed by the Next.js build at compile time and not at runtime, because this is a static export.
Two more details in that file. NEXT_PUBLIC_SITE_URL is the public site origin, used for absolute URLs in metadata and the canonical link, and setting it to https://raspibolt.org flips an isProductionSite flag in lib/shared.ts, which enables search indexing and switches the analytics script to the production website ID. The analytics script only renders in production builds and is additionally pinned to the deploy hostname via data-domains, so next dev and local serves never send stats. NEXT_PUBLIC_BASE_PATH is the path prefix for when the site is not served from the domain root.
Also worth noting is .pa11yci.json, an accessibility check configuration, and lighthouserc.json, a Lighthouse configuration, both of which belong in a repository whose audience includes people setting up hardware rather than people who already know the web.
What this project is not, and the honest limit of a guide
Three boundaries, and the first one is the most important.
The first is that there is no software here. The deliverable is the guide. Nobody installs RaspiBolt, and there is no daemon, no service and no package to add. That means the usual questions you would ask of a tool, does it support my hardware, is it compatible with my operating system, how do I upgrade it, have a different answer here, and the answers are in the pages.
The second is that the guide is tied to a specific set of versions. Bitcoin Core 31.1, LND 0.21.2-beta, Electrs 0.11.1, RTL 0.15.11, Mempool 3.3.1. That set is deliberate, and it is the reason the tokens exist, but it also means the guide is a snapshot. A reader on a different version follows the older v3 archive, which is read only and noindex, and the tradeoffs of the newer components are documented in DECISIONS.md rather than assumed.
The third is the audience. A self sovereign Bitcoin node is a specific act with specific consequences, and the guide is written for someone who has decided to do it and wants the steps to be correct. It is not a comparison of node software, it is not a wallet, and it does not explain the arguments for or against running one.
What it offers instead is a process with a verification story, which is the honest alternative to what most installation guides offer. The commands are single and paste safe, the versions are tokenised so they cannot drift, the pages are linted for secrets, typos, style and accessibility, and the shell blocks are extracted and executed inside a Debian container that reports per page pass or fail. For a guide that asks you to run commands on a device that will hold money, that is a considerably better position than a page of prose with no tests behind it.
Editorial conclusion
RaspiBolt fits a person setting up their own Bitcoin and Lightning node who wants a guide that pins exact versions and gives one paste ready command at a time, and it fits a technical writer who wants to see what a documentation site with real verification looks like. It does not fit a reader looking for a software package to install, because there is nothing to install, the deliverable is the guide, and it does not fit a user who needs the guide for a Bitcoin or Lightning version older than the current one without accepting that the older versions live on a separate archived site. Check three things before you follow it. Check the branch and the site you are on, because the current guide is v4 on the main branch, a v4 staging preview auto deploys from the feature/v4-rewrite branch, and v3 is read only and noindex at v3.raspibolt.org. Check the versions file, because lib/versions.json is where the software versions are defined and every page re-renders from it, with the current set naming Bitcoin Core 31.1, LND 0.21.2-beta, Electrs 0.11.1, RTL 0.15.11, Mempool 3.3.1 and Node.js 24 LTS. And check that you can follow one command at a time, because the writing convention is that every code block holds one shell command. The last push was on 2026-10-02, the newest tagged release is v3-final from 2026-06-15, and the license is MIT.
Frequently asked questions
What is RaspiBolt and what does it give me?
It is a published guide for building a self-sovereign Bitcoin and Lightning node on a Raspberry Pi, and the deliverable is the guide rather than an installable program. The current guide is v4 at raspibolt.org, with a v4 staging preview at next.raspibolt.org and the v3 archive at v3.raspibolt.org.
How does RaspiBolt keep version numbers in sync across pages?
Versions and download URLs are written as tokens such as %versions.bitcoin_core% and %urls.bitcoinDownload%, with raw versions in lib/versions.json and derived filenames and URLs in lib/versions.ts. A custom remark plugin resolves them at build time, even inside code fences, so editing versions.json re-renders every page.
Which software versions does the current RaspiBolt guide target?
Bitcoin Core 31.1, LND 0.21.2-beta, Electrs 0.11.1, RTL 0.15.11, Mempool 3.3.1 and Node.js 24 LTS. The versions are defined in lib/versions.json and every page re-renders on the next build when they change.
How does the RaspiBolt project test the commands in its guide?
There is a testing/ directory with a Debian 13 Trixie systemd-in-docker harness under vm/, an MDX step extractor under extract/ that parses the shell blocks out of guide/, a run-walk.sh end to end autonomous walkthrough runner, and a REPORT.md with a per page PASS or FAIL result.
How do I run the RaspiBolt site locally?
You need Linux, macOS or WSL, Node.js 20 or newer, Python 3.10 or newer for the pre-commit and yamllint tooling, and Git. Clone the repository, run bash scripts/setup-dev.sh, add ~/.local/bin to your PATH, then run npm run dev for a live reload server on http://localhost:3000.
What license is RaspiBolt released under?
MIT, with a LICENSE file at the root of the repository. The newest tagged release is v3-final from 2026-06-15, and the last push was on 2026-10-02.
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/raspibolt-raspibolt)Was this useful?