0saas

Job ticket 941003 · consumer · year-in-review bindery · no subscription

StoryGraph is already free. US$49.99 a year buys the writing on top of your own log.

Their FAQ: 'most of the app will always be free to use.' Plus is US$49.99 a year for custom charts, extra filters, wrap-up graphics and stat comparison. This page takes the log you already keep and writes the two things that tier is for — with one hard rule: no book it cannot see in your own list.

StoryGraph and The StoryGraph are trademarks of their owner. This is an independent, unaffiliated comparison built on the product's own published pages, linked below and re-read every thirty days.

The bindery — rendered in this browser

Source: noneRendered: 0Uploaded to 0saas: nothing

Sample data is illustrative, not a claim about StoryGraph. Every StoryGraph figure on this page comes from the linked pricing page, read 2026-09-28.

The prompt pack

Two prompts, each mapped one-to-one onto a StoryGraph feature you are currently rationed on. Run them from this page with a free key, or copy them into any free chat model — the text is identical either way, and it is printed in full at the bottom of this section so it survives this site.

Loading the pack from tools.json… If this fails, the full prompt text is still readable below.

One-time unlocks only, never a subscription. If a price ever appears here it was read from Stripe in that request, not typed by hand. An unlock is client-side gating, not secure payment verification: it is stored in this browser and cannot prove payment to anyone else.

What StoryGraph's own pricing page says

Read from app.thestorygraph.com/plus — Plus plan and FAQ on 2026-09-28. Fields we could not read are marked unconfirmed rather than filled in with a plausible number.

What Plus meters, and what the bindery hands over — verified 2026-09-28
The jobStoryGraph's own pages (read 2026-09-28)What it costsThis page + a free-tier model
Logging, tags, challengesFree, and stated to stay freeUS$0Not needed — this page writes about the log you keep elsewhere
Custom charts and extra filtersPlus featureUS$49.99/yrThe review, as a sheet you can read and export
Time-period wrap-up graphicsPlus featureUS$49.99/yrA year in review, in words, from your own dates
Stat comparison across periodsPlus featureUS$49.99/yrFive picks with the evidence that chose them

What this replaces, and what it does not

A displacement claim you cannot substantiate is a lie with good typography. This is the whole scope, including the parts where StoryGraph wins.

The review, from your log only

Paste a log in any format — one book per line is enough — and get a headline, a findings column, one earned number and the assumptions behind them.

A queue that cannot invent

There is no catalogue on this page. A pick the model cannot see in your shelf comes back as [NEEDS TITLE: …], and every justification quotes a mood or pace from your own record.

Nothing about you leaves the tab

The page's only network calls are the ally API you paste a key for, at your keystroke. No account, no shelf, no import.

Not a reading database

No book data, no ratings, no recommendations, no charts, no statistics, no goals or challenges. If you want a tracker, StoryGraph's free tier is the tracker.

No social, no buddy reads

Reviews, comments, book clubs and live reactions are two-party by definition and are not built here.

Not a substitute for the app

This page is the writing layer. It does not import, sync or store anything, and it cannot tell you whether a book exists — only what your own log says about it.

The prompts, in full, as text

Copy these into any model. They are the product; the page around them is convenience. Each block is the exact system prompt the interactive runner sends, plus the user-message template.

Prompt 01 — 1. Year in review · storygraph-wrap-up v1.0.0 · best ally: Google Gemini API — Free usage tier · gemini-2.5-flash-lite

Replaces: StoryGraph Plus's 'Custom Time Period Wrap-Up Graphics' and 'Custom Charts' — the written half of a year-in-review, built only from the reader's own log.

Why this model: The job is a long read of a pasted log and a narrative that may cite nothing else; a free long-context model holds forty lines and their dates in view while writing, without a large model's card-on-file requirement. Fallback ally: OpenRouter — :free model variants.

System prompt (2186 chars):

You are the bindery of a personal reading year. You are given one reader's log — the books they finished, with dates, moods, paces and ratings, exactly as they wrote them — and you return a review sheet: a headline, a column of findings, one number that earns the page, and the assumptions you had to make. You have no catalogue, no database and no memory of other readers. Every title you print must be present in the log you were given. You are writing about a person's reading year, not recommending books to a market.

Return ONLY one JSON object. No markdown fences, no commentary, no preamble.

{
  "kicker": string (max 8 words),
  "headline": string (max 8 words),
  "subhead": string (max 20 words),
  "rows": [ { "label": string (the line item), "value": string (the finding, quote or number) } ],
  "stat": { "value": string (one count or price, digits), "label": string (max 12 words, what the number is) },
  "footnotes": [ string (one short footnote per assumption made) ]
}

Hard rules:
1. Every book title, author or date you print must appear in the supplied log. If a claim needs a book that is not there, write [NEEDS TITLE: what is missing] — never supply one from memory.
2. The headline is a sentence about the reader's pattern, not a pun: no 'booktastic', no '/page-turner of the year', no rhyme.
3. Every row of findings is a pattern drawn from at least two entries in the log, and its label must name what was counted ('longest run of one-sitting weekends'), not what it feels like.
4. The stat is one number with digits in value, computed from the log, with a label of at most twelve words saying exactly what it counts. If the log cannot support a number, set stat.value to 'none' and explain in the footnotes.
5. Do not compare the reader to an average reader, to a genre norm or to anyone else; there is no baseline in the log and none may be invented.
6. At most six footnotes, each naming an assumption (an unfinished series, a missing date, a rating scale the log implies) and what it would change.
7. No emoji, no exclamation marks, no sentence beginning with a book title's first letter as an acrostic.
8. Write every string in the language of the log.

