shouldivibecodeit

Should I vibe codeGoodLinks?

Save readable pages locally across Apple devices with tags and highlights

Saving a link is not saving an article. Store the HTML at save time or your archive is a list of 404s.

?

Their verdict, the Premium (Annual Feature Upgrade) price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.

Can you build it?asked by canivibecodeit.com ↗YESone-shottable · one sitting
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usSHIP ITgo. worst case you delete a repo.

The honest answer

why the verdict is what it is

A local database with a good reader on top, and both halves are honest weekend work: Readability extracts the article, SQLite holds the list, a share sheet puts things into it. Build it. The one decision that matters is made on day one — saving a URL is not saving an article. The page you meant to read will be paywalled, rewritten or gone by the time you get to it, and a read-later app whose archive turns out to be a list of dead links is a bookmark bar with better typography.

What actually breaks

not "if". the specific failures.

  • Extraction, on exactly the sites that need it most: paywalls, cookie walls, JS-rendered pages, newsletter archives
  • Link rot, if you stored the URL and not the page — half a decade-old reading list is already gone
  • Sync, the first time two devices edit the same item offline and last-write-wins quietly eats a highlight
  • Search, which is the only feature that matters at two thousand saved items and the one nobody builds first
  • The iOS share extension's memory budget, which is smaller than the page you are trying to save
  • Your reading list itself, which is a more revealing document than it feels like while you are making it

Is that you?

the verdict is a default, not a law

ship it if
  • The saved HTML is stored at save time, not fetched again at read time
  • Everything lives on your device, or in your own storage, and syncs through something you already trust
  • There is an export to Markdown and JSON, and you have run it
  • You are the only user and nobody else's reading is in the database
don’t ship it if
  • Sync is a shared table with no conflict rule, because the conflict is coming
  • You are hosting other people's reading lists, which is a far more sensitive dataset than it looks
  • The reader fetches and executes the original page's scripts in order to render it
  • The only copy of five years of highlights is a SQLite file that has never been backed up

If you build it anyway

the checklist, then the prompt that enforces it

  1. Store the extracted article HTML at the moment of saving, and keep the raw response too. Re-fetching later is how a reading list becomes an obituary.
  2. Sanitise before you render. Reader mode that runs the page's own scripts is a browser with none of a browser's protections.
  3. Give every item a stable id and a last-modified timestamp, and define the merge rule for conflicting edits before you enable sync on the second device.
  4. Build full-text search early, over the stored article text rather than titles. It is the difference between an archive and a pile.
  5. Export to Markdown plus a JSON index on a schedule, so the app is never the only way to read your own highlights.
  6. Treat the reading list as personal data even though it is only yours — it is a record of what you were worried about, month by month. Encrypt the sync payload.
the guardrail prompt
I am building a personal read-later app: save a page, read it cleanly, tag it,
highlight it. Local-first. Apply these constraints.

1. On save, fetch and store the article HTML immediately, and keep the raw
   response alongside the extracted version. Never design a flow that re-fetches
   the URL at read time — link rot is this app's defining failure.
2. Sanitise stored HTML before rendering: strip scripts, iframes, event handlers
   and remote form targets. Reader mode must never execute the source page.
3. Build the export before the reading UI. One Markdown file per item with the
   canonical URL, save date, tags, highlights and notes, plus a JSON index. Give
   me a command that runs it and tell me to try it before I rely on the app.
4. Everything is local by default: SQLite plus a files directory. If I ask for
   sync, do it as encrypted blobs through storage I control, and make me define
   the conflict rule before you write any sync code.
5. Give every record a stable UUID and a modified timestamp from the start.
   Retrofitting identity onto a synced dataset is not possible in practice.
6. Add full-text search over stored article text, not just titles, once there
   are more than a few hundred items — before any theming or animation work.
7. The share extension runs under a hard memory limit. Do the fetch and the
   extraction in the main app, not the extension: the extension's only job is to
   write a URL and return.
8. Do not add accounts, a server, or any analytics. If a feature needs a server,
   tell me what it would cost me to run for ten years before you build it.
9. Out of scope: social sharing, public profiles, recommendations, and anything
   that sends my reading list anywhere.
paste this before you build — not after something breaks25 lines · 1728 chars

That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.

their build prompt ↗

Or don’t build it

the boring option, and the way back out

just pay for it

$9.99 once for the universal app plus $4.99 a year for the feature upgrade is the cheapest thing on this site — call it forty cents a month for an app that is actively developed and syncs through iCloud without you owning a server. Build your own because you want the archive in your own files and formats, not to save money, because you are not saving any.

$0.42/mo is cheaper than your weekend.

your exit plan, if you already built it

A folder on disk: one HTML file and one Markdown file per saved item, named by date and title, plus a JSON index carrying tags, highlights and notes. That is a read-later archive that needs no application at all, which is the only kind that survives a phone upgrade, an OS deprecation and your own loss of interest in the project.

prior art · someone already did this
wallabag

Self-hosted read-later that stores article content rather than links, with mobile clients and exports.

Readability

Mozilla's article extraction library — the reader-mode engine you would otherwise try to write.

Questions

Is extraction really a solved problem?

Mostly. Mozilla's Readability handles a good majority of the web and is what a lot of shipping products lean on. The remaining fraction is the annoying part: paywalls, consent interstitials, pages that render their body in JavaScript, and sites that deliberately break reader mode. Budget for a manual paste-the-text fallback rather than an ever-growing pile of per-site rules.

Why is data-loss the risk tag on such a harmless app?

Because the value is cumulative and invisible until it is gone. Two thousand saved articles with highlights across six years is a real personal archive, it lives in one SQLite file, and nobody backs up an app's container directory. The failure is not dramatic — it is a restored phone and a fresh empty list.

Does the iCloud versus my-own-sync choice matter?

Operationally, a lot. GoodLinks uses iCloud, which means no server for the developer and no account for you. If you build your own, sync is the single hardest part of the project and the only part that can lose data silently. If you can live with one device, one device is a legitimate answer.

did you build it?

Every week, someone ships something they shouldn’t have.

New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.

also on the regret index
ReadwiseDEMO ONLY

Import your own highlights, resurface them on a schedule. Genuinely a small program.

Raindrop.ioSHIP IT

Save a URL, tag it, search it. This has been a solved weekend since 2004.

InoreaderSHIP IT

A reader is a polite HTTP loop and a table. The only way to get this wrong is to skip the polite part.

last reviewed 2026-08-05 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice