Skip to content

Repository files navigation

iWork Viewer logo

iWork Viewer

Render Apple Pages, Numbers, and Keynote documents directly in the browser.

No server-side conversion. No document upload. No runtime CDN.

npm version CI status Apache-2.0 license Browser native Offline first

Quick start · Format coverage · File Viewer adapter · 简体中文


iwork-viewer is a standalone, browser-native renderer for .pages, .numbers, and .key files. It reads both iWork '09 XML/APXL packages and modern Snappy/IWA containers, then renders a static document scene without sending the source file to a conversion service.

The project deliberately separates the document engine from framework integration:

Package Purpose Runtime dependency
iwork-viewer Standalone parser, Worker, scene model, and renderer No File Viewer dependency
@file-viewer/renderer-iwork Thin adapter for File Viewer's renderer contract @file-viewer/core >=2.3.0 <3

Why this exists

Uploading a private iWork document just to preview it is a poor default for internal tools, archives, and offline deployments. iWork Viewer keeps parsing and rendering in the browser, exposes a small lifecycle API, and leaves the surrounding product UI to the host application. The preview surface contains document content—not engine labels, license cards, or format-specific marketing chrome.

Quick start

pnpm add iwork-viewer@0.0.2

Give the viewer a container with an explicit size, then pass a File, Blob, ArrayBuffer, or typed-array source:

<input id="file" type="file" accept=".pages,.numbers,.key" />
<div id="viewer" style="height: 720px"></div>
import { renderIworkDocument } from 'iwork-viewer'

const input = document.querySelector<HTMLInputElement>('#file')
const target = document.querySelector<HTMLDivElement>('#viewer')
if (!input || !target) throw new Error('Missing viewer elements')

const file = input.files?.[0]
if (!file) throw new Error('Select an iWork document first')

const viewer = await renderIworkDocument(file, target, 'pages', {
  embeddedPreview: 'fallback',
  workerTimeoutMs: 60_000,
})

viewer.fit('width')

// Release the Worker, object URLs, and rendered DOM when the view closes.
viewer.destroy()

The optional type hint accepts pages, numbers, or key. Container inspection still validates the real file signature and rejects mismatched or malformed inputs.

Format coverage

Format Generations Static preview coverage Intentional limits
Pages iWork '09 and 2013+ IWA Paginated and page-layout scenes, text, images, shapes, tables, charts, and styles No document editing or live layout reflow
Numbers iWork '09 and 2013+ IWA Multiple freeform sheets and tables, number formats, saved formula results, images, shapes, and charts Formulas are not recalculated
Keynote iWork '09 and 2013+ IWA Slides, master backgrounds, text, images, shapes, tables, charts, and presenter notes Animations, transitions, and video playback stay static

Encrypted iwpv2 documents are detected and reported, not decrypted. Embedded Quick Look images may be used as an explicit fallback, but they are never counted as high-fidelity rendering evidence.

File Viewer adapter

The adapter keeps File Viewer-specific registration, zoom, export, thumbnail, and Worker-path handling outside the standalone engine.

pnpm add @file-viewer/core@^2.3.0 @file-viewer/renderer-iwork@0.0.2
import { createFileViewer } from '@file-viewer/core'
import iworkRenderer from '@file-viewer/renderer-iwork'

const viewer = createFileViewer({
  container,
  options: {
    renderers: [iworkRenderer],
  },
})

Use the standalone package when iWork is the only document family you need. Use the adapter when your application already uses File Viewer for a broader format matrix.

Runtime design

  • Parsing runs in a module Worker by default and supports abort, timeout, and deterministic teardown.
  • ZIP expansion, compression ratio, object count, image pixels, and nesting depth are bounded.
  • Modern IWA parsing covers Snappy framing, protobuf archives, object graphs, media, and styles.
  • iWork '09 parsing covers Pages/Numbers XML, Keynote APXL, gzip payloads, media, and styles.
  • The renderer exposes zoom, fit, print pages, HTML export, thumbnail targeting, and cleanup through one instance.
  • All runtime code and assets are packaged locally; the viewer does not fetch a third-party CDN.

API at a glance

const viewer = await renderIworkDocument(source, target, type, options)

viewer.fit('contain')
viewer.zoomIn()
viewer.zoomOut()
viewer.setZoom(1.25)
viewer.getZoomState()
viewer.getPrintPages()
viewer.toHtml()
viewer.destroy()

Worker options include workerUrl, useWorker, workerTimeoutMs, embeddedPreview, and the documented parser resource limits. TypeScript declarations ship with both packages.

Verification

The repository uses real file-level fixtures with recorded provenance and SHA-256 values. Its regression suite covers iWork '09, 2015-era IWA, and current Pages, Numbers, and Keynote files.

pnpm install --frozen-lockfile
pnpm verify
pnpm verify:visual

pnpm verify builds both packages, runs parser tests, packs the release tarballs, installs the standalone tarball into a clean project, and renders native Pages, Numbers, and Keynote documents through the packaged Worker. Visual gates use fixed fonts and viewport settings with maximum pixel-difference ratios of 3% for Pages/Keynote and 5% for Numbers.

Fixture provenance is recorded in test/fixtures/manifest.json. Golden images live in test/goldens/.

Security

Treat every document as untrusted input. The parser runs with explicit resource limits and never executes macros, scripts, Keynote actions, or external programs. Please report security issues privately using the process in SECURITY.md.

Contributing

Read CONTRIBUTING.md before submitting a change. Every parser or rendering change should include a focused fixture, structural assertions, and—when layout changes—an updated visual baseline with documented provenance.

License

Licensed under Apache-2.0. Third-party notices are listed in packages/iwork-viewer/THIRD_PARTY_NOTICES.md.

Apple, Pages, Numbers, and Keynote are trademarks of Apple Inc. This project is independent and is not affiliated with or endorsed by Apple Inc.

About

Browser-native Apple iWork viewer for Pages, Numbers and Keynote with offline IWA and iWork '09 parsing.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages