Web Applications

Margin, a reading log that is not a social network

Built by Camille Anne Villaruz

A private log of what I read and what I thought about it, with no followers, no ratings and no year-end wrap.

  • Builder email verified

    Verification

Project screenshot
Type
Personal
Category
Web Applications
Published
Jul 25, 2026
Updated
Jul 25, 2026
Built withSvelteKitTypeScriptSupabasePostgreSQLTailwind CSS
TopicsLifestyleProductivity

About this project

What I built & why

I kept a reading list on three different services over about six years and abandoned each one when it started asking me to perform. The last straw was a wrap-up graphic I did not ask for that ranked my year by page count. What I actually wanted was somewhere to put a book, a date, and the two or three things I want to remember about it — closer to a commonplace book than a library. I built it over one long holiday and a few weekends after, mostly for myself.

The problem

It solves the problem of wanting a durable record without wanting an audience. Every existing option treats reading as content: ratings, streaks, friends, recommendations. Margin has none of those. You add a book, you add notes and quotes against it, and you can search across everything you have ever written down — which is the only feature I use daily and the one every social reading app buries. It is for people who take notes on books and lose them.

What I owned

All of it, though it is small. The interesting parts are the note model — notes attach to a book and optionally a page, and quotes are a separate kind so they can be searched apart from my own commentary — and the import, which reads the export files from two services I left. I did the design too, which for once meant deciding what not to draw. It runs on a hosted database and a static frontend, and it costs me nothing.

Technical & product decisions

No ratings, and I have been asked for them by every person I have shown it to. A rating compresses a book into a number and then you start comparing, and comparing is the thing I was leaving. I also made it single-user with no sharing at all, rather than private-by-default with sharing available, because 'available' becomes 'expected'. On the technical side I chose full-text search in the database over any search service — the corpus is a few thousand notes, the built-in index is plenty, and one fewer moving piece means it keeps working while I ignore it for months.

Hardest challenge

The import from my old services was worse than building the app. Both exports were CSV, both encoded notes inline with lossy escaping, and one of them had silently truncated every note over a thousand characters years earlier, which I only discovered by comparing against a screenshot I still had. I ended up writing a reconciliation pass that flags any imported note ending mid-sentence so I could go back and rewrite them from the books. About sixty were unrecoverable, which is the actual cost of using services that do not care about export.

Result & impact

I have used it every week for two years and put roughly eleven hundred notes in it, which is more than the previous six years combined across three services — mostly because searching my own notes made me start writing them properly. Four friends use it now on their own copies. It has no analytics so I genuinely do not know more than that, which was a deliberate choice and is occasionally frustrating.

Who else worked on it

Nobody, though a friend who is a librarian talked me out of a tagging system and into plain search, which was the right call. Another friend hosts her own copy and has patched two bugs against it.