Browser Kitty uses the phrase “fully local processing” for tools that handle images, video, databases, AI, PowerPoint files, and other user data. But simply running in a browser—or not operating our own backend—does not prove that selected files and inputs never leave the device. This article explains the checks we actually use in Browser Kitty.

In this article, “fully local processing” means that user-selected files and inputs are not sent to an external server for the app’s processing, and the main processing path completes on the device. It does not mean “there is never any network traffic at all,” including downloading the hosted HTML or an explicit share action initiated by the user.

Five views of a fully local processing claim

Data path

Where the processing data flows

We check whether files, text input, camera/microphone data, and similar material stay in the browser processing path—JavaScript, workers, Wasm, and web APIs—instead of being sent to a server for computation.

Runtime

What is fetched while the app runs

We check for runtime downloads of CDN scripts, Wasm, AI models, fonts, and other assets. Dependencies fetched during the build and embedded into the HTML are treated differently from runtime network dependencies.

Guardrail

Use CSP to narrow network paths

For apps that need no external connections, policies such as connect-src 'none' restrict fetch/XHR-style network paths. Because other resource types have separate CSP directives, we review the whole policy together with the implementation.

Behavior

Verify real workflows too

We exercise representative flows—file selection, processing, export, and error paths—and check for unexpected requests. The intent visible in source code is verified against real browser behavior.

Boundary

Where save and share actions hand data off

We identify explicit handoffs such as file save, clipboard, OS share, print, and NFC. These user-triggered outputs are treated separately from hidden uploads used to perform the processing.

Downloading the app is different from sending processing data

A tool hosted on GitHub Pages first needs to download its HTML. The distributed single-HTML build can still embed the runtime it needs and avoid sending the user’s file to a server after the page has loaded. We distinguish network traffic used to obtain the app from network traffic that sends the user’s processing data.

Likewise, “fully local processing” is not identical to “every feature works offline in every environment.” APIs such as Web Share, Web NFC, and screen capture can require a secure HTTPS context or specific browser/OS support. Requiring HTTPS does not by itself mean that the actual data processing runs on a server.

1. Trace the processing path after input selection

The first check is where the data goes after a user chooses a file or enters text. The File API lets a web application read a File selected by the user. Selecting the file is not itself an upload; sending it to a server requires a later network or submission step such as fetch, XMLHttpRequest, or a form submission.

In Browser Kitty we trace whether the input moves through on-device components such as JavaScript, Web Workers, WebAssembly, Canvas, and WebCodecs. We also look for code that passes processing Blobs, ArrayBuffers, or text into network APIs. The first check is the end-to-end data path, not merely the absence of an obvious backend.

2. Remove runtime external dependencies

A tool can avoid uploading the user file and still depend on runtime networking—for example by loading JavaScript from a CDN or fetching Wasm or an AI model from an external URL after startup. For Browser Kitty's standalone builds, we therefore embed required JavaScript, Wasm, worker code, models, icons, and similar runtime assets whenever practical.

The important distinction is that “uses a third-party library” is not the same as “contacts a third party at runtime.” Libraries such as FFmpeg, DuckDB, or a PPTX renderer can be fetched and pinned during the build, then embedded into the distributed HTML so the user's session does not need to retrieve them. Conversely, a file that looks self-contained but calls a CDN or API after startup is not truly self-contained at runtime.

3. Use CSP to make the browser enforce the intended boundary

For Browser Kitty apps that do not need external connections, generated HTML commonly uses connect-src 'none'. The connect-src directive restricts script-driven connection mechanisms including fetch, XMLHttpRequest, WebSocket, EventSource, and sendBeacon, providing a browser-enforced guardrail if an unintended network call appears in the code.

But connect-src 'none' is not treated as proof by itself. CSP uses separate directives for resource types such as scripts, images, and fonts, while form submissions are controlled separately as well. We review the actual policy together with the HTML to look for other external resource paths. CSP is an additional enforcement layer, not a substitute for understanding the implementation.

4. Exercise the app and observe real network behavior

Static code review alone can miss lazy loading, error-only paths, or network behavior hidden inside a library. We therefore load representative files, exercise parsing, processing, preview, export, and other main flows, and watch for unexpected external requests in the browser’s network log.

In practice, after the initial page load finishes, we clear the Network log and then run the main workflow from file selection through export. If new external requests appear during that sequence, we investigate whether processing data or runtime dependencies are leaving the local path.

Wasm modules and AI models are especially easy to miss because some apps fetch them only when the first real operation begins. A worker can also trigger a request if it is created from an external URL. We therefore test after exercising the main features, not just after the first screen renders. For the standalone HTML build, we also try the main processing path offline or via file:// where supported; that is a separate check for runtime dependencies.

5. Separate explicit handoff actions from hidden uploads

A fully local tool can still provide explicit ways for the user to move data elsewhere: saving a file, copying to the clipboard, printing, opening the operating system share sheet, or writing to an NFC tag. These are different from an application silently uploading processing data to a server.

