A single-user Roam is a tree of blocks in SQLite with page links, block references, backlinks and a daily-notes page, and an agent can wire that up in a weekend. The hard part is the editor: Enter, Tab and Shift-Tab, collapsing, zooming into a block and live-updating references that stay correct as you type. Real-time collaboration, a plugin store and mobile apps are well beyond one prompt, and Logseq or SiYuan already give you most of the model for free.
Before you buildRoam has no free plan. Logseq and SiYuan are free and open source with the same block model; try them before building.
Build me a personal block-based note outliner to replace Roam Research. Requirements:
- Node.js 22 + TypeScript: a Fastify API and a React front end built with Vite.
`npm start` serves http://localhost:4870 and opens today's daily note.
- Storage: better-sqlite3 in ./data/notes.db: pages (uid, title unique, created_at), blocks
(uid of 9 characters, page_id, parent_id, position, text, collapsed, updated_at), a refs table
(block_uid, target_page or target_block_uid) rebuilt whenever a block is saved, and an FTS5
table over block text.
- Editor: each block is a plain-text textarea that renders to formatted text when unfocused
(`markdown-it` plus inline rules for [[page]], #tag, #[[tag with spaces]], ((block-uid)) and
key:: value). Enter splits a block, Tab and Shift-Tab indent, Backspace on an empty block
merges, Alt-Up and Alt-Down move, and a bullet click zooms into that block.
- Autocomplete: typing [[ lists pages and creates a new one on Enter; typing (( searches block
text and inserts a block reference that shows the referenced text inline and updates when the
source changes.
- Pages: a daily-note page per day titled like "October 19th, 2026", a Linked References panel
(blocks that mention this page, grouped by source page) and an Unlinked References panel
(plain-text mentions of the title), each updating without a reload.
- Navigation: Ctrl/Cmd-K search over page titles and block text; a right sidebar opened with
Shift-click on any link; {{[[TODO]]}} blocks with checkboxes and a list of all open ones.
- Import and export: read a Roam JSON export (title, children, uid, string, create-time) into
pages and blocks, keeping block uids so ((references)) still resolve; export every page as
Markdown with nested bullets, plus one JSON file.
- Single user, one password from .env. No accounts, no telemetry, local-first. Back up the
SQLite file nightly into ./data/backups/ and keep 14 copies.
- Out of scope: real-time collaboration, a graph view, Roam queries, plugins, mobile apps.
- README: how to import a Roam export, and a warning that block references are rebuilt on
import so the first run on a large graph can take a few minutes.Opens your agent with the prompt filled in, you press enter. Or copy it and paste it into an empty folder.
The first prompt builds the core. Run these one at a time in the same folder to grow it into your own Roam Research.
Add simple queries to the outliner in this folder. Requirements:
- A block like {{query: {and: [[Project X]] [[TODO]]}}} shows a live list of blocks matching
all the page references, with {or: ...} and {not: ...} supported.
- Results show the block text with its page and parent path, are editable in place, and update
when the source blocks change.
- Reject malformed queries with a visible error inside the block.
- Unit-test at least 12 query strings. Update the README.Add a graph view to the outliner in this folder. Requirements: - /graph draws pages as nodes and links as edges with `d3-force`, sized by the number of references; clicking a node opens the page. - A filter box that limits the graph to a page and its neighbours up to two hops away. - Cap the drawn nodes at 800, keeping the most-linked, and say so on screen. - Update the README.
Add a Markdown mirror to the outliner in this folder. Requirements: - After every save, debounce by 5 seconds and write the changed page as ./data/mirror/<title>.md with nested bullets and block uids as trailing ^uid markers. - Commit changes to a local git repository in that folder with `simple-git`, one commit per minute at most. - A command `npm run rebuild-from-mirror` that restores the database from the folder. - Update the README.
Roam made the block, not the page, the unit of note-taking: you link a single bullet from anywhere and see where it is used. People with years of daily notes and references inside Roam stay for the editor and its extensions, even though Logseq and Obsidian now cover much of the same ground.
Estimate · Runs on your own machine for nothing; a small VPS at about $5 a month if you want it on your phone. The build itself is token usage on your agent plan.
Checked 2026-10-19 against Roam Research's docs: 1, 2, 3, 4, 5
| Plan | Monthly | Annual, per month | What you get |
|---|---|---|---|
| Pro (monthly) | $15 | — | Unlimited private or public graphs, unlimited collaborators, API access and apps. |
| Pro (yearly) | — | $13.75 | Same as Pro monthly. |
| Believer | — | $8.33 | Everything in Pro plus first access to new features, community calls with the team and priority support. |
No free plan. A 31-day trial applies only to an account that has never had a plan.
Kinda. The core is a weekend build with the prompt on this page, but real gaps remain: Real-time collaboration with other people on one graph, The Roam Depot extension store and the community's scripts and SmartBlocks.
About $15 a month on the Pro plan, $180 a year (checked 2026-10-19).
Real-time collaboration with other people on one graph; The Roam Depot extension store and the community's scripts and SmartBlocks; Mobile access and offline use of your graph; The graph view, queries and the maintained import and export paths; Years of tuned editor behaviour around links, embeds and block references. If any of those matter to you, keep paying.
Yes: Logseq (open source), SiYuan (open source), Obsidian (free).