Skip to content
View Nizoka's full-sized avatar

Block or report Nizoka

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Content in all repositories owned by your account will be closed.
Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
Nizoka/README.md
the native family — pdfnative (ISO 32000-1), zipnative (ISO/IEC 21320-1), pkinative (RFC 5280)

Nizoka

Zero-dependency TypeScript engines for the formats nobody wants to reimplement — PDF, ZIP, PKI.

Most of this code was drafted by AI agents. None of it was shipped by one: there is no long-lived publish token anywhere in this ecosystem, so the only path to the registry is a release a human cut by hand. How this is built ↓

Start here

npm install pdfnative
import { buildDocumentPDFBytes, extractText } from 'pdfnative';

const pdf = buildDocumentPDFBytes({
  title: 'Hello',
  blocks: [{ type: 'paragraph', text: 'Hello, world.' }],
});

extractText(pdf)[0].text; // 'Hello, world.' — it parses, too

Prefer a shell? npx pdfnative-cli render -o out.pdf. ZIP or PKI instead? npm install zipnative, npm install pkinative — same doctrine, same shape.

Driving an agent? All three MCP servers are listed in the official MCP Registry. One config gives any MCP client PDF, ZIP and PKI:

{
  "mcpServers": {
    "pdfnative": { "command": "npx", "args": ["-y", "pdfnative-mcp"] },
    "zipnative": { "command": "npx", "args": ["-y", "zipnative-mcp"] },
    "pkinative": { "command": "npx", "args": ["-y", "pkinative-mcp"] }
  }
}

As written, none of them touches a file: inputs and outputs travel inline. Set PDFNATIVE_MCP_OUTPUT_DIR — or its zip and pki twin — and that server gets exactly one sandbox directory, nothing outside it.

The native family

The engine is the library; the CLI is the trust boundary the engine refuses to be; the MCP server is the same capability, addressable by an agent. Each engine exiles its integrations — filesystem sinks, process I/O, the MCP SDK — into satellite repos, so the core can stay dependency-free.

Package Latest Engine What it does
pdfnative npm version — 0 deps. PDF engine — ISO 32000-1, PDF/A-1b→3b, PDF/X-4, PAdES B-B→B-LTA signing, 27 scripts shaped with GSUB/GPOS, no fontkit
pdfnative-cli npm version pdfnative range 21 commands — render, sign, verify, LTV, inspect, compare, batch
pdfnative-mcp npm version pdfnative range 28 MCP tools, no network path by default
pdfnative-react npm version pdfnative peer range JSX → PDF. No DOM, no headless browser, no SaaS round-trip
zipnative npm version — 0 deps. ZIP engine — own DEFLATE/INFLATE, Zip64, random access without extracting, incremental edits without recompression
zipnative-cli npm version zipnative range 15 commands — zip-slip, symlink, bomb and duplicate guards on by default
zipnative-mcp npm version zipnative range 13 MCP tools, sandboxed to one directory, verified by realpath
pkinative npm version — 0 deps. PKI engine — X.509 and ASN.1 DER, RFC 5280 paths with CRL/OCSP, CMS and RFC 3161 timestamps, PKCS#8/#12; every signature through Web Crypto
pkinative-cli npm version pkinative range 18 commands — inspect, verify, issue, sign; every one of the engine's 294 exports, offline, --json for agents
pkinative-mcp npm version pkinative range 34 MCP tools, no network code path, no key byte ever returned — every artefact re-read by OpenSSL 3

Engine is the range each satellite declares on its engine, read live from npm. A caret range takes every engine minor without a satellite release, so an engine can lead its satellites — and the Latest column shows by how much.

Engines carry zero runtime dependencies. The CLIs add none beyond their engine; the MCP servers add the MCP SDK and zod, pdfnative-react adds react-reconciler — and nothing else. For scale, measured 2026-07-28: pdfkit ships 6 runtime dependencies, pdf-lib 4, jsPDF 3, pdfmake 3. Of the TypeScript PKI libraries measured on 2026-09-19, only pkinative and micro509 ship zero — asn1js 3, pkijs 6, @peculiar/x509 11.

