No description
  • TypeScript 44.9%
  • Rust 40.8%
  • Svelte 11.5%
  • CSS 1%
  • JavaScript 0.9%
  • Other 0.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
RaringM 23b4af8097
Some checks failed
CI / E2E (Chromium 1/2) (push) Successful in 6m46s
CI / E2E (Chromium 2/2) (push) Successful in 6m24s
CI / Web (push) Successful in 2m7s
CI / E2E (API) (push) Successful in 1m26s
CI / Rust (push) Successful in 4m49s
CI / E2E Report (push) Successful in 24s
Release / Web (push) Successful in 1m45s
iOS TestFlight / Web (push) Failing after 2m29s
Docker / Web (push) Successful in 2m44s
Docker / Rust (push) Successful in 4m51s
Docker / E2E (API) (push) Successful in 1m16s
Release / Rust (push) Successful in 7m4s
iOS TestFlight / Rust (push) Successful in 7m11s
iOS TestFlight / E2E (API) (push) Has been skipped
iOS TestFlight / E2E (Chromium 1/2) (push) Has been skipped
iOS TestFlight / E2E (Chromium 2/2) (push) Has been skipped
Release / E2E (API) (push) Successful in 1m54s
Docker / E2E (Chromium 1/2) (push) Successful in 4m19s
iOS TestFlight / E2E Report (push) Failing after 46s
iOS TestFlight / Validate TestFlight commit (push) Failing after 0s
iOS TestFlight / Build and upload to TestFlight (push) Has been skipped
Docker / E2E (Chromium 2/2) (push) Failing after 5m50s
Docker / E2E Report (push) Successful in 39s
Docker / Validate image commit (push) Failing after 0s
Docker / Build & Push Docker Image (push) Has been skipped
Release / E2E (Chromium 1/2) (push) Successful in 4m57s
Release / E2E (Chromium 2/2) (push) Successful in 5m19s
Release / E2E Report (push) Successful in 24s
Release / Validate release commit (push) Successful in 0s
Release / Classify tag (push) Successful in 2s
Release / Web Frontend (push) Successful in 35s
Release / Server (noture-server-linux-arm64) (push) Successful in 3m30s
Release / Server (noture-server-windows-amd64.exe) (push) Successful in 3m4s
Release / Server (noture-server-linux-amd64) (push) Successful in 6m32s
Release / Desktop (Windows x86_64) (push) Successful in 9m9s
Release / Desktop (Linux x86_64) (push) Successful in 10m7s
Release / Server (noture-server-macos-amd64) (push) Successful in 12m26s
Release / Server (noture-server-macos-arm64) (push) Successful in 12m4s
Release / Desktop (macOS x86_64) (push) Successful in 29m35s
Release / Desktop (macOS arm64) (push) Successful in 17m40s
Release / Create Release (push) Successful in 22s
settle the parse and katex before counting keystroke transactions and folding
2026-11-02 14:57:25 -06:00
.forgejo run rust, web and chromium e2e on push, everything else nightly, through shared setup actions 2026-11-01 23:33:34 -06:00
apps bump version to 0.5.0 2026-11-02 14:20:09 -06:00
crates wait for the client's close reply before dropping an event socket 2026-11-02 14:44:38 -06:00
deploy let the nginx example accept 256 MiB imports 2026-11-01 21:43:15 -06:00
e2e rename lib/plugins to lib/registry and move the core registrations into it 2026-11-02 00:34:55 -06:00
fixtures share the note snapshot rules between desktop and web 2026-11-02 00:04:13 -06:00
fuzz bump version to 0.5.0 2026-11-02 14:20:09 -06:00
packages/editor settle the parse and katex before counting keystroke transactions and folding 2026-11-02 14:57:25 -06:00
scripts add a changelog and a script that drafts it from the log 2026-11-01 23:35:48 -06:00
.dockerignore build the docker image in one stage and run the server as a non-root user 2026-11-01 21:12:34 -06:00
.gitignore stop tracking the editor node_modules symlink 2026-11-02 00:32:00 -06:00
.node-version stop pnpm from reinstalling before every script and pin node 24 2026-11-01 21:12:34 -06:00
.prettierignore keep worktrees and leftovers out of lint and format checks 2026-11-01 21:12:34 -06:00
.prettierrc initial move 2026-04-26 19:06:17 -05:00
bench-budget.json work on criterion 2026-05-01 15:08:23 -05:00
Cargo.lock bump version to 0.5.0 2026-11-02 14:20:09 -06:00
Cargo.toml bump version to 0.5.0 2026-11-02 14:20:09 -06:00
CHANGELOG.md add a changelog and a script that drafts it from the log 2026-11-01 23:35:48 -06:00
config.example.toml make the server config strict and fold rarely used knobs into constants 2026-10-07 06:22:50 -05:00
docker-compose.yml initial move 2026-04-26 19:06:17 -05:00
Dockerfile build the docker image in one stage and run the server as a non-root user 2026-11-01 21:12:34 -06:00
eslint.config.js group the export services under services/export 2026-11-02 00:33:10 -06:00
LICENSE initial move 2026-04-26 19:06:17 -05:00
package.json add a changelog and a script that drafts it from the log 2026-11-01 23:35:48 -06:00
perf-budget.json add a keystroke latency budget for long notes 2026-10-07 03:13:55 -05:00
pnpm-lock.yaml drop unused fflate and y-indexeddb 2026-10-07 04:24:12 -05:00
pnpm-workspace.yaml stop pnpm from reinstalling before every script and pin node 24 2026-11-01 21:12:34 -06:00
README.md Merge branch 'review2-p3-sync' into review2-p4-security 2026-11-01 22:02:59 -06:00
rust-toolchain.toml initial move 2026-04-26 19:06:17 -05:00

