The truth is, nothing is bulletproof when it comes to privacy in this current iteration of the Internet. But I tried. This page is dedicated to some of the decisions that go into the privacy-focused development of Pinax.

Images

Favicons

Favicons are compressed into a base64 data URL in the bookmarks file. This ensures that Pinax can remain offline and that there are no external requests after the initial fetch.

OG Images

In grid view, Open Graph Images, or OG Images, are fetched if enabled. However, they are not fetched the same way as favicons. Favicons are usually only a few pixels, but storing base64 URLs of these images would make the system files pretty large.

Another option was to store the actual URLs of these images and fetching them when rendered. This created a host of problems:

  • Tracking pixels: Servers log every view with IP, timestamp, user agent
  • Referer leakage: Reveals you’re using Pinax app
  • Third-party requests: Browser makes requests to dozens of external servers
  • Network metadata: ISP sees which bookmarks you’re viewing
  • Offline doesn’t work: Images fail without internet
  • Continuous exposure: Unlike browsers (fetch on visit), Pinax would need to fetch on every bookmark view

The solution: a cache directory When a bookmark is rendered in grid view, the backend searches the cache folder for an OG image. If one is not found, it will attempt to fetch one and download a compressed copy into the cache folder. Once a bookmark is one day old, this will only happen once a week per bookmark. If a bookmark is updated, the old cache image is deleted first.

This creates a one-time fetch, just like favicon. It saves on space, and is self-healing.

Favicon vs OG Image Privacy

Even still, there are privacy considerations for both.

Favicons:

  • Less concerning - fetched once when adding bookmark
  • Expected behavior - you’re already visiting the site
  • Small exposure - one request per domain

OG Images:

  • More concerning - fetched when rendering bookmark
  • Reveals bookmarking behavior
  • Timing leak - reveals when organizing bookmarks

Risk Assessment

Low Risk: Fetching from your own sites, or even some major sites (GitHub, YouTube) can be low risk. It’s also a one-time fetch that’s cached “forever”.

Medium Risk: Some sites pose a stronger risk. Sites that have analytics (so…most of them) and sites that coorelate IP + timestamp. This potentially could reveal that you bookmarked something.

High Risk: The highest risk is untrusted sites, sites that keep track of who bookmarks content (assuming they know what Pinax is), and senstive private webpages.

How do browsers do it?

Chrome/Firefox/Safari:

  • Fetch favicons when visiting site (not when bookmarking)
  • Don’t fetch OG images for bookmarks at all

Pinax:

  • Fetches once via Rust (no cookies, no tracking)
  • Caches “forever” (no repeat requests)
  • More private than loading URLs on every view (like most other bookmark managers do)

Other Options Explored but Rejected

Hybrid URL + Cache Reference

Store both URL and cache filename in JSON - rejected due to sync conflicts and JSON modification concerns.

Sync Cache Directory

Include cache in sync - rejected due to large sync payload.

Third-Party Screenshot Services

Follow what most other bookmark managers do and use an external services for screenshots or render the actual site in-app - rejected as it violates privacy principles and costs money.

Lazy Cache Population with URLs

Store URLs, build cache on-demand - rejected for privacy concerns.