·Productivity·Self-hosted

Notara

Notara

The notes app you actually own. A minimalist, fair-source Notion alternative — a block editor, inline databases, and real-time collaboration, self-hosted as a single container with everything in SQLite files you control.

🚀 Key Features

  • 📝 Block Editor: Paragraphs, headings, todos, code, toggles, callouts, images, PDFs and more
  • 🗂️ Inline Databases: Table and board views with fields, relations, and custom views
  • 👥 Real-time Collaboration: Invite by email or link, see who’s on the page, edit together
  • 🔍 Full-text Search: Across page titles and block content
  • 🗑️ Trash & Restore: Soft-delete anything, restore in a click, auto-purge on a retention window
  • 📥 Import / Export: Notion Markdown and CSV in, export back out anytime
  • ☁️ S3 Backups: Optional scheduled backups to any S3-compatible bucket
  • 🖥️ Desktop App: Native Electron build for macOS, plus the web client
  • 🔌 CLI + REST API: Scriptable end to end — a JSR-published CLI and a documented /api/v1 for automation, CI, and agents

🏗️ Architecture Highlights

Frontend

  • React: Block editor and app shell
  • Electron: Native macOS desktop build sharing the same codebase as the web client

Backend

  • Effect TS: Full backend built on Effect — services, layers, typed errors, RPC
  • SQLite (via Bun): One file per workspace, plus a separate platform DB for auth/users
  • better-auth: Self-hosted session/auth layer, no third-party auth service
  • Kysely: Typed SQL query builder over SQLite

Development & Deployment

  • Single container: One Docker image, no external services — SQLite on a mounted volume is the whole database
  • Backlog.md: Issue tracking lives in the repo (backlog/tasks/), not GitHub Issues
  • Documented ADRs: Architecture and licensing decisions recorded in docs/adr/

⚖️ Trade-offs

Effect TS for the entire backend

A deliberate, fairly heavy architectural bet: services, layers, and RPC calls are all typed through Effect rather than a conventional Fastify/Express + manual validation stack. The payoff is typed errors on every operation (strong, precise feedback for an LLM working in the codebase, not just for me) and composable services — S3 backups, SMTP, the database layer — built the same way throughout. This is a personal project, which is exactly why I could afford to commit to it: no team to onboard, no deadline pressure to fall back to something more familiar mid-project.

better-auth over a hosted auth provider

Self-host is non-negotiable for a “notes app you actually own” — pulling in Clerk or Auth0 would mean the one thing users are trusting me not to depend on external infrastructure for. better-auth runs entirely inside the same container as everything else.

SQLite, one file per workspace

Not a shared multi-tenant database — each workspace is its own .db file under .data/workspaces/, with a separate platform.db for auth and workspace metadata. This buys real isolation and portability: backing up, moving, or deleting a workspace is copying or removing one file, not running a scoped export against a shared schema.

Single instance, scale up not out

Documented directly in the README: rate limiting and presence state live in-process, so Notara runs as one container behind a reverse proxy — a bigger box, not a fleet. For a self-hosted single-team tool this trade is free; it would need re-architecting (external state store) before it could run as multiple replicas.

FSL-1.1-ALv2 over MIT or a paid EULA

Originally shipped as a one-time-purchase commercial license (capped at 500 buyers via Polar); relicensed to the Functional Source License after concluding that direct monetization at that scale wasn’t realistic and the commercial machinery was gating adoption, not protecting real revenue. Plain MIT/Apache was rejected too — it would let a competitor host “NotaraCloud” on top of the work with nothing returned to the project. FSL keeps the one real threat (a competing hosted service) closed while everything else — self-hosting, modifying, redistributing — stays free, and the license converts to Apache-2.0 two years after each release regardless. Full reasoning in docs/adr/004-fair-source-fsl.md.

Tags:#TypeScript#Effect#SQLite#React#Electron#Bun#better-auth