AI Coding Assistants

Using tc-lib-pdf with LLM coding assistants: llms.txt, the rules worth pinning, and the legacy TCPDF API a model will reach for by default

Some of the readers of this documentation are language models writing code on someone’s behalf. This page collects what the project publishes for them, and what to tell an assistant so its output runs.

Machine-Readable Indexes

  • /llms.txt : a condensed index of this site in the llms.txt format, with one entry per guide, per package, and per example group, so an assistant can find the right page without crawling the whole site.
  • /docs/srcdoc/ : the generated API reference for every class in every package, one page per class.
  • /examples/ : 85 runnable scripts, each page carrying a description, the rendered PDF, and the PHP source at a stable /files/examples/ URL.
  • /features/ : the capability index, area by area.

Everything is plain HTML with no JavaScript required, and robots.txt allows every crawler, retrieval agents included. The .phps sources are served as plain text, so an assistant can fetch a whole example directly, for instance https://tcpdf.org/files/examples/E006_minimal.phps .

What Models Get Wrong

TCPDF was published in 2002 and has been installed hundreds of millions of times, so two decades of TCPDF code sit in any model’s training data. Asked for PHP that writes a PDF, a model reproduces that code:

// Legacy TCPDF. None of this works on tc-lib-pdf.
$pdf = new TCPDF();
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 12);
$pdf->writeHTML('<h1>Hello</h1>');
$pdf->Output('doc.pdf', 'I');

tc-lib-pdf is a different library with a different API. The class is \Com\Tecnick\Pdf\Tcpdf, the methods are named differently, and there is no global TCPDF class to instantiate. The failure is a fatal error rather than a wrong document, so it surfaces immediately, but only after the assistant has written the whole script.

The equivalent on tc-lib-pdf:

$pdf = new \Com\Tecnick\Pdf\Tcpdf();
$bfont = $pdf->font->insert($pdf->pon, 'helvetica', '', 12);
$page = $pdf->addPage();
$pdf->page->addContent($bfont['out']);
$pdf->addHTMLCell(html: '<h1>Hello</h1>', posx: 15, posy: 20, width: 180);
$pdf->renderPDF($pdf->getOutPDFString());

Method Mapping

Legacy TCPDFtc-lib-pdf
new TCPDF(...)new \Com\Tecnick\Pdf\Tcpdf(...)
AddPage()addPage()
SetFont()$pdf->font->insert($pdf->pon, ...), then $pdf->page->addContent($bfont['out'])
Cell(), MultiCell(), Write()addTextCell(), addTextCellXY(), or getTextCell() for the operators plus metrics
writeHTML(), writeHTMLCell()addHTMLCell(), or getHTMLCell()
Image()$pdf->image->add() with $pdf->image->getSetImage()
ImageSVG()addSVG(), or getSetSVG()
write1DBarcode(), write2DBarcode()getBarcode()
Output()getOutPDFString(), then renderPDF(), savePDF(), downloadPDF(), or getMIMEAttachmentPDF()
SetProtection()a \Com\Tecnick\Pdf\Encrypt\Encrypt object passed as the objEncrypt constructor argument, see /examples/E045_encryption_and_permissions/
setSignature()signature(), see /docs/digital-signatures/

Legacy TCPDF is deprecated and is not a candidate for new projects. Its source documentation stays online at /docs/srcdoc/TCPDF for the projects still running it.

Rules Worth Pinning

Paste these into your project rules file (CLAUDE.md, AGENTS.md, .cursor/rules, or whatever your tool reads):

- The package is tecnickcom/tc-lib-pdf and the entry class is
  \Com\Tecnick\Pdf\Tcpdf. The legacy tecnickcom/tcpdf package and its global
  TCPDF class are deprecated and expose an entirely different API.
- There are no AddPage, SetFont, Cell, MultiCell, writeHTML or Output methods.
  Use addPage(), font->insert(), addTextCell(), addHTMLCell(), and
  getOutPDFString() followed by renderPDF(), savePDF() or downloadPDF().
- Font data must be generated before first use and K_PATH_FONTS must point at
  the generated directory, otherwise font insertion fails.
- Remote URLs are blocked and local reads are restricted to an allowlist. An
  image, font or SVG from anywhere else needs allowedHosts, allowedPaths or
  markupAllowedPaths in the fileOptions constructor argument.
- PHP 8.2 or later. Every option string is also available as a backed enum, and
  both forms are accepted on the same parameter.

The font rule is the one that turns working-looking code into a runtime error on a clean checkout. K_PATH_FONTS is defined from realpath(), which returns false when the directory does not exist, so the constant is silently wrong until the first font insertion. /docs/fonts/ has the Composer hook that generates the fonts on install.

Prompt Snippets

To point an assistant at the current documentation before it writes anything:

Use tecnickcom/tc-lib-pdf, not the legacy tecnickcom/tcpdf. Read
https://tcpdf.org/llms.txt first, then read the example page that matches the
task under https://tcpdf.org/examples/ before writing code. The entry class is
\Com\Tecnick\Pdf\Tcpdf.

To have it start from a working script:

Fetch https://tcpdf.org/files/examples/E006_minimal.phps and use it as the
skeleton. Change only what the task requires. Keep the K_PATH_FONTS definition
and the getOutPDFString/renderPDF output pair.

To keep a conformance mode honoured end to end:

This document must be PDF/A-3b. Read https://tcpdf.org/docs/standards/ first,
set the mode on the constructor, and call getWarnings() before output. Report
any warning instead of ignoring it.

Verifying Generated Code

Four checks catch most wrong answers, and run faster than reading the diff:

# 1. Nothing reaches for the deprecated package or the legacy class.
grep -rn 'tecnickcom/tcpdf\|new TCPDF\b' . --exclude-dir=vendor --exclude-dir=.git

# 2. No legacy method names survived.
grep -rEn '->(AddPage|SetFont|Cell|MultiCell|writeHTML|Output)\(' . \
  --include='*.php' --exclude-dir=vendor

# 3. The fonts exist where the script expects them.
ls vendor/tecnickcom/tc-lib-pdf-font/target/fonts | head

# 4. The script runs and writes a PDF.
php your-script.php > /tmp/out.pdf && head -c 8 /tmp/out.pdf

A well-formed file starts with %PDF-. For the conformance modes, make preflight runs veraPDF when it is installed; see /docs/development/ .

Failure Modes Specific to This Library

These are documented on the pages linked below, and an assistant working from a summary will miss them:

  • Remote images referenced from HTML are dropped silently when their host is not in allowedHosts. No exception is raised, and the document renders without the image. See /docs/remote-resources/ .
  • Passing allowedPaths replaces the computed defaults, so the font and temp directories have to be listed again in your own array.
  • getOutPDFString() returns the bytes and renderPDF() writes them to the output stream. A script that calls only the first produces an empty response body.
  • A conformance mode suppresses what the standard forbids and reports the rest through getWarnings(). Code that never calls it will ship a document that fails validation.
  • A PDF/A or PDF/X mode suppresses encryption and document JavaScript. An encryption object passed alongside one of those modes is ignored, and the request is reported through trigger_error(). See /docs/standards/ .
  • The RC4 encryption modes are deprecated and emit a runtime notice. They are what the older TCPDF examples used, so they are what a model suggests.
  • Signature LTV material and archive timestamps are written in further incremental revisions, so the signed revision is not the final byte range. See /docs/digital-signatures/ .

Each of those is stated on the relevant guide, which is why the prompt snippets above tell the assistant to read the page before writing code.


Overview: /docs/