The Web Share API, for example, hands data to the operating system's native sharing mechanism after a user action, and the user chooses the target. If the user selects email or a messaging app, the data may of course leave the device from that point onward. Browser Kitty distinguishes “the app does not transmit data for processing” from “the user explicitly hands data to another destination,” and documents the latter when a feature supports it.

We make the same distinction for localStorage and Blob URLs. localStorage belongs to the browser storage area for an origin, while Blob URLs let in-memory Blob data be referenced as a URL. They are not server storage, though persistence and file:// behavior can vary, so tools that need durable data also provide explicit export paths where appropriate.

Three real examples: different data, the same verification questions

Browser Kitty applies the same questions to very different workloads—from small text inputs to million-row generation jobs and tools combining PPTX, audio, video, and Wasm: where does processing happen, what is fetched at runtime, and where can the result go?

Examples from Browser Kitty
ToolHandled on deviceSave/share and other explicit output actions
Wi-Fi ShareSSID/password, QR generation, saved Wi-Fi entriesOS share, clipboard, print, NFC tag write
Test Data GeneratorSeed/configuration, Web Worker generation, CSV / TSV / JSON / JSONL outputGenerated files and settings files saved by the user
Presentation Video MakerPPTX, speaker notes, recordings, local audio, BGM, project data, MP4 creation.pvm projects, subtitles, scripts, and MP4 files explicitly saved by the user

No single badge proves local processing

There is no single badge that proves a tool is fully local. A single HTML file can call an external API. An app with no first-party backend can still send data to a third-party service. Even with connect-src 'none', other CSP-controlled resource paths and explicit user sharing need to be understood separately.

The reverse is also true: an initial request to obtain a hosted app, a Secure Context requirement, or the use of a third-party library does not automatically mean the user's processing data is handled in the cloud. Browser Kitty uses “fully local processing” as the result of reviewing runtime data paths and behavior, not as a synonym for a particular distribution format.

The five checks Browser Kitty uses

Before describing a new tool as fully local, we run through at least these checks. The APIs and storage methods differ by tool, but the questions are consistent.

  1. Data pathConfirm that user files and inputs flow into browser-side processing rather than being passed to network APIs for computation.
  2. Runtime dependenciesCheck that JavaScript, Wasm, workers, AI models, fonts, and similar dependencies are not pulled from external URLs at runtime. Pin and embed required assets during the build when practical.
  3. CSPFor apps that need no external connections, use policies such as connect-src 'none' and review the rest of the CSP/HTML for script, image, font, form, and other resource paths.
  4. Real workflowLoad representative files and exercise main features, exports, and error paths while checking for unexpected requests or lazy runtime downloads.
  5. Save/share boundaryTreat file save, clipboard, OS share, print, NFC, and similar user-triggered handoffs separately from hidden uploads, and explain the boundary where needed.
Try it in Browser Kitty

Presentation Video Maker

Turn PowerPoint (PPTX) slides into narrated MP4 videos locally using speaker notes, recordings, or local audio files.

Open toolView tool details

Tips and limitations

  • “Fully local processing” is not a blanket security guarantee. Browser/device security, the destination chosen in an OS share sheet, and how exported files are handled are separate questions.
  • Site-level analytics and whether an app transmits the user's processing data are separate concerns. Browser Kitty keeps analytics and ad code out of the actual tool app pages and designs them not to transmit the user's processing data.
  • Local-processing wording follows the implementation of each tool. When a tool has explicit handoff features such as Web Share, NFC, camera, or microphone access, we describe that boundary instead of making an overly broad “no communication of any kind” claim.

Frequently asked questions

Does connect-src 'none' prove that an app is fully local?

No. It strongly restricts common script-driven connections such as fetch, XHR, WebSocket, and sendBeacon, but CSP has separate directives for scripts, images, fonts, and other resource types. We also inspect data paths, external resources, form submission behavior, and real network activity.

How can a hosted GitHub Pages app be local if opening it uses the network?

Because downloading the app itself is different from sending the user's processing data to a server. Browser Kitty uses “fully local processing” to mean the latter does not happen and the main work runs on the device. For standalone builds, we also verify that supported workflows do not require runtime external dependencies.

Does using a third-party library make an app non-local?

Not necessarily. A dependency can be fetched during the build, embedded into the distributed HTML, and run entirely on the device without runtime retrieval or user-data transmission. The key question is the runtime data and network path, not simply who authored the library.

Can a fully local tool still have a Share button?

Yes, if the processing itself remains on device. Once sharing is explicitly invoked, the data is handed to the operating system's share mechanism and then follows the behavior of the destination the user chooses. We distinguish that user-triggered handoff from hidden transmission used to perform the processing.

Can users verify local processing themselves?

To a degree. Browser Kitty tool repositories are generally public, so the implementation and build configuration can be inspected. Running representative workflows while watching the browser Network panel also shows which requests occur at runtime. A single inspection, however, cannot guarantee the behavior of every future version.

References

This article combines Browser Kitty's actual implementation and verification practices with browser specifications and official documentation. The references below cover the File API, CSP, Web Share, and the public repositories used as implementation examples.