Noture

A self-hostable note-taking app built on plain markdown files. Inspired by Obsidian's editing experience and Sublime Text's aesthetics, powered by Rust.

Highlights

  • Live Preview editor — CodeMirror 6 with inline rendering of markdown, math, diagrams, and images
  • Built-in sync — real-time CRDT sync across devices with no third-party service required
  • E2E encryption — optional per-vault encryption (XChaCha20-Poly1305) so the server never sees plaintext
  • Lightweight desktop app — native app via Tauri (~5 MB, not Electron)
  • Self-hosted — run with Docker or a single binary; you own your data
  • Plain markdown — flat files on disk, no proprietary format, no vendor lock-in
  • Documentation publishing — publish notes or folders as websites under a path or subdomain

Quick Start

# Copy the example config
cp config.example.toml config.toml

# Start with Docker Compose
docker-compose up -d

Open http://localhost:8080 and create your first account.

Installation

Docker Compose

services:
  noture:
    build: .
    ports:
      - '8080:8080'
    volumes:
      - noture-data:/data
      - ./config.toml:/etc/noture/config.toml:ro
    environment:
      NOTURE_CONFIG: /etc/noture/config.toml
      NOTURE_DATA_DIR: /data
    restart: unless-stopped

volumes:
  noture-data:

Minimal config.toml:

bind_addr = "0.0.0.0:8080"
data_dir = "/data"

The first account you create is the admin. Registration then closes; the admin adds further accounts from the admin page.

Single Binary

Download the latest release binary for your platform, then:

export NOTURE_DATA_DIR=/var/lib/noture
export NOTURE_BIND_ADDR=0.0.0.0:8080
./noture-server

Desktop App

Download the Tauri desktop app from the releases page. Available for macOS, Windows, and Linux. The desktop app stores vaults locally and can optionally connect to a self-hosted server for sync.

Configuration

See config.example.toml for the full configuration reference. The server reads NOTURE_CONFIG (default ./config.toml, optional). Every key can be overridden by an environment variable named NOTURE_<KEY>. Unknown keys, invalid values, and an unreadable config file stop the server at startup.

Key Default Description
bind_addr 0.0.0.0:8080 Address and port to listen on
data_dir ./data Directory for databases, attachments, and the search index
secure_cookies true Mark session cookies Secure (disable only for plain HTTP)
cors_origins [] Origins allowed to make credentialed cross-origin requests
trusted_proxies [] Reverse-proxy CIDRs whose X-Forwarded-For is trusted
publish_base_domain — Base domain for subdomain-published vaults
public_origin — Canonical origin for public links
auth_rate_limit 5 Auth attempts per client IP per minute (0 disables)
password_hash_fast false Minimal password-hashing cost, for test environments only

Backups

noture-server backup --data-dir /var/lib/noture --output noture-backup.tar.gz

The archive holds both databases, the attachments and a SHA-256 manifest, and is verified before it is written. It works while the server runs. Add --include-tantivy to keep the search index; otherwise it is rebuilt on start. To restore, stop the server, extract the archive into an empty directory and start the server with data_dir pointing at it.

Features

Editor

  • Live Preview markdown (headings, bold, italic, code, links, images)
  • WikiLinks with autocomplete and backlink tracking
  • Tables, footnotes, strikethrough
  • Math rendering via KaTeX (inline and display)
  • Mermaid diagrams
  • Obsidian-style callouts (14 types)
  • Block references and transclusion (![[note]])
  • Slash command menu for block insertion

Organization

  • Vaults, folders, and tags
  • Graph view (D3.js)
  • Backlinks panel
  • Daily notes and templates
  • Starred notes, recent files
  • Full-text search

Sync & Collaboration

  • Real-time CRDT sync via Yjs/yrs (WebSocket)
  • Shared vaults with roles and invitations

Security

  • Optional per-vault E2E encryption
  • Argon2id password hashing
  • API tokens for programmatic access

Publishing

  • Publish notes or entire folders as static websites
  • Path or subdomain routing (publish_base_domain)

Import & Export

  • Import from Obsidian, Joplin, and plain markdown
  • Export to HTML, PDF, or ZIP

Tech Stack

Layer Technology
Desktop shell Tauri v2
Frontend Svelte 5 + SvelteKit
Editor CodeMirror 6
Backend Axum (Rust)
Sync yrs (Rust Yjs port)
Storage Flat markdown + SQLite (WAL)
Search Tantivy
Encryption XChaCha20-Poly1305 + PBKDF2

Building from Source

Prerequisites: stable Rust (rust-toolchain.toml), Node.js 24 (.node-version), pnpm 11.24.0 (pinned in package.json)

pnpm install

# Web server (produces a single binary with embedded frontend)
pnpm run build:server

# Desktop app
pnpm run tauri build

Development

pnpm run dev          # SvelteKit dev server (port 5173)
pnpm run tauri dev    # Desktop app with hot reload
pnpm run version:bump -- patch   # Bump Noture to the next patch version
pnpm run test         # Rust unit and integration tests
pnpm run test:js      # Editor tests
pnpm --filter @noture/web run test  # Frontend service/store tests
pnpm run test:e2e     # Playwright end-to-end tests
pnpm run lint:all     # Frontend + Rust lint and type checks

License

GNU Affero General Public License v3.0