I stopped saying “PDFSwift is private” as a single sentence. It is two pipelines that share a website. One pipeline never uploads the file. The other exists to upload content, because a model cannot read a page that stayed on your laptop unless you send it something. Mixing those sentences is how someone pastes a draft settlement into a chat box and thinks it behaved like Merge.
What stays in the tab
Merge, split, rotate, and organize run on pdf-lib. They copy or reorder page objects and save a download. JPG and PNG export, compress, lock, and unlock run on PDF.js canvases. Compress, lock, and unlock then call jsPDF. Sign embeds an image with pdf-lib. JPG-to-PDF embeds images with pdf-lib. None of those scripts post your file to a PDFSwift storage endpoint. They do fetch JavaScript from CDNs — unpkg for pdf-lib, cdnjs for PDF.js and jsPDF — so the browser talks to those hosts to get code. The document bytes are not that request.
A crashed tab loses the in-memory file. It does not mean a server kept a copy. There was no copy. If you needed a record, the download is the record. I download before I experiment with a second destructive pass.
| Action | Document bytes | What I will put in it |
|---|---|---|
| Merge, split, rotate, organize, sign, JPG to PDF | Browser memory, then your download | Client files, with ordinary device hygiene |
| Compress, lock, unlock, PDF to JPG/PNG | Same, but the download is a raster copy | Same, knowing text becomes pixels on some of these |
| Chat, summarize, rewrite, translate, CV tools | The text you submit goes to the Worker and a model | Text I am willing to have processed off-device |
| OCR | The page image goes to a vision model | Scans I am willing to have processed off-device |
The AI path, without the soft language
The Worker picks a model per task. Summaries and chat try a DeepSeek endpoint first, then other fallbacks. OCR tries a vision model and sends the image. Translation sends text. I am not going to inventory every model string as if it were a promise. Fallbacks exist because providers fail. What is stable is the direction of travel: your prompt leaves the browser, a completion comes back, and you should assume the processor saw the prompt.
I do not put the following in that box: passwords, full account numbers, medical detail I would not email, unreleased financials, or a contract that says it must not be submitted to a model. I will put a public manual, a draft blog post, or a chapter I have already decided is fine to process. The page does not have a “confidential mode” that changes this. There is no toggle I am hiding from you.
Local tools can run offline once the libraries are cached, until a hard refresh needs the CDN again. AI tools cannot. If the network is down, the model is down. That is a useful test. If a feature still works on a laptop in airplane mode, it is the local pipeline. If it errors, it needed the Worker.
Ads, cookies, and the other request your browser makes
Pages load AdSense. That is a third-party request about the visit, not about the PDF’s contents. It still identifies a browser to an ad network. If that bothers you, the cookie policy is the place that says so, and a browser that blocks third-party cookies will change what those scripts can do. Blocking them does not change the AI pipeline. The AI pipeline is a first-party call you trigger by pressing the button.
Support email is a third path. If you attach the broken PDF to a message to support@pdfswift.cc, you have uploaded it to mail, on purpose. I ask people not to send passwords or confidential contents in bug reports. A screenshot of the status line and the file size is usually enough. “It failed on a 40 MB encrypted scan in Firefox” is a better bug than the scan itself.
How I decide in under a minute
Does the next step need a model? If no, I stay on the local tool and I keep the master. If yes, I split to the smallest excerpt that answers the question, I read it once for secrets, and I submit that. I do not submit the data room to get a summary of page 2. Smaller input is both a better answer and a smaller disclosure.
Shared computers: the download folder is the leak. Local processing does not scrub Downloads. I use a private window for the session and I delete the downloads when I stand up. Private windows do not make AI requests local. They make the leftover files less likely to sit in a profile someone else opens. Different problem. I still do it.
If a colleague asks “is it safe to run the client’s employment file through here,” I ask which button. Merge, yes, with the usual caveat about the machine you are on. Summarize, no, not that file, not for a curiosity. The website being one brand does not make the buttons one data path. Read the button.
Libraries, and the request that is not your file
The first load of a local tool fetches pdf.js or pdf-lib from a public CDN. That request carries the usual browser metadata to that host. It does not include the PDF. If your threat model cannot tolerate a CDN seeing that you loaded a script, you have a stricter environment than this site was built for, and you should run a local copy of the libraries or not use the page. I am not going to pretend a script tag is a private courier. I am going to keep the distinction straight: script fetch versus document body. People collapse those and then either avoid a harmless merge or paste a contract into chat because “it all goes to the cloud anyway.” It does not all go. Some of it goes when you ask a model to read it.
Downloads land in the browser’s download directory, which backup software will happily copy to a phone. Local processing plus a synced Downloads folder is a leak with extra steps. I set that browser profile’s download location to a folder that is not in the sync client when I am on a client file. Tedious the first time. Invisible after. The privacy property of the tool ends at the download. After that it is your disk, your sync, your habit of emailing yourself the master “so I have it.” Emailing yourself the master is an upload. Name it as an upload when you decide to do it.
I keep a one-line comment in the project note when a model was used: “summary of pages 40–55 sent to the site AI on 12 May.” Not the text of the summary. The fact of the transmission. If a client ever asks what left the building, the note answers without me reconstructing it from memory. Memory is generous to me and useless to them. The note is dull enough that I will actually write it.
Browser extensions are outside this model. A “PDF helper” extension can upload a file the page itself never sent. I disable those on the profile I use for client work. The site cannot defend you from a plugin that reads the DOM or the file input. If the extension’s description says it syncs documents, believe it.