One API surface. Node.js ≥ 22 and browsers run in CI; Deno, Bun and Workers follow from the architecture but are not yet a tested matrix. MIT, all of it.

The doctrine

Four rules, inherited down the family. Each is enforced by code somewhere — and the row says where.

Rule Enforced by
Zero runtime dependencies The engines declare no dependencies at all. In pdfnative and pkinative, tree-shaking probes bundle isolated imports against byte budgets and forbidden-marker assertions — importing a color parser must not drag in an AES S-box.
Secure-by-default parsing Every loop over untrusted bytes consults a named limit, the riskiest tagged with its CWE. pkinative's ASN.1 decoder is iterative: depth is a bounded number, never the call stack.
Determinism as a product feature Byte-identical output, buffered or streaming, serial or parallel — and across runtimes under deterministic: true. Changing those bytes is a semver-major.
No I/O in the engine No filesystem, no network, no process, no eval. The only node: touch is an optional zlib fast path that the pure-TypeScript codec replaces when it is absent. In pkinative an architecture test decides this from the syntax tree and fails the build.

How this is built

Every repo carries AGENTS.md, .github/AGENT_RULES.md and a machine-readable .github/ai-governance.json. They assign exactly one role to the agent and one to the human:

You act as a draftsman, never as an autonomous submitter.

"human_in_the_loop": {
  "role_of_agent": "draftsman",
  "gate": "A human MUST explicitly review, sign off on, and trigger any …"
}

In full, the gate ends: the agent's authority ends at producing a local draft plus a compliance report. That is the policy. This is the enforcement: in every repo but zipnative-cli and zipnative-mcp, a PreToolUse hook denies npm publish, gh pr create, gh release and any git push — including when the command is buried inside $( ), sh -c or a node -e payload. Its rule table has its own test file. Weaken the governance and the build fails.

agent drafts
   ↓
local reproduction
   ↓
zero-dependency check
   ↓
draft + compliance report
   ↓
human reviews & signs off   ← the gate
   ↓
human submits. never the agent.

And the line the agent must repeat before every submission, straight out of ai-governance.json: anything submitted is published under the human's GitHub identity, and the human shares responsibility for the content.

Agents draft. Gates decide. A human signs.

Verified, not claimed

Every line below is a CI job against an outside corpus — not a badge someone drew.

  • veraPDF — PDF/A conformance across the pdfnative repos, including negative canaries the validator is required to reject. Blocking in all four.
  • ISO/IEC 21320-1 — clause by clause, fail-closed, on Linux and Windows. No external ZIP validator exists — JHOVE has no ZIP module — so this one is the project's own; the corpus and its negative canaries are what make it a test rather than a claim.
  • x509-limbo, Wycheproof + NIST PKITS — 30 361 certificates, 1 530 ECDSA vectors, the 405 PKITS certificates and 224 signed S/MIME messages, pinned by commit and SHA-256, differentially cross-checked against OpenSSL. The 565 refusals sit in a reviewed baseline, frozen with their codes for the whole 1.x line.
  • OpenSSL 3 — every artefact pkinative-mcp writes, re-read by OpenSSL across 12 command families: a 28-entry corpus, five of them canaries OpenSSL must refuse, blocking on Linux and Windows. The other direction too — 42 fixtures OpenSSL wrote, read and verified by the tools.
  • npm Trusted Publishing (OIDC) + SLSA provenance — on all ten published packages. No long-lived token exists anywhere.

Every engine, and every satellite but zipnative-cli and zipnative-mcp, holds the numbers its docs quote to a single source of truth — an ecosystem.json or its own data registries — and a verify:docs step breaks the build when the prose disagrees.

Latest release

