The NextPDF design philosophy
Ce contenu n’est pas encore disponible dans votre langue.
Spec: ISO/IEC 25010 ISO/IEC 25010 Spec: ISO 32000-2 ISO 32000-2 Evidence: Design principle
At a glance
Section titled “At a glance”This page states the principles every NextPDF API decision is held against. They are deliberately few, because a principle you cannot recite is one you cannot apply under pressure.
It is the page to read first. The other Insider_ pages show these principles at work in specific places. This one names them so the rest make sense.
Why this matters
Section titled “Why this matters”PDF is old enough to have opinions, and strict enough to punish guesses. A signature covers exactly the bytes it covers. A font is either embedded or it is not. An archival profile either holds or fails an audit months later, in front of someone who needs evidence.
A library has a choice when the inputs are ambiguous. It can guess and stay quiet, or it can stop and say so. The first feels friendlier in a demo. It can also cost you a production incident with no trace of what went wrong. NextPDF chooses the second. It accepts a less reassuring first impression in exchange for a defensible one. Software quality standards name this trade directly. Fail-safe behaviour is the capability of a product to revert to a safe state on failure rather than continue in an undefined one ( Spec: ISO/IEC 25010, §3 ISO/IEC 25010 §3 ).
The short version
Section titled “The short version”NextPDF is built on five principles, in priority order:
- Explicit beats implicit. If intent matters, you state it. The engine does not infer a signature level, an output mode, or a conformance target from context.
- Fail fast, fail loud, fail early. An invalid input is rejected before a byte is written, with a message that names the cause.
- Errors are an API surface. Failures are specific, typed, and carry structured context — designed, not incidental.
- Boundaries are stated, not discovered. Every claim says where it stops. “Necessary, not sufficient” is a phrase NextPDF states on purpose.
- Nothing silently degrades. The engine does not return a half-correct artifact that looks finished.
Everything else — the fluent builder, the disposable document, strict typing — is downstream of these.
How NextPDF approaches it
Section titled “How NextPDF approaches it”The principles are not slogans. They show up as concrete shapes in the source, and they reinforce one another.
The table below maps each principle to where you can see it in the engine and what it costs if it is absent.
| Principle | How it shows up in NextPDF | The cost of the opposite |
|---|---|---|
| Explicit beats implicit | setSignature(certInfo:, level:) takes the PAdES level as a required, named argument — there is no “auto” level | A document signed at a profile the obligation did not require, discovered at validation time |
| Fail fast, fail loud | save() rejects a stream-wrapper or null-byte path before rendering; setSignature() followed by save() throws rather than emit an unsigned file | A path-traversal write, or an “unsigned but believed signed” PDF in an archive |
| Errors are an API surface | One abstract base exception, specific typed subclasses, each exposing structured getContext() for logs and APM | A generic stack trace and a long afternoon of guessing |
| Boundaries are stated | In-process conformance checks return findings and say in words that the verdict belongs to an independent validator | A “no exception, so it must be conformant” conclusion that an auditor disproves |
| Nothing silently degrades | The archival-timestamp path refuses to return a half-written profile rather than emit one missing its required dictionary | A long-term-validation profile that quietly is not one |
Read the principles together and a single stance emerges: the engine would rather give you an honest “no” than a confident “maybe”. That is not pessimism. It recognizes that a PDF is often a legal artifact. A legal artifact that is wrong is worse than one that was never produced.
What the evidence says
Section titled “What the evidence says”This page is a Evidence: Design principle statement: the principles are deliberate decisions, argued rather than measured. Where a principle has a name in an external discipline, the page anchors to it so the reasoning is not merely an in-house opinion.
- The “refuse rather than continue in an undefined state” stance is the fail-safe quality property in Spec: ISO/IEC 25010 ISO/IEC 25010 §3 — a product that places itself in a safe condition on failure. Fault tolerance, in the same family, is the degree to which a system keeps behaving as intended despite faults. NextPDF directs that effort toward detecting and stopping, not toward concealing the fault.
- The “state the boundary before adoption” stance is appropriateness recognizability ( Spec: ISO/IEC 25010, §3.26 ISO/IEC 25010 §3.26 ): the ability to judge fit from documentation and first impressions.
- The PDF-specific reason any of this matters is Spec: ISO 32000-2, §12.8 ISO 32000-2 §12.8 : a signature’s byte range protects exactly the bytes it covers and nothing more, so an engine that “helpfully” rewrites or guesses around a signed document has not helped at all.
The individual principles are demonstrated against real engine source on their own pages — An API that refuses to guess and Errors as a feature carry the Evidence: Code-backed proof. This page is the why; those pages are the what.
Practical example
Section titled “Practical example”The principles are visible in a few lines of ordinary use. The signature call states intent explicitly. The engine refuses early rather than emit something misleading.
<?php
declare(strict_types=1);
use NextPDF\Core\Document;use NextPDF\Exception\NotImplementedException;use NextPDF\Security\Signature\CertificateInfo;use NextPDF\Security\Signature\SignatureLevel;
$document = Document::createStandalone();$document->setTitle('Service Agreement 2026-0042');$document->addPage();$document->setFont('helvetica', '', 12);$document->cell(0, 10, 'This agreement is configured for a PAdES signature.', newLine: true);
// Explicit beats implicit: the PAdES level is a required, named argument.// There is no inferred or "auto" level.$document->setSignature( certInfo: new CertificateInfo( certificate: $certificatePem, privateKey: $privateKeyPem, ), level: SignatureLevel::PAdES_B_B,);
try { // Fail fast, no silent degradation: rather than emit an UNSIGNED file // that the caller believes setSignature() signed, the high-level path // refuses and names the supported route. $document->save('/srv/output/agreement.pdf');} catch (NotImplementedException $e) { // The message identifies the feature and the follow-up, not a stack // trace: "... is not implemented in this release. <actionable follow-up>" error_log($e->getMessage());}The point is not the signature mechanics. Three principles are observable in
one snippet: intent is stated (level:), the failure is early and named, and
the engine declines to produce a document that would lie about its own state.
Common misconception
Section titled “Common misconception”The most common misreading is that these principles make NextPDF “harder to use”. They make it harder to use wrongly. A required argument is one fewer silent default to be surprised by. An early exception is one fewer corrupt artifact in an archive. The friction is deliberately placed where a mistake is cheap — at the call site, in development — instead of where it is expensive: in production, in an audit, in court.
A second misreading is that “opinionated” means “inflexible”. It does not. The engine has opinions about correctness and intent, not about your document. You still control layout, content, fonts, and structure completely. The opinions are about not guessing on your behalf where a guess would be unsafe.
Limits and boundaries
Section titled “Limits and boundaries”This page states design intent. It is not itself a behavioural specification. The principles describe how decisions are made, not a guarantee about any one method. Each method’s exact contract lives in the reference and in its own Insider_ page with that page’s evidence level.
The principles are also not absolute laws of physics. They are priorities, applied with judgement. Where two principles conflict (a stricter refusal versus a more forgiving default), the priority order above is the tie-breaker. A specific module may still document a reasoned exception. When it does, that exception is written down, not assumed.
Finally, “design principle” is the evidence basis here by design. This page argues. It does not benchmark. Claims that need a number, a test, or a clause to be supported are made on the pages that own that evidence, not here.
Related docs
Section titled “Related docs”- An API that refuses to guess — the explicit-intent and fail-fast principles, shown against the real API.
- Errors as a feature — the typed exception hierarchy as a designed surface.
- The PHP 8.4 foundations — the language features that let these principles be enforced rather than hoped for.
Glossary
Section titled “Glossary”- Design principle (evidence level) — a page whose claims are deliberate design decisions, argued from intent and corroborating standards rather than measured by a benchmark or a single test.
- Fail-safe — a software-quality property: on failure, the product reverts to a safe state instead of continuing in an undefined one. The reason NextPDF refuses rather than guesses.
- Fail fast — rejecting an invalid input at the earliest possible point, with a clear cause, instead of proceeding and failing obscurely later.
- PAdES — PDF Advanced Electronic Signatures, the ETSI profile family for signing PDF documents (B-B, B-T, B-LT, B-LTA). Expanded here on first use; covered in depth on the signing pages.
- Necessary, not sufficient — a deliberate phrasing used when an in-process check is a real signal but not a conformance verdict; the authoritative decision belongs to an independent validator.