
Security News
White House Authorizes Private Companies to Conduct Offensive Cyber Operations
A new federal program will let vetted U.S. cybersecurity firms help investigate and disrupt foreign cybercrime groups under government direction.
@file-viewer/ppt
Advanced tools
Professional native WebAssembly canvas viewer for PowerPoint 97-2003 (.ppt) files.
Professional, browser-native preview for PowerPoint 97–2003 (
.ppt).
@file-viewer/ppt is Flyfish's independently developed preview engine for the
PowerPoint 97–2003 binary (.ppt) format. It reconstructs slides directly in a
modern browser without Microsoft Office, LibreOffice, browser plug-ins, or a
server-side document conversion service.
The product is designed for document platforms, archives, knowledge systems, intranets, SaaS applications, and web products that still need dependable access to traditional PowerPoint files. Its viewport-first runtime is equally suitable for ordinary presentations and very large decks.
.ppt understanding — Reads the classic PowerPoint compound-file,
persist-record, text, drawing, and picture structures directly.localStorage.This package previews PowerPoint 97–2003 binary .ppt files. For XML-based
.pptx files, use a dedicated PPTX viewer.
npm install @file-viewer/ppt
import { createPptViewer } from '@file-viewer/ppt';
const viewer = await createPptViewer({
worker: 'auto',
cache: {
enabled: true,
maxBytes: 256 * 1024 * 1024,
maxEntries: 200,
maxEntryBytes: 32 * 1024 * 1024
}
});
const response = await fetch('/documents/presentation.ppt');
const mounted = await viewer.mount(
'#ppt-viewer',
await response.arrayBuffer(),
{
scale: 1,
pixelRatio: window.devicePixelRatio,
virtualize: true,
rootMargin: '150% 0px',
releaseDelayMs: 1200
}
);
console.log(viewer.mode); // "worker" or "direct"
console.log(await mounted.cacheStats());
// When this mounted preview is no longer needed:
await mounted.close();
await viewer.close();
worker: 'auto' is the default. It selects the module Worker path when Worker,
OffscreenCanvas, and URL-based assets are available, and otherwise uses the
compatible direct renderer. Set worker: true when worker rendering is a hard
deployment requirement, or worker: false for explicit direct mode.
virtualize: true is also the default. The viewer creates stable page shells,
renders pages near the viewport, and releases hidden raster backing stores.
In worker mode, when IndexedDB is available, revisiting a released page can
restore its final watermarked PNG before a native rerender is needed. Cache
failure or browser quota eviction never prevents the document from rendering;
direct mode simply rerenders a released page.
For very large files, set transferInputOwnership: true when constructing the
viewer to transfer a full input ArrayBuffer without an additional main-thread
copy. The supplied buffer is detached, so enable this only when the application
will not read it again.
import { createPptViewer } from '@file-viewer/ppt';
const viewer = await createPptViewer();
const response = await fetch('/documents/presentation.ppt');
const pptDocument = await viewer.open(await response.arrayBuffer());
const canvas = document.querySelector('canvas');
const result = await pptDocument.renderSlide(0, canvas, { scale: 1.25 });
console.log(pptDocument.slideCount, pptDocument.width, pptDocument.height);
console.log(result.source); // "native" or "indexeddb" in worker mode
await pptDocument.releaseSlide(0);
console.log(await pptDocument.cacheStats());
await pptDocument.close();
await viewer.close();
The API is asynchronous in both worker and direct modes, so application code does not need separate lifecycle branches. Close a mounted viewer, document, or runtime when it is no longer needed so associated native and graphics resources can be released promptly.
| API | Purpose |
|---|---|
createPptViewer(options) / loadPptViewer(options) | Loads and verifies the runtime assets; returns worker or direct mode |
viewer.mount(target, input, options) | Mounts a complete, virtualized Canvas presentation |
viewer.open(input) | Asynchronously opens a .ppt and returns an opaque document handle |
document.renderSlide(index, canvas, options) | Asynchronously renders or restores one final slide frame |
document.releaseSlide(index) | Releases a slide's active raster resources |
document.cacheStats() / mounted.cacheStats() / viewer.cacheStats() | Returns current bounded-cache counters |
document.close() / mounted.close() / viewer.close() | Releases resources at the corresponding lifecycle boundary |
getPptPackageManifest() | Returns package, asset, edition, and capability metadata |
All public APIs include TypeScript declarations. Parsed document models, records, HTML, SVG, drawing command streams, and unwatermarked frames are not part of the public API.
The relevant defaults are:
| Option | Default | Meaning |
|---|---|---|
virtualize | true | Render the viewport and overscan window instead of retaining every page |
rootMargin | 150% 0px | IntersectionObserver overscan around the scroll viewport |
releaseDelayMs | 1200 | Grace period before a hidden page is persisted and released |
cache.enabled | true | Use IndexedDB when available |
cache.maxBytes | 256 MiB | Total final-frame cache budget |
cache.maxEntries | 200 | Maximum cached slide frames |
cache.maxEntryBytes | 32 MiB | Maximum encoded PNG size for one frame |
The IndexedDB cache operates in worker mode and is a performance layer, not
document storage: it contains only final
watermarked PNG frames, does not retain source .ppt bytes, and degrades safely
when private browsing, storage policy, or quota makes IndexedDB unavailable.
Synchronous string-based localStorage is intentionally not used for frame
data.
Static deployments must preserve the following package assets:
index.mjs
worker.mjs
frame-cache.mjs
ppt-native.wasm
ppt-font-cjk.otf
manifest.json
The default locations are resolved relative to index.mjs. If a bundler or CDN
moves assets, configure them explicitly:
const viewer = await createPptViewer({
workerUrl: new URL('/vendor/file-viewer/ppt/0.3.0/worker.mjs', location.origin),
wasmUrl: new URL('/vendor/file-viewer/ppt/0.3.0/ppt-native.wasm', location.origin),
fontUrl: new URL('/vendor/file-viewer/ppt/0.3.0/ppt-font-cjk.otf', location.origin)
});
For the widest browser compatibility, serve worker.mjs and
frame-cache.mjs from the application origin. A separate asset origin for the
WASM or font must provide CORS permission and be allowed by connect-src.
ppt-font-cjk.otf is a renderer resource, not a CSS @font-face dependency.
It is fetched and verified independently from the smaller WASM engine, so a
browser or CDN can reuse the font response across presentations and application
visits.
Use these response types:
| Extension | Content-Type |
|---|---|
.mjs | text/javascript; charset=utf-8 |
.wasm | application/wasm |
.otf | font/otf |
.ppt | application/vnd.ms-powerpoint |
Place assets under a versioned or content-addressed path before serving them with a long immutable cache lifetime:
Cache-Control: public, max-age=31536000, immutable
Do not apply immutable to an unversioned path that may later serve different
bytes. The runtime verifies the declared size and SHA-256 of both
ppt-native.wasm and ppt-font-cjk.otf before use.
A same-origin baseline CSP is:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'wasm-unsafe-eval';
worker-src 'self';
connect-src 'self';
font-src 'self';
img-src 'self' blob:;
style-src 'self' 'unsafe-inline';
Extend connect-src for approved WASM/font CDNs. Some browsers require
'wasm-unsafe-eval' to compile WebAssembly. The default worker architecture
does not require SharedArrayBuffer, cross-origin isolation, or a blob Worker.
fetch, and
Canvas 2D is required.worker: 'auto' falls back to direct mode when these capabilities
are unavailable.Traditional PowerPoint files may contain macros, ActiveX controls, OLE objects, linked media, or host-specific behaviors that browsers cannot execute. These features are treated as non-executable preview content. Font substitution may be used when a document font is not available to the viewer.
| Edition | Permitted use | Watermark | Origin |
|---|---|---|---|
| Public npm edition | Individual personal, non-commercial, non-organizational use | Mandatory Flyfish Viewer on every slide | Any normal HTTP/HTTPS origin |
| Commercial edition | Licensed company, organization, customer project, intranet, SaaS, OEM, or production use | Watermark-free build available according to the purchased agreement | According to the commercial agreement |
Commercial use requires a purchased license. Use by or for a company, organization, government body, school, nonprofit, team, employer, customer, or client—including internal evaluation—is commercial use.
The public npm edition is proprietary software and is not licensed under Apache-2.0. Removing, hiding, covering, replacing, or bypassing the required watermark is prohibited. See LICENSE for the binding terms.
Purchase a commercial license from the Flyfish Shop.
@file-viewer/ppt 是 Flyfish 纯自研的 PowerPoint 97–2003 二进制 .ppt
专业预览引擎。它直接理解传统 PPT 文件结构,并在现代浏览器中重建幻灯片,无需
安装 Microsoft Office、LibreOffice、浏览器插件,也不依赖服务端格式转换。
产品适用于文件预览平台、档案与知识管理系统、企业内网、SaaS 产品,以及仍需 稳定支持传统 PowerPoint 文档的 Web 应用。面向视口的运行架构既适合普通文档, 也适合包含大量页面的演示文稿。
.ppt:直接读取复合文件、持久化记录、文字、绘图和图片结构。localStorage。本包专门预览 PowerPoint 97–2003 二进制 .ppt 文件。XML 格式的 .pptx
应使用专用 PPTX 预览器。
npm install @file-viewer/ppt
import { createPptViewer } from '@file-viewer/ppt';
const viewer = await createPptViewer({
worker: 'auto',
cache: {
enabled: true,
maxBytes: 256 * 1024 * 1024,
maxEntries: 200,
maxEntryBytes: 32 * 1024 * 1024
}
});
const response = await fetch('/documents/presentation.ppt');
const mounted = await viewer.mount(
'#ppt-viewer',
await response.arrayBuffer(),
{
scale: 1,
pixelRatio: window.devicePixelRatio,
virtualize: true,
rootMargin: '150% 0px',
releaseDelayMs: 1200
}
);
console.log(viewer.mode); // "worker" 或 "direct"
console.log(await mounted.cacheStats());
// 预览不再使用时:
await mounted.close();
await viewer.close();
worker: 'auto' 和 virtualize: true 均为默认值。支持 Module Worker 与
OffscreenCanvas 的浏览器会把解析与渲染放到 Worker;否则自动使用兼容的直接
渲染模式。完整预览会创建稳定的页面容器,仅渲染视口附近内容,并在页面离开
预加载区后释放其光栅资源。
IndexedDB 可用时,再次浏览已释放页面可优先恢复最终水印 PNG。浏览器禁用 IndexedDB、隐私模式限制存储或缓存被配额机制清理时,不影响原生重新渲染。该 IndexedDB 缓存用于 Worker 模式;直接模式会在页面再次进入视口时重新渲染。
超大文件可在创建 viewer 时设置 transferInputOwnership: true,把完整
ArrayBuffer 的所有权直接转移给 Worker,避免主线程额外复制。该缓冲区随后会
被 detach,仅应在业务不再读取原缓冲区时启用。
const pptDocument = await viewer.open(await response.arrayBuffer());
const canvas = document.querySelector('canvas');
const result = await pptDocument.renderSlide(0, canvas, { scale: 1.25 });
console.log(result.source); // Worker 模式为 "native" 或 "indexeddb"
await pptDocument.releaseSlide(0);
console.log(await pptDocument.cacheStats());
await pptDocument.close();
await viewer.close();
Worker 与直接模式采用相同的异步 API。文档、完整挂载预览或运行时不再使用时,
请 await close(),以便及时释放原生内存、Worker 和图形资源。
| API | 用途 |
|---|---|
createPptViewer(options) / loadPptViewer(options) | 加载并校验运行资源,返回 Worker 或直接模式 |
viewer.mount(target, input, options) | 挂载完整、支持虚拟滚动的 Canvas 预览 |
viewer.open(input) | 异步打开 .ppt 并返回不透明文档句柄 |
document.renderSlide(index, canvas, options) | 异步渲染或恢复指定页最终画面 |
document.releaseSlide(index) | 释放指定页当前光栅资源 |
cacheStats() | 在文档、挂载对象或运行时级别读取缓存统计 |
close() | 在对应生命周期边界释放资源 |
getPptPackageManifest() | 返回包、资源、版本和能力信息 |
所有公开 API 均提供 TypeScript 类型。解析后的文档模型、记录、HTML、SVG、 绘图指令流和无水印画面均不属于公开 API。
默认仅保留视口及 150% 0px 预加载区;页面离开该区域 1200ms 后会被缓存并
释放。IndexedDB LRU 默认总容量上限为 256MiB、最多 200 页、单页编码 PNG
最多 32MiB,均可通过 cache 选项调整。
IndexedDB 缓存用于 Worker 模式,并且只是性能加速层;它只保存最终水印 PNG,
不保存源 .ppt 文件或中间文档
数据;不可用或被浏览器清理时会安全退化为重新渲染。同步、字符串化且容量有限的
localStorage 不用于页面缓存。
静态部署需完整保留以下资源:
index.mjs
worker.mjs
frame-cache.mjs
ppt-native.wasm
ppt-font-cjk.otf
manifest.json
默认地址相对 index.mjs 解析。使用打包工具或 CDN 改变目录时,请通过
workerUrl、wasmUrl、fontUrl 指定实际地址。为获得最广泛的浏览器兼容性,
建议 worker.mjs 与 frame-cache.mjs 保持同源;WASM 或字体使用独立 CDN
时,需要正确配置 CORS 和 connect-src。
推荐 MIME:.mjs 使用 text/javascript; charset=utf-8,.wasm 使用
application/wasm,.otf 使用 font/otf,.ppt 使用
application/vnd.ms-powerpoint。
将资源发布在版本化或内容寻址目录(如 /vendor/file-viewer/ppt/0.3.0/)后,
可配置:
Cache-Control: public, max-age=31536000, immutable
不要为可能替换内容的非版本化地址设置 immutable。ppt-font-cjk.otf 是渲染器
资源而不是 CSS @font-face 字体;它会独立加载和校验,因此可在不同 PPT 文档及
多次访问之间复用浏览器/CDN 缓存。
同源部署的基础 CSP 需要允许包模块、Module Worker、资源请求和 WebAssembly;
部分浏览器要求在 script-src 中加入 'wasm-unsafe-eval'。若字体或 WASM 使用
独立 CDN,还需将该域名加入 connect-src。默认 Worker 架构不要求
SharedArrayBuffer、跨域隔离或 Blob Worker。
fetch 和 Canvas 2D。worker: 'auto' 会在不支持时回退到直接模式。传统 PPT 可能包含宏、ActiveX、OLE、链接媒体或依赖桌面宿主的行为,浏览器无法 执行这些能力;预览器会把它们作为不可执行内容处理。原始字体不可用时可能使用 兼容字体替代。
| 版本 | 允许用途 | 水印 | Origin |
|---|---|---|---|
| 公网 npm 版 | 自然人个人、非商业、非组织用途 | 每页强制显示 Flyfish Viewer | 任意正常 HTTP/HTTPS origin |
| 商业版 | 已授权的公司、组织、客户项目、内网、SaaS、OEM 或生产用途 | 按商业协议提供无公网水印构建 | 按商业协议执行 |
任何商业用途均需购买授权。 公司、组织、政府、学校、非营利机构、团队、 雇主、客户或委托项目的使用,包括内部评估,均属于商业用途。
公网 npm 版是专有软件,不适用 Apache-2.0。禁止删除、隐藏、遮挡、替换或 绕过强制水印。具有法律约束力的完整条款见 LICENSE。
商业授权请前往 Flyfish 商店购买。
FAQs
Professional native WebAssembly canvas viewer for PowerPoint 97-2003 (.ppt) files.
The npm package @file-viewer/ppt receives a total of 2,006 weekly downloads. As such, @file-viewer/ppt popularity was classified as popular.
We found that @file-viewer/ppt demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
A new federal program will let vetted U.S. cybersecurity firms help investigate and disrupt foreign cybercrime groups under government direction.

Research
/Security News
The campaign amassed more than 75,000 installs by targeting Russian-speaking users seeking access to blocked services.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.