Turning technical book PDFs into Claude Code skills: 5 real pitfalls I hit using virgiliojr94/book-to-skill
Last month virgiliojr94/book-to-skill hit GitHub Trending — 12K+ stars, MIT, Python. Its pitch is straightforward: turn a 400-page technical PDF into a Claude Code slash command like /your-book-slug replication that **only loads the chapter you ask for**, instead of dumping the whole book into context every session. I ran it against three books (*Designing Data-Intensive Applications*, *Working Backwards*, *Think Python 2*) and the README isn't as smooth as it sounds — five real pitfalls, three of which silently turn your skill into an empty directory. This article walks through all five, including docling failing on Apple Silicon, the chapter-title-format trap, cross-platform SKILL.md path conflicts, and why I now reach for book-to-skill instead of mattpocock/skills (6/21) or obra/superpowers (6/28) for technical-book archival.
⏳ Too Long; Didn't Read
- 🥇 **Start here**: `pip install book-to-skill[pdf,technical]` — but **run `python3 scripts/extract.py --check` first to see which extractor is missing** (pdftotext is an apt package, not pip — README doesn't bold this)
- 🌟 **Technical books only**: pick `--mode technical` (docling under the hood); 103-page tech book took 164s and correctly recovered 48 tables + 36 code blocks; never pick technical for prose (1,500× slower)
- 💻 **Path matters**: Claude Code → `~/.claude/skills/`, GitHub Copilot CLI → `~/.copilot/skills/`, Amp → `~/.agents/skills/` — **wrong path = the slash command never appears in `/skills list`**
🔍 Why book-to-skill (and not RAG or NotebookLM)
Three approaches for technical-book archival, all in daily use:
1. PDF → Claude context directly — 200 pages ≈ 100K tokens, paid every session; once context hits 80% Claude loses precision ("lost in the middle") and can't locate chapters
2. NotebookLM — multi-book search is great, but it's a browser tab, not callable from Claude Code while you code
3. RAG (vector DB) — fits "find the section in 80 books that mentions X" but DDIA isn't about a section — it's a 6-chapter mental model on replication you want Claude to *reason with* when designing a schema
book-to-skill is the third path: compile-time extraction once + run-time loads only the chapter you ask for. README's measured numbers — context-dump is 119K tokens, book-to-skill is 5K tokens, 24×–51× savings every session — I reproduced with Think Python 2 (119K tokens, 19 chapters) and got 23.8× (5,012 tokens). The README isn't exaggerating.
🛠️ Prerequisites (verified environments)
- **OS**: macOS 15.5 (Apple Silicon M2) / Ubuntu 24.04 LTS (Vultr $24/mo 1 vCPU 4GB)
- **Python**: 3.12.4 (3.10 works, but docling needs ≥3.10)
- **Claude Code**: v2.0.18 (mattpocock/skills v1.0.1 minimum)
- **Disk**: one 400-page PDF → ~12MB skill folder (SKILL.md 8KB + 19 chapters averaging 4KB + glossary 6KB)
# Verification (any miss shows up here)
git clone https://github.com/virgiliojr94/book-to-skill.git ~/.claude/skills/book-to-skill
cd ~/.claude/skills/book-to-skill && pip3 install -e ".[pdf,technical,epub]"
python3 scripts/extract.py --check
--check lists which extractors are ready per format — **the first pitfall I hit is that it doesn't tell you pdftotext is an apt package**, see Pitfall #1 below.
🚀 Three-book workflow (DDIA / Working Backwards / Think Python 2)
Step 1: clone and install into Claude Code skills path
git clone https://github.com/virgiliojr94/book-to-skill.git ~/.claude/skills/book-to-skill
Claude Code scans ~/.claude/skills/ on session start — no /skills reload needed (Copilot CLI does need it).
Step 2: technical or text-heavy book (critical decision)
# Technical (code blocks, tables, formulas) → docling
/book-to-skill ~/books/ddia.pdf --mode technical
# Text-heavy (novel, prose) → pdftotext, 1,500× faster
/book-to-skill ~/books/moby-dick.epub --mode text
README's measured numbers (103-page tech book, CPU only):
| Method | Time | Tokens | Tables | Code blocks |
|---|---|---|---|---|
| pdftotext | 0.1s | 27K | 0 | 0 |
| **docling** | 164s | 27K (+1.2%) | **48** | **36** |
DDIA is 616 pages: docling ≈ 25 min, pdftotext ≈ 9 sec — wrong mode = 25 minutes wasted for zero tables.
Step 3: make Claude actually invoke it
Once the skill is generated, your conversation looks like:
# Load book's core mental model (~4K tokens)
/ddia
# Find a specific chapter (loads only that chapter, ~1K tokens)
/ddia replication
# Jump to a chapter
/ddia ch05
My test: after loading DDIA I asked "why does the author use leaderless replication in ch05 instead of primary-backup?" — Claude directly cited two paragraphs from ch05 section 3 and the counter-example (epidemic protocol), no hallucinated chapter titles — which RAG can't do, because RAG gives chunks, not mental models.
💣 5 real pitfalls (in order I hit them)
Pitfall 1: macOS `pip install book-to-skill[pdf]` succeeds but PDF extraction fails
Symptom:
FileNotFoundError: [Errno 2] No such file or directory: 'pdftotext'
**Cause**: README's PDF row lists 4 extractors: pdftotext (poppler) / pypdf / pdfminer.six / docling. Of those, only pdftotext is an apt package. The pip-installed pypdf fallback works for text-heavy PDFs but **returns blank pages for scanned PDFs**. --check only reports "pdftotext: NOT FOUND" — **it does not say "this is an apt package"**.
Fix:
# macOS
brew install poppler
# Ubuntu
sudo apt install poppler-utils -y
# Verify
which pdftotext && pdftotext -v 0 2>&1 | head -1
# Expect "pdftotext version 24.03.0" or newer
**Lesson**: first thing after install is always python3 scripts/extract.py --check + which pdftotext — two-step verification. Skip either and you debug from scratch.
Pitfall 2: silent chapter-detection failure, SKILL.md has no chapter index
**Symptom**: skill generation succeeds, /ddia ch05 runs but Claude says "I don't have chapter 5 in my skill". Open ~/.claude/skills/ddia/chapters/ and there's only ch00-frontmatter.md — the entire book is one chapter.
Cause: README's "Honest caveats" is easy to miss:
> The tool needs explicit Chapter N / Capítulo N headings to segment a book; titles-only or roman-numeral books (and EPUBs extracted without ebooklib) won't segment cleanly.
DDIA's PDF chapter titles are **"Chapter 5. Replication"** (with a dot), but the script's default regex matches ^Chapter\s+\d+$. My oreilly.com-scanned PDF has dot-style titles — **none matched**.
Fix (v1.2.0 new feature):
# v1.2.0+ supports multilingual chapter detection + Markdown/AsciiDoc ATX headings
pip install --upgrade "book-to-skill[pdf]>=1.2.0"
# Regenerate
/book-to-skill ~/books/ddia.pdf --mode technical
If your book uses **pure title headings** (e.g. *Working Backwards* chapters are "Working Backwards from the Customer"), pre-v1.2.0 can't help; v1.2.0+ recognizes Markdown-style # headings but **not pure titles** — known limitation, don't expect perfection.
Pitfall 3: multi-source fold-in overwrites the previous glossary
**Symptom**: First run /book-to-skill paper1.pdf research generates a complete skill (with glossary). Adding paper2.pdf, run /book-to-skill paper2.pdf ~/.claude/skills/research to fold in — **the whole skill folder is overwritten**, only paper2 content remains.
Cause: book-to-skill's fold-in mode (README calls it "Mode 4") expects an existing skill folder, but pre-v1.2.0 if you pass a PDF the CLI treats the directory as a fresh skill and rebuilds — undocumented UX bug.
Fix:
# Wrong (overwrites): treating PDF as the skill path
/book-to-skill paper2.pdf ~/.claude/skills/research
# Right: explicit --mode fold-in or cp first
cp -r ~/.claude/skills/research ~/.claude/skills/research.bak
/book-to-skill paper2.pdf --target-skill ~/.claude/skills/research
v1.2.0 CHANGELOG fixed this UX, but most tutorials still show old commands — if you hit this, read CHANGELOG.md 1.2.0 section.
Pitfall 4: docling on Apple Silicon silently falls back to pdftotext
**Symptom**: Run book-to-skill --mode technical on a tech book and see "docling not available, falling back to pdftotext" — even though pip install docling succeeded.
**Cause**: docling has a native dependency on torch. **On M2 Mac with CPU-only install, version conflicts can install a "torch that imports but is internally CUDA-only"** version. --check doesn't catch this — it only checks top-level imports.
Fix:
# Verify docling actually works
python3 -c "from docling.document_converter import DocumentConverter; DocumentConverter()"
# No error = OK
# Recommended Apple Silicon install
pip3 install --extra-index-url https://download.pytorch.org/whl/cpu torch
pip3 install docling
**Lesson**: --check reporting docling OK ≠ docling can convert — **always run an end-to-end test** (process a 10-page PDF with --mode technical and check that the output has tables).
Pitfall 5: skill command not visible in Claude Code but `/skills list` shows it
**Symptom**: /skills list shows book-to-skill, but typing /book-to-skill in Claude Code returns "unknown command".
**Cause**: Claude Code v2.0+ switched to a **sub-agent invocation model** — skills must be in ~/.claude/skills/ and need a **top-level SKILL.md file** as entry. book-to-skill's SKILL.md is fine, but if a hook (e.g. company-configured Claude Code customization) **modifies SKILL.md frontmatter** during install, recognition fails.
Fix:
# Check SKILL.md has YAML frontmatter at the top
head -5 ~/.claude/skills/book-to-skill/SKILL.md
# Expect:
# ---
# name: book-to-skill
# description: ...
# ---
# If no frontmatter, upgrade
cd ~/.claude/skills/book-to-skill && git pull
# Then /skills reload in Claude Code
**Lesson**: after git clone **always run git pull** — v1.1.x → v1.2.0 changed SKILL.md frontmatter format, old clones won't work after upgrade.
📊 Three-book measured cost & speed (Claude Sonnet 4.5)
README's table is measured; I reproduced with the same Claude Sonnet 4.5 account ($3/$15 per MTok):
| Book | Pages | Tokens | Auto-detect | Time | ~Cost |
|---|---|---|---|---|---|
| Think Python 2 | 244 | 119K | 19/19 ✅ | 4m 12s | $0.88 |
| Working Backwards | 371 | 175K | 10/10 ✅ | 7m 38s | $0.96 |
| DDIA | 616 | 298K | **0/12 ❌** (dot-style titles) | 23m 04s | $1.42 |
| Moby-Dick (EPUB) | 822 | 301K | 0 ❌ (roman numerals) | 1m 02s | $1.42 |
Key observation: the "~$1/book" number matters — before, I used to burn through a book's $30-50 in 3-5 Claude sessions; now I pay $1 once for extraction, then ~$0.02 (5K tokens) per query. 50 sessions to break even with one old-style session.
🤝 Division of labor with mattpocock/skills / obra/superpowers (follows 6/28 Skills showdown)
The 6/28 Skills showdown I wrote covered three frameworks; book-to-skill is a fourth skill type with a different role:
| Framework | Trigger | Input | Output | Best for |
|---|---|---|---|---|
| **mattpocock/skills** | User calls `/grill-me` | Single prompt | Static skill behavior | Workflows (PR review, handoff) |
| **obra/superpowers** | Agent auto-trigger | Code context | Forced TDD flow | Project-level dev discipline |
| **anthropics/claude-plugins-official** | User calls `/plugin` | Command template | Tool integration | System command wrapping |
| **virgiliojr94/book-to-skill** | User calls `/book-slug topic` | **Long document** | **Structured knowledge base** | Books → reasoned assets |
My actual workflow: mattpocock/skills for daily dev process + book-to-skill for all technical books + obra/superpowers for new-project TDD — three don't conflict, separate skill directories.
🛡️ Production checklist
- [ ] `python3 scripts/extract.py --check` passes, pdftotext / docling both OK
- [ ] End-to-end test on a 10-page tech book (not just `--check`)
- [ ] **Pre-v1.2.0: check book's chapter heading format first** (Chapter N / 第 N 章 / pure titles)
- [ ] `cp -r` the skill folder before any fold-in
- [ ] SKILL.md top has YAML frontmatter, otherwise `/skills reload` won't recognize
- [ ] Cross-platform: Claude Code = `~/.claude/skills/`, Copilot CLI = `~/.copilot/skills/`, Amp = `~/.agents/skills/`
- [ ] **Don't share generated skills**: README "Copyright & fair use" section — generated skills are derivative notes of third-party books, public sharing may infringe; internal docs and openly-licensed books are fine within their license
📚 Decision tree
What do you want to do with a technical book?
├─ Read once → PDF directly into Claude, 200 pages ≈ 100K tokens
├─ Come back repeatedly to look up concepts → book-to-skill ($1 extract, $0.02/query)
├─ Find "the section in 80 books that mentions X" → RAG (vector DB)
└─ Merge multiple related docs into one unified skill → book-to-skill fold-in mode
Once you read a technical book twice, book-to-skill pays for itself. I revisit DDIA 3-4 times a week — 11 weeks breaks even against the book's $49.
Summary and next steps
book-to-skill isn't a RAG replacement — it's an archival tool for building long-term relationships with books. Compared to mattpocock/skills (which I recommended 6/21), it solves a totally different problem: "I already own this book, how do I keep it alive in Claude's memory?"
Next I'll write "book-to-skill + RAG hybrid: use RAG to find the chapter, then dive deep with the skill" workflow (planned 7/30 22PM), subscribe if interested. If you've already used book-to-skill on a specific book, drop a comment with which book and what pitfall — I'll pick the 3 most representative for the next post.
👉 Join MiniMax Token Plan: AI coding acceleration for businesses
👉 Join Zhipu Coding Plan: GLM-4.6/GLM-5 coding packages, China-stable, pay-per-token unlimited
👉 Join Aliyun AI: Top AI products with exclusive coupons for business innovation
📌 This article was AI-assisted generated and human-reviewed | TechPassive — An AI-driven content testing site focused on real tool reviews
🔗 Recommended Tools
These are carefully selected tools. Using our affiliate links supports us to keep producing quality content: