Vorabversion · v1.0.0-beta.7

PDF-Engine · E-Rechnung · reines TypeScript

PDFs und E-Rechnungen in reinem TypeScript.

Komponenten schreiben, PDF erhalten - und XRechnung- und ZUGFeRD-E-Rechnungen, die die offiziellen Prüfungen nach EN 16931 und PDF/A bestehen. Die Engine ist unsere eigene - kein Headless-Browser, kein Java - und zeichnet PDFs mit eigenem Renderer, in Node oder direkt im Browser.

invoice.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
wird zu
  • XRechnung
  • ZUGFeRD
  • EN 16931
  • PDF/A-3
  • echte Pagination
  • Vue · React · Angular · Nuxt
  • läuft im Browser
  • kein Chromium · keine JVM
  • MIT

eine Bibliothek · jedes Framework

Eine Engine. Jedes Framework.

Vue, React, Angular und Nuxt bekommen je eine Anbindung, die sich nativ anfühlt: Komponenten, wo das Framework in Komponenten denkt, ein Service und Signals, wo Angular das tut. Darunter liegt dieselbe Engine, ein Dokument sieht also gleich aus, wo immer Sie es schreiben.

  • reines TypeScript
  • kein Headless-Browser
  • kein Java, nichts Natives zu installieren
  • Node und Browser

@jasy/e-invoice · XRechnung · ZUGFeRD · Factur-X

Deutschland: Pflicht ab 2027

E-Rechnungen, die die offiziellen Prüfungen bestehen.

Ein typisiertes Objekt hinein, eine konforme E-Rechnung heraus: das PDF, das ein Mensch liest, und die EN-16931-Daten, die eine Maschine liest. Java hat Mustangproject, PHP hat horstoeko/zugferd, Python hat factur-x - das ist die Antwort für TypeScript.

invoice.ts
import { renderZugferd, type Invoice } from "@jasy/e-invoice";

const invoice: Invoice = {
  number: "INV-2027-001",
  issueDate: "2027-01-15",
  currency: "EUR",
  dueDate: "2027-01-29",
  seller: {
    name: "Northwind GmbH",
    vatId: "DE265013614",
    address: { line1: "Hauptstrasse 1", city: "Berlin", postCode: "10115", country: "DE" },
    contact: { name: "A. Schmidt", email: "billing@northwind.de", phone: "+49 30 123456" },
  },
  buyer: {
    name: "Globex AG",
    address: { line1: "Marktplatz 5", city: "Munich", postCode: "80331", country: "DE" },
  },
  lines: [{ name: "Consulting", quantity: 8, unit: "HUR", netUnitPrice: 120,
            vat: { category: "S", ratePercent: 19 } }],
  payment: { iban: "DE89370400440532013000", terms: "Payable within 14 days." },
};

const { bytes, xml } = await renderZugferd(invoice, { locale: "en" });

$ jasy validate invoice.pdf

ZUGFeRD · EN 16931 (CII) - gültig

  • EN-16931-Geschäftsregeln

    KoSIT

    0 Fehler · 0 Warnungen
  • PDF/A-3-Struktur

    Factur-X-XMP, sRGB, eingebettetes XML

    13 von 13
  • veraPDF

    PDF/A-3b-Profil

    0 fehlgeschlagene Regeln
Eigene Rechnung prüfen
  • Summen, die stimmen

    Positionen, Summen und die Aufschlüsselung nach Steuersätzen werden aus Ihren Daten berechnet - nichts doppelt getippt, kein Cent daneben.

  • ZUGFeRD, XRechnung, Factur-X

    PDF/A-3 mit dem EN-16931-XML darin, oder das XML allein - CII oder UBL, ein Schalter.

  • Ihre Daten bleiben bei Ihnen

    Kein Dienst, kein Upload, kein Java. Es läuft in Ihrem Node-Prozess, direkt bei Ihren Daten.

warum Sie uns trauen können

Zu jeder Aussage auf dieser Seite gibt es den Beleg.

  • Eine eigene Engine

    Layout, Textsatz und der PDF-Writer sind unsere eigenen, in TypeScript. Kein Chromium, kein Java, kein pdf-lib darunter.

    So funktioniert es
  • Gegen react-pdf gemessen

    Schneller, standardmäßig mit AES-256 verschlüsselt, barrierefrei nach PDF/UA - jede Messung mit dem Code zum Nachprüfen.

    Zum Vergleich
  • Geprüft, nicht behauptet

    E-Rechnungen bestehen die EN-16931-Regeln der KoSIT und veraPDF. Prüfen Sie jede Datei selbst - unsere oder jede andere.

    Zum Prüfdienst
  • Barrierefreie PDFs

    Ein Schalter erzeugt ein getaggtes PDF/UA-1-Dokument, das die maschinellen Prüfungen von veraPDF besteht.

    Barrierefreiheit
  • Byte-genaue Ausgabe

    Dasselbe Dokument ergibt jedes Mal dieselben Bytes - eine archivierte Rechnung bleibt reproduzierbar.

    Ausgabeoptionen
  • Überall, wo JavaScript läuft

    Node oder Browser, reines TypeScript, Vue, React, Angular oder Nuxt - darunter dieselbe Engine.

    Alle Anleitungen

