CLI tool
flyfish-dev/file-viewer avatar
flyfish-dev/file-viewer

File Viewer: Browser-Native Preview for Internal Documents

Browser-native Office / PDF / CAD / archive viewer for internal web apps, with Vue, React, Svelte, jQuery, Web Components, and no server-side conversion.

2,322 stars241 forksTypeScriptApache-2.0

At a glance

What is it?
Flyfish's File Viewer renders Office, PDF, CAD and archive files in the browser without a conversion backend, and ships framework-specific packages for React, Vue, Svelte, jQuery and Web Components. The trade-off is bundle weight and a format matrix you must check before committing.
Who is it for?
Adopt File Viewer if your preview path must stay inside your network and your team already ships a React, Vue, Svelte or vanilla front end. Do not adopt it if your users need pixel-perfect fidelity on every legacy Office artefact, or if you cannot absorb a WASM and Worker payload in the initial route.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem File Viewer Targets

The README opens with a blunt claim: uploading a private DOCX or DWG just to preview it is awful. That sentence names the audience. This is a library for internal web applications, admin panels and intranet tools where a user needs to look at a document that never should have left the company network. The alternative it argues against is a SaaS converter that receives the file, or a self-hosted preview backend that runs LibreOffice or a CAD engine per format. Both options move the file, or a rendering of it, through a server. File Viewer keeps the parse and the paint inside the browser tab. The project description lists Office, PDF, CAD and archives, and the topics include docx, pptx, xlsx, dwg, dxf and wasm. The scope is deliberately wider than a PDF embed. If your requirement is a single PDF iframe, this is more machinery than you need.

How the Browser Does the Work

The README states that files are parsed and rendered in the browser whenever the format allows it, and that Workers, WASM, fonts and vendor assets can stay on your network. That is the whole architecture in two clauses. There is no conversion service in the request path. Heavy capabilities are loaded per format rather than bundled into the entry point, which the README calls lazy heavy pipelines and names PDF, CAD, Typst and archives as examples. The consequence is a data flow that starts at a URL you control and ends in a DOM node, with the parsing step running as WebAssembly or Worker code fetched on demand. The README does not publish a per-format memory budget, so the cost of opening a large DWG is something you have to measure on your own hardware. The framework packages are wrappers over the same core: the React, Vue, Svelte and jQuery packages expose a component, while the vanilla path exposes a mountViewer function that takes a DOM element and an options object. The README describes one component API covering source, lifecycle, toolbar, search, zoom, print and export across formats, which is the actual reason to pick this over stitching together four separate viewers.

Installing It and Mounting a Viewer

The README gives two entry paths. For a new project, npm create file-viewer@latest my-viewer scaffolds a runnable app. For an existing package.json, npx file-viewer-cli@latest add . integrates into the current tree. The CLI detects the framework and package manager, shows the packages and asset work before writing anything, and keeps heavy formats explicit, according to the README. Manual installation is still supported. The package naming follows a light and full split per framework. Vanilla and Web Component users install @file-viewer/web or @file-viewer/web-full. React 18 and 19 use @file-viewer/react or @file-viewer/react-full. Vue 3 uses @file-viewer/vue3 or @file-viewer/vue3-full. There are separate packages for React 16.8 and 17 (react-legacy) and for Vue 2.7 and 2.6. The mounting call is small. The Web Component example imports mountViewer from @file-viewer/web-full and passes a DOM element plus an options object with url and filename keys. The React example renders a FileViewer component with a url prop. The Vue example does the same inside a template. Nothing in the README suggests a required server endpoint, a licence key call, or a registration step at runtime.

The Light and Full Package Split

The package table is the part of the README that deserves the most attention, because it encodes a decision you cannot defer. Every framework has a light package and a full package. The README also mentions a Standard profile and the option to choose exact renderers, or to retain what it calls the established Full compatibility package for an existing application. Read together, these statements imply that the light packages cover a narrower set of formats and that the full packages carry the broad compatibility set. The README does not, in the supplied text, enumerate which extensions fall into which package. That gap matters more than any other detail here. A team that installs @file-viewer/react and later discovers that DWG or Typst support lives elsewhere will be reworking their dependency tree after the first release. The README points at a format matrix at doc.file-viewer.app/guide/formats for exactly this reason. Treat that page as the specification, not the marketing copy.

Where File Viewer Is the Wrong Choice

Browser-native rendering is a fidelity trade, and the README does not pretend otherwise, though it also does not quantify the loss. The phrase whenever the format allows it is doing real work. A DOCX rendered by a browser parser will not match Word's layout engine on every document. Complex pagination, embedded fonts that the viewer cannot substitute, tracked changes, and unusual table structures are the usual places where a reimplementation diverges. CAD is a sharper case: the README lists DWG and DXF among the topics and the demo GIF shows a DWG preview, but a browser viewer is a geometry display, not a drafting tool. If your users need to measure, edit or trust dimension annotations, a viewer that only renders is not the deliverable. There is a second boundary. The README's own pitch assumes the file is reachable by URL from the browser. If your documents sit behind a token exchange that only a server can perform, or if the browser must never receive the raw bytes, the no-server-conversion model is the opposite of what you need. In that case a server-side render to an image or a PDF is the correct architecture, and File Viewer is not.

How This Differs From Server-Side Conversion

The obvious alternative is a conversion service: upload or stream the file to a backend, run LibreOffice or a CAD engine, and return a PDF or a set of images that the front end displays in an iframe or a canvas. That approach wins on fidelity, because it uses the same rendering engines that produced the file, and it wins on client weight, because the browser downloads a flat document instead of a parser and a WASM module. It loses on deployment surface, because you now operate a conversion service, a queue, a cache and a cleanup job, and you inherit the security posture of every engine you run. File Viewer inverts all of that. The client gets heavier and the server gets simpler, potentially to the point of being a static file host. The README's private-deployment claim follows from that inversion: runtime code, renderers, Workers, WASM and vendor assets can be hosted inside your network, so the viewer works in an air-gapped or restricted environment. If your constraint is data residency rather than fidelity, the browser-native model is the stronger fit. If your constraint is exact output, the server model still wins.

Licence, Releases and Upgrade Surface

The repository is Apache-2.0, which permits commercial and closed-source use and includes an explicit patent grant, but it also carries notice and attribution obligations. That is a summary of the licence text, not legal advice; have counsel review it if your distribution model is unusual. The README adds a supply-chain detail worth acting on. The current npm scope is @file-viewer/*, and the README states that historical @flyfish-group/* package names remain compatibility aliases. It also states that doc.flyfish.dev is a legacy documentation domain that should resolve to doc.file-viewer.app. Two naming generations in the wild means a dependency audit can surface the old scope and look legitimate. The README tells you to verify a release through the flyfish-dev/file-viewer repository, its public release page, and the published npm package metadata. On maintenance cost, the release history shows v3.0.1, v3.0.2 and v3.0.3 within about a week in September 2026, which is a fast patch cadence on a major line. Frequent patch releases are good for fixes and bad for lockfile churn, so pin exact versions and read the release notes before bumping. The README also notes a public CI workflow, which gives you a signal to check before upgrading.

Editorial conclusion

Adopt File Viewer if your preview path must stay inside your network and your team already ships a React, Vue, Svelte or vanilla front end. Do not adopt it if your users need pixel-perfect fidelity on every legacy Office artefact, or if you cannot absorb a WASM and Worker payload in the initial route. Before writing any integration code, open the format matrix at doc.file-viewer.app/guide/formats and confirm every extension you plan to serve is listed for the package you intend to install.

Official sources

  1. flyfish-dev/file-viewer on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes