Technical details

How Seatpocket works.

For the curious: how Seatpocket packs a site, how the reader plays it back, what doesn’t work offline, where your packed sites live, and how to install and check the download from Terminal.

Packing a site

A real browser engine does the packing.

Each page loads in a hidden Chromium window, so sites that build their pages with JavaScript are packed as they actually appear.

  • Every request is recorded

    Seatpocket records every request a page makes, including the data its JavaScript fetches, with the original status codes and headers. It scrolls each page to bring in lazy-loaded images. Files shared between pages are stored once.

  • Pause, quit, pick up later

    Crawl state lives in the packed site’s database, so a long crawl can pause, survive quitting the app, and resume where it stopped. Failed URLs are listed and can be retried.

  • Rides out bad Wi-Fi

    Dropped connections are retried after a short wait. If your Mac goes offline mid-crawl, the crawl pauses instead of failing every page, and you resume when you’re back.

  • Refreshes fetch only what changed

    Refresh re-crawls with conditional requests (If-None-Match, If-Modified-Since), rewrites only what changed, and adds new pages. A packed site can also refresh daily when your Mac is online, on power, and idle.

  • Polite by default

    Seatpocket follows robots.txt and any crawl delay it sets, loads at most 2 pages at a time from each host, and waits 250 ms between them. robots.txt applies to pages: the images, styles, and scripts an allowed page needs are fetched the way a browser would. Every packed site can change these settings.

  • Sensible limits

    Each packed site stops at 2 GB and skips single files over 25 MB unless you change those limits. Video and audio are off by default. You can also cap the page count and link depth.

Presets

Grab exactly as much as you need.

The Pack a Website form offers three choices under “How much to bring”. Advanced options adds Custom and every setting behind them: scope, include and exclude patterns, caps, media types, and pacing.

A whole guide or manual

Everything under the start URL’s folder, seeded from sitemap.xml. Good for guides, manuals, and online books.

Depth
Unlimited
Pages
Up to 5,000

News site or blog

The same site, two links deep from the homepage. Refresh re-crawls from the homepage.

Depth
2 links
Pages
Up to 300

Just this page

Just this URL and everything it needs to render.

Depth
0
Pages
1

Custom

Start from the defaults and set scope, patterns, caps, media, and pacing yourself.

Depth
3, or anything
Pages
500, or anything

A whole guide or manual covers the start URL’s folder, and the form says which folder that is. A last segment without a trailing slash counts as a page, so https://react.dev/learn covers all of react.dev/. End the URL with / to keep to one section.

Reading offline

Pages that behave like the real thing.

The reader serves every request from the packed site, with the original status codes and headers, and has no route to the internet. It has back and forward, find in page, and an address bar that shows the page’s real URL.

Live or Snapshot, per page

Most sites replay with their JavaScript running. When a site’s scripts won’t cooperate offline, switch to Snapshot with ⌘⇧S.

LiveReplays the page with its JavaScript, serving every request from the packed site.
SnapshotThe page as it was rendered when it was packed, with JavaScript off.

Missing pages are marked

Links to pages that weren’t packed are faded, with a dashed underline on text links. Following one opens a “This page stayed behind” note instead of a browser error, even when the site’s own JavaScript router handles the click. Turn the marks off with Reader › Mark Links That Aren’t Packed.

Tested on 34 real sites: documentation built with Docusaurus, MkDocs, Sphinx, VitePress, and Starlight, plus Wikipedia, news sites, blogs, a newsletter platform, and single-page apps. In the latest round, pages replayed offline made no network requests and hit no missing pages.

Sign-in

Sessions, not passwords.