eine Engine · zwei Laufzeiten · derselbe Code

Läuft auf Ihrem Server. Und im Browser.

Reines TypeScript, nichts, was nur in Node läuft. Derselbe Komponentenbaum ergibt dasselbe byte-genaue PDF, ob er auf einem Server läuft oder ganz im Browser - Ihre Wahl, nicht die der Bibliothek.

auf Ihrem Server

Node, Nitro, Lambda, Workers

Rechnungen und Berichte in Ihrer API oder Ihrem Backend erzeugen - mit wenigen Abhängigkeiten, ohne Chromium zu starten, ohne JVM zu füttern.

im Browser

100 % im Client

Das ganze PDF im Browser des Nutzers rendern - ohne Umweg über den Server, funktioniert offline, und nichts verlässt das Gerät.

$const bytes = await renderToBytes(doc) // derselbe Aufruf, Server oder Browser

@jasy/vue · PDFs als Vue-Komponenten

neu · auf npm

Ihr PDF ist eine Vue-Komponente.

Bauen Sie ein Dokument wie eine App - mit Komponenten, Props, Slots und Ihren reaktiven Daten - und machen Sie daraus ein echtes PDF, direkt im Browser. Darunter echtes Layout und echte Pagination, vollständig typisierte Props - und wer @react-pdf/renderer aus React kennt, fühlt sich gleich zu Hause.

Zum Vue-Guide pnpm add @jasy/vue vue
Invoice.vue
<Document>
  <Page :gap="12">
    <Text :size="30" bold>{{ invoice.title }}</Text>

    <Row
      v-for="line in invoice.lines"
      :key="line.id"
      :justify="'between'"
    >
      <Text>{{ line.name }}</Text>
      <Text bold>{{ line.total }} €</Text>
    </Row>
  </Page>
</Document>
const bytes = await renderToPdf(Invoice) // → ein PDF, direkt im Browser
  • Komponenten & Props

    Bauen Sie ein Dokument wie eine App - mit wiederverwendbaren Komponenten, Props und Slots.

  • v-for, v-if, computed

    Ihre reaktiven Daten bestimmen die Seite; Schleifen, Bedingungen und berechnete Werte funktionieren einfach.

  • Rendert im Browser

    Die isomorphe Engine macht aus dem Komponentenbaum ein PDF im Browser - ganz ohne Server.

@jasy/nuxt · das Nuxt-Modul

neu · auf npm

Sofort startklar in Nuxt.

Eine Installation, null Konfiguration. Bauen Sie PDFs als Komponenten und rendern Sie sie direkt im Browser oder streamen Sie sie aus einer Server-Route - Ihre Wahl, auf beiden Seiten dieselben Komponenten und Helfer.

Zum Nuxt-Guide npx nuxi module add @jasy/nuxt
im Browser
<script setup>
const { open, download } = usePdf(Invoice)
</script>

<template>
  <button @click="open">View PDF</button>
</template>
in einer Server-Route
// server/api/invoice/[id].get.ts
export default definePdfHandler((e) =>
  Document([
    Page([
      Text(`Invoice #${getRouterParam(e, "id")}`),
    ]),
  ]),
)
  • Null Konfiguration

    In die Module eintragen, fertig. Komponenten und Render-Helfer werden automatisch importiert - keine Verdrahtung, keine Imports.

  • Client oder Server

    Im Browser rendern mit usePdf oder aus einer Nitro-Route streamen mit definePdfHandler. Auf beiden Seiten dieselben Helfer.

  • Nitro-Cache, schlankes Bundle

    Eine Route pro Pfad und Query cachen, mit einer Option. jimp bleibt auf dem Server - das Browser-Bundle bleibt klein.

@jasy/react · PDFs als React-Komponenten

neu · auf npm

Ihr PDF ist eine React-Komponente.

Schreiben Sie ein Dokument in JSX - mit Komponenten, Props, Hooks und Context - und machen Sie daraus ein echtes PDF, direkt im Browser. Darunter echtes Layout und echte Pagination: Tabellen mit Header auf jeder Seite, Zeitungsspalten, Header und Footer, die ihren Platz behalten.

Invoice.tsx
<Document>
  <Page gap={12}>
    <Text size={30} bold>{invoice.title}</Text>

    {invoice.lines.map((line) => (
      <Row key={line.id} justify="between">
        <Text>{line.name}</Text>
        <Text bold>{line.total} €</Text>
      </Row>
    ))}
  </Page>
</Document>
const bytes = await renderToPdf(<Invoice />) // → ein PDF, direkt im Browser
  • Komponenten, Hooks & Context

    Bauen Sie ein Dokument wie eine App - mit Props, Hooks, Context und Ihren eigenen Komponenten.

  • Typisiert von der Engine

    Jeder Prop hat den Optionstyp der Engine selbst - eine neue Option ist vom ersten Tag an typisiert und wird vervollständigt.

  • Rendert im Browser

    Die isomorphe Engine macht aus dem Elementbaum ein PDF im Browser - oder auf dem Server, mit demselben Aufruf.

@jasy/angular · PDFs auf die Angular-Art

neu · auf npm

PDFs, die Ihren Signals folgen.

Ein Dokument ist eine Funktion seiner Daten. inject(JasyPdf) macht daraus ein echtes PDF, und pdfResource() rendert es neu, sobald sich Ihre Signals ändern - direkt im Browser, mit echtem Layout und echter Pagination darunter.

Zum Angular-Guide ng add @jasy/angular
invoice.pdf.ts
export const invoicePdf: PdfDocumentFn<Invoice> = (invoice) =>
  Document([
    Page({ gap: 12 }, [
      Text(invoice.title, { size: 30, bold: true }),
      ...invoice.lines.map((line) =>
        Row({ justify: "between" }, [
          Text(line.name),
          Text(`${line.total} €`, { bold: true }),
        ]),
      ),
    ]),
  ]);

// in a component: renders again whenever the invoice changes
readonly preview = pdfResource(invoicePdf, () => this.invoice());
<iframe [src]="preview.latest()?.safeUrl"> // → eine Live-Vorschau, direkt im Browser
  • Gebaut, wie Angular baut

    provideJasy() in der App-Config, inject(JasyPdf) dort, wo Sie ein PDF brauchen. Ein Dokument läuft in einem Injection Context, inject() funktioniert darin also.

  • Eine Vorschau, die Ihren Signals folgt

    pdfResource() baut auf resource() von Angular auf: Es rendert bei jeder Änderung neu und behält so lange das letzte PDF, die Vorschau flackert also nicht.

  • ng add, und es ist eingerichtet

    Ein Befehl installiert und konfiguriert es. Getestet mit Angular 20, 21 und 22, zoneless und mit zone.js, mit und ohne SSR.

Roadmap · MIT · offen entwickelt

1.0 ist gebaut. Das kommt als Nächstes.

Offen entwickelt, unter MIT-Lizenz. Alles, was sich die 1.0 vorgenommen hat, ist fertig und ausgeliefert; das hier kommt danach - in dieser Reihenfolge, ohne versprochene Termine.

  • Jedes PDF lesen und bearbeiten

    Eine Datei öffnen, ändern, was auf der Seite steht, zusammenführen, teilen oder herauslösen. Formulare lesen und ausfüllen gibt es schon.

  • Digitale Signaturen

    Ein Dokument signieren, damit der Empfänger nachweisen kann, dass es danach niemand verändert hat - das Stück, das einer E-Rechnung noch fehlt.

  • Die letzten Prozent Layout

    Ein öffentlicher measure()-Helfer, eine Überschrift über alle Spalten und eine Border, die offen bleibt, wo eine Box über Seiten geteilt wird.

  • Vorlagen zum Loslegen

    Eine Rechnung, ein Bericht und ein Brief, die so funktionieren, wie sie sind, und sich zerlegen lassen, wenn Sie Ihre eigenen wollen.

  • Mehr E-Rechnungs-Profile

    Peppol und weitere Länderformate, zusätzlich zu den Profilen von Factur-X, ZUGFeRD und XRechnung, die schon unterstützt werden.

  • Unser eigenes Bidi

    Hebräisch und Arabisch stehen schon in der richtigen Reihenfolge. Die UAX-#9-Bibliothek dahinter wurde seit 2023 nicht mehr angefasst und bringt keine Typen mit, deshalb wird sie unsere eigene.

Auf GitHub folgenZum ganzen BoardIssues, Ideen und PRs willkommen.