pkinative-mcp 1.0 shipped on 2026-10-17 — pkinative, addressable by an agent. 34 tools inspect and verify certificates and chains, CRLs, OCSP responses, CMS signatures and RFC 3161 timestamps; issue certificates and CSRs; open PKCS#8 and PKCS#12. Every one of the engine's 117 runtime exports is reached by a named tool, and a test proves it.

There is no network code path in it — no CRL, OCSP or TSA fetch, no telemetry: the server builds the request bytes, the caller carries them, the server judges the evidence that comes back. Signing keys stay non-extractable Web Crypto handles and no tool returns a key byte. A refused certificate is a verdict — valid: false with pkinative's reason codes — never a crash. The tool API is frozen at _meta.apiVersion 1.0.0.

With it the PKI line is complete: engine, CLI and MCP server, all at 1.0 within thirteen days — CLI first, then MCP, the order both elders followed. Next: pdfnative's own signature stack moving onto pkinative.

Earlier releases

pkinative-cli 1.0 shipped on 2026-10-08 — the engine's command line, with pkinative as its one runtime dependency. 18 commands reach every one of pkinative's 294 exports, and a test proves it; nothing is fetched from the network, and --json gives scripts and agents a stable contract: the report on stdout, one envelope on stderr, pkinative's codes verbatim.

pkinative 1.0 shipped on 2026-10-04 — a zero-dependency PKI engine, extracted from pdfnative's signature stack and destined to return to it.

It reads certificates strictly — DER by default, BER only on request — and verifies them the whole way: signatures, RFC 5280 §6 paths, CRL and OCSP revocation, host names and key purposes. It reads, builds and verifies CMS SignedData and RFC 3161 timestamps, opens PKCS#8 and PKCS#12 into non-extractable Web Crypto keys, and creates certificates and certification requests. Secret-dependent cryptography is never written in TypeScript here: Web Crypto does every signature.

The 1.x promise has three legs — the export surface, the error codes, and the decision surface: which certificate is refused, with which code. Each is a frozen snapshot that a build rule holds, not a sentence. Stated plainly: there is no external security audit at 1.0; what stands in its place is listed in its SECURITY.md.


MIT · pdfnative.dev · zipnative.dev · pkinative.dev · Sponsor on GitHub

Pinned Loading

  1. pdfnative pdfnative Public

    Lightweight, zero-dependency PDF engine in pure TypeScript. Fast on-device generation (no Chromium). Create, parse, sign, and modify ISO 32000-1 docs. Supports PDF/A, PDF/UA, BiDi, and font shaping.

    TypeScript 17 1

  2. zipnative zipnative Public

    Zero-dependency ZIP engine in pure TypeScript — random-access reads, secure-by-default extraction (zip-slip & zip-bomb guards), deterministic reproducible archives, streaming, in-place incremental …

    TypeScript

  3. pkinative pkinative Public

    Zero-dependency PKI toolkit in pure TypeScript. Parse and verify X.509 certificates (RFC 5280 paths, CRL, OCSP, host names), CMS signatures and RFC 3161 timestamps; open PKCS#8/#12 keys; create cer…

    TypeScript

  4. pdfnative-mcp pdfnative-mcp Public

    Official Model Context Protocol (MCP) server for local-first PDF/A generation. Empowers AI agents (Claude, Cursor, Zed) to securely create, sign (PAdES), verify, and transform documents with barcod…

    TypeScript 2

  5. pdfnative-cli pdfnative-cli Public

    High-performance, zero-dependency CLI for the pdfnative engine. Automate JSON-to-PDF/A rendering, digital signatures (RSA/ECDSA), and compliance inspection within CI/CD pipelines via shell-pipe wor…

    TypeScript

  6. zipnative-cli zipnative-cli Public

    Agent-grade ZIP CLI on the zipnative engine — create deterministic, reproducible archives, list and inspect without extracting, extract with zip-slip / zip-bomb / symlink guards, verify, stream, mo…

    TypeScript