← All projects

Case · Go backend

Card Index: notes with search

A Markdown notes base on Go and SQLite: [[wiki]] links with backlinks and a link graph, FTS5 full-text search (bm25, highlighting, simplified Russian morphology), version history with its own diff, autosave with conflict resolution, .md export and import.

  • Go
  • SQLite
  • FTS5
  • bm25
  • modernc.org/sqlite (no CGO)
  • REST API
  • Markdown (custom safe renderer)
  • SVG force-layout
  • Vanilla JS
  • embed
  • Docker
  • GitHub Actions

01 · How it looks

Screenshots

Screenshot of the project "Card Index: notes with search" at 1280 pixels wide
Desktop, 1280 px
Screenshot of the project "Card Index: notes with search" on a phone screen, 390 pixels wide
Phone, 390 px

02 · About

What it is and why

Card Index is a Markdown notes base on Go and SQLite. Notes are linked with [[wiki links]], with backlinks and a link graph, and search runs on SQLite FTS5 with bm25 ranking, match highlighting and simplified Russian morphology.

A single binary: the standard library and modernc.org/sqlite (no CGO), with a vanilla JS interface embedded through embed. Demo mode adds 12 notes about the project itself, each one honestly marked.

Limitations

The Russian morphology is simplified: it strips endings from a short list and adds prefix search. Fleeting vowels, alternations and irregular forms are not handled, and short words can produce false matches.

Renaming a note does not rewrite the old [[links]] in other notes. Markdown has no tables, images or footnotes.

One shared token, with no users or permissions. Conflicts are resolved wholesale (take theirs or overwrite); there is no line-by-line merge.

The graph is meant for hundreds of notes, not thousands. The -race tests run only in CI (there is no gcc locally).

What is inside

  • A custom safe Markdown renderer: the source is escaped as a whole, only the renderer creates tags from a closed set, and link schemes come from an allow-list; the XSS test runs about 30 payloads
  • Wiki links [[Title]] and [[Title|label]] with backlinks; a link to a note that does not exist yet comes alive when the note appears
  • An SVG link graph: a Fruchterman-Reingold layout in vanilla JS, draggable nodes, keyboard navigation
  • FTS5 search: bm25 with weights (title x8, tags x4, body x1), prefix search, highlighting done in Go code, a tag filter
  • Version history and a line-based diff on LCS between any two versions, with restore
  • Autosave with an optimistic list update, rollback on error and conflict resolution by rev (409)
  • Export everything as a zip of .md files with front matter; import a folder of .md files, single files or a zip
  • A REST API behind a Bearer token, dark and light themes, Docker and GitHub Actions

03 · How to run

Run it locally

git clone <repository on request> notes-search
cd notes-search
SEED_DEMO=1 go run ./cmd/server   # http://localhost:8089, token demo

04 · Code

The repository is private

The source lives in a private repository. I will grant access on request: write to me and I will send an invitation.

Request the code