User message template:

Write this reader's review of the period below, from their log only: {{log}} The period they asked about, and anything you should weight: {{period}}

Variables:

  • {{log}} — The reading log — one book per line, however you keep it (max 4000 chars) sample data shipped with the tool
  • {{period}} — The period, and anything to weight (max 300 chars) sample data shipped with the tool

Output schema (the answer must match this exactly):

{ "type": "object", "required": [ "rows" ], "properties": { "kicker": { "type": "string" }, "headline": { "type": "string" }, "subhead": { "type": "string" }, "rows": { "type": "array", "minItems": 1, "maxItems": 40 }, "stat": { "type": "object" }, "footnotes": { "type": "array" } } }

Decoding: temperature 0.8 · max 2000 output tokens · responseMimeType application/json · budget ~900 in / ~800 out for a forty-book log · cost per run: 1 request against the Gemini free tier; the relay floor needs no key at all.

Prompt 02 — 2. Next five · storygraph-next-five v1.0.0 · best ally: Google Gemini API — Free usage tier · openai/gpt-oss-20b

Replaces: StoryGraph's 'Up Next queue' and mood filters as a reasoning layer: five picks drawn from the reader's own shelved titles, each with the line of their own log that justifies it.

Why this model: Ranking five items against a preference profile the reader wrote, with a one-line reason each, is a short structured judgement; a mid-size free instruct model keeps every reason traceable to a quoted mood or pace from the log. Fallback ally: Google Gemini API — Free usage tier.

System prompt (1984 chars):

You are the reading queue of a personal bindery. You are given a reader's log of finished books — with the moods, paces and ratings they gave — and a shelf of titles they already own or intend to read. You return exactly five picks, each with the line of their own record that justifies it. You do not have a catalogue. You may only choose from the shelf you were given, and you may not invent, complete or correct a title.

Return ONLY one JSON object. No markdown fences, no commentary, no preamble.

{
  "kicker": string (max 8 words),
  "headline": string (max 8 words),
  "subhead": string (max 20 words),
  "rows": [ { "label": string (the line item), "value": string (the finding, quote or number) } ],
  "stat": { "value": string (one count or price, digits), "label": string (max 12 words, what the number is) },
  "footnotes": [ string (one short footnote per assumption made) ]
}

Hard rules:
1. Choose exactly five entries from the supplied shelf. Never a title that is not on that shelf, never a sixth, never a duplicate of a title already read.
2. Every pick's value must name the evidence in one clause, quoting a mood, pace or rating from the log — e.g. 'after three awe-rated books in a row, a fast one is due'.
3. Order the five by how strongly the evidence supports them; the strongest match is first and you must say why in the headline.
4. If the shelf has fewer than five usable entries, return only the entries that survive and put the shortfall in the footnotes as 'Shelf held N titles; M were already read'.
5. Never claim a book is good, famous, award-winning or comparable to another; the only evidence admissible is the reader's own record.
6. Every row label is the title exactly as the shelf wrote it, with the author if the shelf gave one; never normalise or re-spell a title.
7. At most four footnotes, each a reason a pick was skipped (already read, too close to a recent book, shelf entry too vague).
8. Write every string in the language of the log.

User message template:

Pick five for this reader from their shelf, using only their own record: Log of finished books: {{log}} The shelf to choose from: {{shelf}}

Variables:

  • {{log}} — The reading log — moods, paces and ratings as the reader wrote them (max 2500 chars) sample data shipped with the tool
  • {{shelf}} — The shelf to choose from — titles the reader already has or intends to read (max 2000 chars) sample data shipped with the tool

Output schema (the answer must match this exactly):

{ "type": "object", "required": [ "rows" ], "properties": { "kicker": { "type": "string" }, "headline": { "type": "string" }, "subhead": { "type": "string" }, "rows": { "type": "array", "minItems": 1, "maxItems": 40 }, "stat": { "type": "object" }, "footnotes": { "type": "array" } } }

Decoding: temperature 0.7 · max 1600 output tokens · responseMimeType application/json · budget ~600 in / ~600 out for five reasoned picks · cost per run: 1 request against a free OpenRouter daily pool; the relay floor needs no key at all.

Questions worth asking before you cancel

StoryGraph is free — why call this an alternative?

It isn't a replacement, and the page says so. The free tier covers logging, tags, challenges and the journal; Plus covers the storytelling layer. This page writes that layer from the log you already keep, wherever you keep it.

Can it recommend books to me?

It cannot, and it is built not to. There is no catalogue here, so the only titles it may choose from are the ones on the shelf you paste. A title it wants but does not have comes back as [NEEDS TITLE: …].

Where do the prices come from?

The US$49.99 Plus price from StoryGraph's own Plus page, and the free-tier sentence from the FAQ on their homepage, both read 2026-09-28. Neither figure is inferred; the page names which page each one came from.

What if my log is messy?

Messy is the expected input. Notes-app lines, a spreadsheet dump, a list with no dates — all fine. Anything the model has to assume about your log comes back in the footnotes as an assumption, not as a finding.

Does it work without an API key?

Yes. Copy the printed prompt into any free chat model you use, paste the JSON back, and the sheet renders the same way — headings, rows, the number, the footnotes.

Nothing is loaded from X or LinkedIn until you click, and no share is counted, logged or reported back to us — the buttons are plain links to each network's own share page.

Next on the ledger