KitePDF¶
One pure-Kotlin PDF engine for Kotlin Multiplatform. Read, create, edit and render PDFs from commonMain, with the exact same code on every target: Android, iOS, desktop, web and Kotlin/Native.
// commonMain. Nothing platform-specific. This runs everywhere Kotlin runs.
val doc = PdfDocument.open(bytes)
val text = doc.pages[0].extractText() // read
doc.edit().apply { // edit
redactRegion(doc.pages[0], Rectangle(72.0, 700.0, 320.0, 720.0))
}.saveRewritten()
val fresh = PdfBuilder() // create
.page { text(StandardFont.Helvetica, 24.0, x = 72.0, y = 720.0, "Hello, world!") }
.build()
- New here? Get started in 5 minutes
- Browse the guides below, or jump to the API reference
Why KitePDF¶
Most "Kotlin PDF libraries" are thin expect/actual wrappers around the platform's own engine: PdfRenderer on Android, PDFKit on iOS, PDF.js in the browser, PDFBox on the JVM. You inherit four engines, four sets of bugs, and four feature sets that never line up.
KitePDF is a single standalone engine, 100% common Kotlin, with zero expect/actual in the core. Write your PDF code once in commonMain and it behaves identically everywhere, because it is the same code. Parser, renderer, writer, editor, encryption and fonts are all included. When something is wrong, it is one bug in one place.
Drawing to a screen is the only thing that needs a platform, and KitePDF keeps that cleanly separate so the engine stays pure and portable.
Install¶
The engine is a single dependency. Add it to commonMain and you have everything except drawing to a screen:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.yuroyami:kitepdf:0.1.0")
}
}
}
Its only dependency is kotlin-stdlib, and it works on every Kotlin target. Rendering bindings are opt-in; see Show it on screen below.
Not using Kotlin Multiplatform?
The same artifact works in a plain Android or JVM project. Add io.github.yuroyami:kitepdf:0.1.0 to your normal dependencies { } block.
What you can do¶
Everything in this section is pure common code from the kitepdf engine.
Read¶
val doc = PdfDocument.open(bytes)
doc.pages[0].extractText() // text, or structured layout with positions
doc.pageCount // metadata, outlines, annotations, form fields...
// Encrypted? Pass the password.
val locked = PdfDocument.open(bytes, password = "secret".encodeToByteArray())
require(locked.isAuthenticated)
Text extraction (plain and structured), document metadata and XMP, outlines and bookmarks, annotations, form fields, encryption and permissions, page labels, optional-content layers, attachments and more. See Reading PDFs.
Create and edit¶
// Fill a form field and save (append-only)
doc.edit().apply {
setTextFieldValue(doc.formField("Name")!!, "Jane Doe")
}.saveIncremental()
// Truly redact a region (the underlying content is removed, not covered)
doc.edit().apply {
redactRegion(doc.pages[0], Rectangle(72.0, 700.0, 320.0, 720.0))
}.saveRewritten()
// Build a new PDF from scratch
PdfBuilder()
.page {
text(StandardFont.HelveticaBold, 24.0, x = 72.0, y = 720.0, "Invoice")
setFillRgb(0.9, 0.95, 1.0); rectangle(72.0, 600.0, 200.0, 80.0); fill()
}
.build()
Build from scratch with a content DSL, fill forms, stamp and watermark, and redact for real. See Creating PDFs and Editing & redaction.
Show it on screen¶
The engine is headless. Rendering is the one job that needs a platform, so it lives in separate, optional artifacts.
Compose Multiplatform: kitepdf-compose¶
A PDF page is just another composable, drawn straight into a Compose DrawScope.
val state = rememberPdfViewState(doc)
PdfView(
state = state,
layout = PdfLayout.Paged(Orientation.Horizontal), // or Continuous / SinglePage
zoomSpec = PdfZoomSpec(maxZoom = 6f), // pinch, double-tap, pan
renderSpec = PdfRenderSpec.Rasterized(), // or Vectorized()
overlay = { PdfNavigationControls(it, Modifier.align(Alignment.BottomCenter)) },
)
PdfPageIndicator(state)
PdfThumbnailStrip(state)
Headless: kitepdf-native-renderer and kitepdf-skia¶
For servers, CI and thumbnails, render a page straight to image bytes with no UI:
See Headless rendering.
Guides¶
| Getting started | Open your first PDF and display it, step by step. |
| Compose viewer | PdfView: layouts, zoom, render modes, navigation, export. |
| Reading PDFs | Text, metadata, outlines, annotations, forms, encryption. |
| Creating PDFs | Build from scratch with the content DSL. |
| Editing & redaction | Fill forms, stamp pages, redact, save. |
| Headless rendering | Page to PNG / Bitmap without a UI. |
| Recipes | Copy-paste patterns for common tasks. |
| Platform support | What runs where, and why. |
Status¶
KitePDF is pre-1.0 and actively developed. Reading, text extraction, metadata, outlines, annotations, forms, encrypted documents, the Compose viewer, headless rendering, editing, redaction and building from scratch all work today. Digital signatures, the JBIG2 and JPEG 2000 codecs, and advanced colour management are on the way.
If a PDF renders incorrectly, open an issue with the file attached. Every fix lands as a regression test against a MuPDF pixel-diff harness.