Last updated: 2026-08-10
SaaS Made Free is a directory of SaaS subscriptions that can be replaced with a self-hosted alternative built by a coding agent. The browser extension recognizes when you land on the website of a tool that is in the directory and shows you a small, dismissible panel with that tool's entry: whether it can be replaced, roughly what it would cost you in time, and a ready-to-use prompt.
The extension reads exactly one piece of information from the page you have
open: its hostname (for example notion.so). It
compares that hostname against a list of known tools.
Reading the hostname is the only thing the extension does on every page. If — and only if — that hostname matches a tool in the directory, it writes exactly one thing to the page: its own small, dismissible panel. That panel is rendered inside a closed Shadow DOM, a self-contained element isolated from the rest of the page. It does not read or modify anything that was already on the page, and the page's own scripts cannot see or reach inside it. If the hostname does not match, nothing is written at all.
The extension makes network requests in two situations, both described below in full. There is no third case.
notion) to our voting service. That
request carries no name, email, account identifier, or page content — only
the tool identifier. If you are offline at that moment, the identifier is
queued locally instead, and sent the same way the next time the extension
starts up or runs its daily refresh — see "Local storage on your device"
below.
A vote request necessarily arrives from your IP address, the way any network request does. Before anything is written to storage, our server hashes that IP address together with the day and a secret key that only the server holds and that is never published. The raw IP address is never written to disk in clear form — only the resulting hash, alongside the tool identifier and the day. This lets the server enforce "one vote per tool per day" while keeping the stored hash impossible to reverse back to your IP address without that key.
The website (not the extension) counts its audience itself, first-party, and publishes everything it collects on the public stats page. There is no private dashboard: what you see there is all we have.
What is counted, per day: page views (path and language), prompt copies and the agent chosen, visits from AI assistants and search engines, and visits from known AI crawlers (bot name only). Daily unique visitors use the same protection as votes: a SHA-256 hash of your IP address with a server-held secret and the current date — irreversible, and not linkable from one day to the next. Rows in that table are deleted after 45 days.
What is never collected: cookies, persistent identifiers, full referrer URLs (the browser reduces the referrer to a short label such as “chatgpt” before anything is sent), raw user-agent strings, or IP addresses in clear. The beacon only runs on saasmadefree.com and sends nothing from previews or local copies.
The website sells advertising slots. Buying one is the only thing on this site or in this extension that collects personal data about you. Reading the directory, copying a prompt, or voting never does.
The payment happens on Stripe, not here. Clicking to buy a slot sends you to Stripe's own checkout page, on their domain. Card numbers are typed there and never reach our servers — we never see them, and we could not store them if we wanted to. Stripe is a payment processor working on our behalf, not a buyer of data. What they collect on their page is covered by Stripe's privacy policy.
Stripe's form asks for four things, and passes all four back to us once the payment succeeds:
What we store on our side, in our own database (Cloudflare D1, the same one behind the public stats page): the Stripe session identifier, the slot, the number of months, the amount and currency, the date, the order's status, and the four fields above. Nothing else. There is no account and no password — buying a slot does not create a login.
While a slot is being paid for, its row also holds a hash of your IP address, built exactly like the one used for votes: SHA-256 of the address, the day, and a server-held secret that is never published. It caps how many slots one visitor can hold at once. It is erased the moment the payment goes through, or when the reservation expires about 35 minutes later.
How long. An order row is the record of a sale, so it is not deleted on a timer the way the analytics rows are (45 days). If you want yours removed, write to the address at the bottom of this page and we will delete everything we are not required to keep as an accounting record — starting with your email address.
The extension stores four things locally in your browser, using Chrome's standard extension storage. Three of them are settings that never leave your device: which tool panels you've dismissed, your language preference, and, if you choose to add one, your own custom agent template. None of those three are transmitted anywhere, including to us.
The fourth is different, on purpose: a small queue of votes cast while you
were offline. It holds the tool identifier (for example notion)
for each vote that couldn't reach our server right away. The extension
retries automatically — the next time it starts up, or at the next daily
refresh, whichever comes first — sending exactly those identifiers to our
voting service, the same request described above under "What leaves your
device," nothing more. Each identifier is removed from this local queue
once it has been sent successfully.
When you install this extension, Chrome shows a warning that it can "read and change data on all websites you visit." This permission exists for one reason: so that a new tool added to the public directory is recognized by every already-installed copy of the extension, the next time it refreshes its data — without you having to install an update. The extension's code that runs on a page you visit only ever compares the page's hostname against that list, and, only on a match, writes its own isolated panel described above; it never reads or changes anything else on the page. See "Auditability" below for how to verify this yourself.
The specific browser permissions requested, and why:
host_permissions: <all_urls> — needed to run the content script described above (read the hostname, and on a match write the panel) on any site, so newly added tools work without a new extension release.clipboardWrite — used only when you click a button to copy a prompt to your clipboard.storage — used only for what's described in "Local storage on your device" above.alarms — used only to schedule the once-a-day feed refresh described above.This extension is open source. The source code, including the exact file described above, is public and can be read, built, and compared against the version published in the Chrome Web Store.
Only one file in the extension ever runs on the pages you visit:
extension/content.js. It reads only
location.hostname from the page — never its content, its forms,
or its cookies — and makes no network request of its own. The one thing it
writes, and only on a hostname match, is its own panel element,
self-contained inside a closed Shadow DOM: it does not read or modify
anything already on the page. This is a short file and a ten-second read for
anyone who wants to verify both claims directly.
This extension is not directed at children and does not knowingly collect any data from anyone, of any age, beyond what is described above.
If this policy changes, the "Last updated" date at the top of this page will change accordingly. Because this page is part of a public, versioned repository, past versions of this policy remain visible in its history.
Privacy questions, or anything about the data described above: privacy@saasmadefree.com.