Every crawl and refresh of a packed site uses that site’s own sign-in session. Seatpocket keeps only the cookies Chromium stores, separately for each packed site, and never sees your password.

  • Sign In…

    Opens the live site in a window with back, forward, reload, and an address bar. Email and password work, and so do “Sign in with …” popups. Click Done and the packed site shows when you signed in. Cookies the site sets only for the browser session are kept for 30 days, so the sign-in survives quitting the app, until it expires or you click Sign Out.

  • Use Sign-In from …

    Some sign-in providers, notably Google, refuse embedded browsers. ••• › Use Sign-In from … copies the cookies that Chrome, Brave, Edge, Arc, Chromium, or Firefox holds for the packed site and its subdomains. For Chromium-based browsers, macOS first asks whether Seatpocket may use the browser’s “Safe Storage” key from the Keychain, and you can refuse.

  • Bot checks and login walls

    When a bot check or login wall blocks the whole site, the crawl pauses and says what to do next, for example: sign in, complete the check in the sign-in window, then resume.

  • Paywalled articles

    An article that comes back as a teaser keeps what it got and is listed under Failed, so Retry can fetch the full text after you sign in.

Limits

What doesn’t work offline.

The complete list.

  • Embeds from other sites, such as videos or social posts, aren’t recorded. They show a small “stayed behind” placeholder with an Open in Browser link.
  • Anything that needs a live server: comments, live search APIs, chat, WebSockets, server-sent events, and form posts.
  • Ads, analytics, and live widgets such as comment counts, “most read” lists, and personalization are simply missing on news sites. The article text and images are packed.
  • Video and audio are off by default to keep packed sites small. You can turn them on per site. Streaming video (HLS or DASH) isn’t supported, and files over the size cap (25 MB by default) are skipped.
  • Responsive images are stored at one size, so an image can look softer or sharper than on the live site.
  • Scripts that build addresses from the clock or random numbers can ask for something that was never saved. Common cache-busters are handled. If a page still breaks, switch it to Snapshot.
  • Snapshot mode has no JavaScript, so canvas drawings and interactive widgets don’t work there.
  • Aggressive bot protection or paywall scripts can block or cut short a crawl, even after you sign in.

Storage and privacy

Plain folders on your Mac.

No account, analytics, telemetry, or crash reporting. Besides crawling the sites you ask it to pack, the app only checks for updates, and you can turn that off.

  • One folder per packed site

    Packed sites live in ~/Library/Application Support/Seatpocket/archives. Each holds a SQLite index (pages, resources, crawl state, and a full-text search index) and the packed files, stored by content hash so shared files are kept once.

  • One file to move it

    Export any packed site as a single .seatpocket file and bring it into Seatpocket on another Mac with Import Site… (⌘⇧I).

  • The reader can’t reach the network

    Every request from a replayed page is answered from the packed site. The only way out is Open in Browser, which hands the address to your default browser.

  • More detail

    The privacy page lists everything the app stores and sends.

Install

Gatekeeper, Terminal, and checksums.

Seatpocket is signed ad hoc, not with an Apple Developer ID, and it isn’t notarized, so macOS asks you to confirm the first time you open it. The install guide walks through it step by step.

Seatpocket 0.3.1

Disk image for Apple silicon, macOS 13 or later

Download for Mac
File
Seatpocket-0.3.1-arm64.dmg
Released
Size
140.2 MB
SHA-256
ada845721a727acc263fd73b808acf191e8b76028e81f938cd7ccb680b665aea
  1. Skip the Gatekeeper prompt from Terminal

    After dragging Seatpocket to Applications, remove the quarantine flag, then open it normally.

    xattr -dr com.apple.quarantine /Applications/Seatpocket.app
  2. Or use System Settings

    • macOS 15 or later: open Seatpocket and close the warning. Then go to System Settings › Privacy & Security and click Open Anyway. Control-click › Open no longer bypasses Gatekeeper on macOS 15.
    • macOS 13 or 14: Control-click Seatpocket in Applications, choose Open, then click Open again.
  3. Check the download

    The result should match the SHA-256 shown here.

    shasum -a 256 ~/Downloads/Seatpocket-0.3.1-arm64.dmg
  4. Updating

    The app checks a signed update feed 30 seconds after launch and every 6 hours. It downloads a newer version in the background and checks its Ed25519 signature, SHA-256, bundle identity, and code signature. It installs when you choose Restart to Update or when you quit, and puts the old version back if the new one doesn’t start. It updates itself only from Applications (or another folder you can write to), so it offers to move there when opened from the disk image or Downloads. Turn off automatic checks in Check for Updates…. Packed sites are stored separately and stay where they are.