<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Liran</title>
    <description>The latest articles on DEV Community by Liran (@ilirans).</description>
    <link>https://dev.to/ilirans</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3935354%2F60ccb45d-a3fa-41bf-89d7-2f89698e3827.png</url>
      <title>DEV Community: Liran</title>
      <link>https://dev.to/ilirans</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ilirans"/>
    <language>en</language>
    <item>
      <title>How I Implemented a Local-First, E2EE Architecture with Sync in My App</title>
      <dc:creator>Liran</dc:creator>
      <pubDate>Tue, 09 Jun 2026 19:41:50 +0000</pubDate>
      <link>https://dev.to/ilirans/how-i-implemented-a-local-first-e2ee-architecture-with-sync-in-my-app-4c28</link>
      <guid>https://dev.to/ilirans/how-i-implemented-a-local-first-e2ee-architecture-with-sync-in-my-app-4c28</guid>
      <description>&lt;p&gt;Building a note-taking app is almost a rite of passage for developers. There are already plenty of great options out there, so when I started working on Annota, I wanted to challenge myself with a different set of problems: building something local-first, fully offline-capable, and encrypted by default.&lt;/p&gt;

&lt;p&gt;The result is &lt;strong&gt;Annota&lt;/strong&gt;, a security-focused note-taking app with dedicated desktop applications built using Tauri (macOS and Windows) and mobile apps built with React Native + Expo (iOS today, Android coming soon).&lt;/p&gt;

&lt;p&gt;One thing I cared about from the beginning was keeping the architecture maintainable as the project grows. The app is split into isolated packages with clear responsibilities—for example, the editor and synchronization engine live independently from each other, making it easier to evolve each system without creating tight coupling.&lt;/p&gt;

&lt;p&gt;Over the last few weeks, I documented some of the core architectural decisions behind Annota. Here's a high-level look at three of the biggest challenges I tackled.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛡️ End-to-End Encryption
&lt;/h2&gt;

&lt;p&gt;For a privacy-focused application, I wanted the server to know as little as possible about user data.&lt;/p&gt;

&lt;p&gt;Everything starts on the user's device:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A master seed is generated from a 12-word BIP39 recovery phrase.&lt;/li&gt;
&lt;li&gt;That seed is processed with Argon2id to derive a 256-bit master key.&lt;/li&gt;
&lt;li&gt;Using HKDF-SHA256, the master key is split into separate encryption keys for notes and file attachments.&lt;/li&gt;
&lt;li&gt;Before anything is synced, note content and metadata are serialized and encrypted locally using AES-256-GCM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The server never sees plaintext note content.&lt;/p&gt;

&lt;p&gt;📖 Full write-up: &lt;a href="https://www.lirans.online/blog/annota-encryption" rel="noopener noreferrer"&gt;Architecture Walkthrough: Annota Encryption&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Synchronization
&lt;/h2&gt;

&lt;p&gt;Building a sync engine for a local-first app turned out to be one of the most interesting parts of the project.&lt;/p&gt;

&lt;p&gt;The challenge is finding a balance between responsiveness, reliability, and battery usage.&lt;/p&gt;

&lt;p&gt;A few things Annota does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sync operations are debounced for 10 seconds after the last edit to avoid excessive network requests.&lt;/li&gt;
&lt;li&gt;A safety timer forces a sync every 2 minutes during long editing sessions so changes don't remain local indefinitely.&lt;/li&gt;
&lt;li&gt;Deleted notes are tracked using tombstones, allowing deletions to propagate correctly across devices.&lt;/li&gt;
&lt;li&gt;File synchronization uses ID-based diffing so devices only download attachments they don't already have.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is simple: keep devices in sync without wasting bandwidth or battery.&lt;/p&gt;

&lt;p&gt;📖 Full write-up: &lt;a href="https://www.lirans.online/blog/annota-sync" rel="noopener noreferrer"&gt;Architecture Walkthrough: Annota Synchronization&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Public Notes
&lt;/h2&gt;

&lt;p&gt;One challenge I found particularly interesting was public sharing.&lt;/p&gt;

&lt;p&gt;If every note is encrypted, how do you allow users to publish selected notes to the web?&lt;/p&gt;

&lt;p&gt;The solution was to separate public content from the encrypted note store entirely.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Published notes are stored in a dedicated database table.&lt;/li&gt;
&lt;li&gt;Limits are enforced at the database level to prevent abuse.&lt;/li&gt;
&lt;li&gt;The web frontend accesses published content through a Supabase Edge Function rather than connecting directly to the database.&lt;/li&gt;
&lt;li&gt;Next.js ISR provides fast page loads, while webhooks immediately invalidate cached pages whenever a note is updated or unpublished.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows users to share public notes while keeping the core encrypted storage model intact.&lt;/p&gt;

&lt;p&gt;📖 Full write-up: &lt;a href="https://www.lirans.online/blog/annota-published-notes" rel="noopener noreferrer"&gt;Architecture Walkthrough: Annota Public Notes&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Hidden Performance Improvements
&lt;/h2&gt;

&lt;p&gt;I recently shifted focus from UI work to optimizing Annota's core engine for scale. The goal was simple: keep the app fast and efficient even with thousands of notes.&lt;br&gt;
Key improvements included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduced the mobile editor bundle by ~30% through dependency cleanup and lazy loading heavy features.&lt;/li&gt;
&lt;li&gt;Cut note saves from 6 database queries to just 3 by adding intelligent caching and change detection.&lt;/li&gt;
&lt;li&gt;Optimized task list handling to avoid unnecessary database updates when nothing changed.&lt;/li&gt;
&lt;li&gt;Eliminated dozens of redundant sync-related queries by batching operations and improving cache usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These changes may be invisible day-to-day, but they significantly reduce CPU usage, database overhead, and battery consumption as note collections grow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Building Annota has been a great opportunity to explore local-first architecture, synchronization challenges, and practical end-to-end encryption. I've learned a lot along the way, and there are still plenty of interesting problems left to solve.&lt;/p&gt;

&lt;p&gt;Right now, I am exploring how to securely integrate MCP (Model Context Protocol) Servers into the app. To protect the core privacy model, I already have a Bring-Your-Own-Key (BYOK) system where the local environment can strictly sandbox and expose only explicitly selected notes as context to the providers or local LLMs.&lt;/p&gt;

&lt;p&gt;If you're building something in the local-first, offline-first, or privacy-focused space, I'd be interested to hear how you've approached these challenges. Feedback, questions, and architecture discussions are always welcome. Thanks for reading !&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>opensource</category>
      <category>security</category>
    </item>
    <item>
      <title>I built a cross-platform, local-first note app with E2EE and BYOK AI (Tauri + Expo)</title>
      <dc:creator>Liran</dc:creator>
      <pubDate>Sat, 16 May 2026 19:13:21 +0000</pubDate>
      <link>https://dev.to/ilirans/i-built-a-cross-platform-local-first-note-app-with-e2ee-and-byok-ai-tauri-expo-1gmn</link>
      <guid>https://dev.to/ilirans/i-built-a-cross-platform-local-first-note-app-with-e2ee-and-byok-ai-tauri-expo-1gmn</guid>
      <description>&lt;p&gt;Hi, I've been working on a note taking app called &lt;strong&gt;&lt;a href="https://annota.online" rel="noopener noreferrer"&gt;Annota&lt;/a&gt;&lt;/strong&gt;. It started as a fun hobby project but I kept adding more and more features and it became a very refined product with many features.&lt;/p&gt;

&lt;p&gt;I’m building it as a monorepo, and I just released the &lt;a href="https://github.com/iLiranS/Annota/releases/latest" rel="noopener noreferrer"&gt;Windows&lt;/a&gt; .exe and an iOS/MacOS TestFlight beta. I'm looking for some early feedback from other developers before I try to launch it officially.&lt;br&gt;
It's also &lt;a href="https://github.com/iLiranS/Annota" rel="noopener noreferrer"&gt;open sourced&lt;/a&gt; if you want to check the code-base.&lt;/p&gt;

&lt;p&gt;Here is a quick look at the stack and the features :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Desktop (Windows &amp;amp; MacOS) : Tauri + React&lt;/li&gt;
&lt;li&gt;Mobile (iOS, Android soon) : React Native + Expo&lt;/li&gt;
&lt;li&gt;Local Database : SQLite with SQLCipher for local encryption&lt;/li&gt;
&lt;li&gt;Backend : Supabase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb3wznqmbzu4m4esc1ka.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb3wznqmbzu4m4esc1ka.webp" alt=" " width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Under The Hood: Security &amp;amp; Data
&lt;/h3&gt;

&lt;p&gt;Privacy is a big deal for me, so the architecture is designed around owning your data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local-First E2EE&lt;/strong&gt;: Your database is encrypted locally using SQLCipher. If you choose to use the upcoming cloud sync, your data is AES-256 encrypted locally before it ever leaves your device.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Optimization&lt;/strong&gt;: I implemented a double-hashing file duplication recognition system. If you copy-paste the same image or file multiple times, it only saves it once under the hood.&lt;/li&gt;
&lt;li&gt;FTS5 : Lightning-fast full-text search across all notes.&lt;/li&gt;
&lt;li&gt;Safety Net : Local version history for your notes, just in case you mess something up.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Editor
&lt;/h3&gt;

&lt;p&gt;I wanted an editor that could handle everything a dev throws at it without feeling bloated.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports Code blocks, Mermaid diagrams, and LaTeX.&lt;/li&gt;
&lt;li&gt;Custom components built-in, like Flashcards for studying.&lt;/li&gt;
&lt;li&gt;Fully customizable: tweak the fonts, sizing, spacing, and UI to your liking.&lt;/li&gt;
&lt;li&gt;Standard folder structure and tagging system for organization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7x8uz278y4erkwtwb284.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7x8uz278y4erkwtwb284.webp" alt=" " width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Integration (Ollama &amp;amp; BYOK)
&lt;/h3&gt;

&lt;p&gt;I didn't want to force users into a proprietary AI subscription.&lt;br&gt;
&lt;strong&gt;Local AI&lt;/strong&gt;: Full integration with Ollama so you can run models entirely locally.&lt;br&gt;
&lt;strong&gt;BYOK (Bring Your Own Key)&lt;/strong&gt;: Plug in your API keys for OpenAI, Anthropic, or Google.&lt;br&gt;
&lt;strong&gt;Clever Context&lt;/strong&gt;: The AI is token-minimized by default to save you money on API calls.&lt;br&gt;
&lt;strong&gt;Features&lt;/strong&gt;: You can chat with your notes, highlight text for a quick rewrite, ask questions about specific selections, and even toggle on web search or "thinking" modes for supported models.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;All the local features are 100% free.&lt;br&gt;
When I officially launch, the only thing that will cost money is the cloud sync (to cover server costs), but there will be a limited free tier for that as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out!
&lt;/h2&gt;

&lt;p&gt;I’d love for you to try it out and try to break it. I'm actively adding features and improving it day after day.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://www.annota.online" rel="noopener noreferrer"&gt;https://www.annota.online&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Windows Download: &lt;a href="https://github.com/iLiranS/Annota/releases/latest" rel="noopener noreferrer"&gt;Github Release&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Apple TestFlight: &lt;a href="https://testflight.apple.com/join/mmgSW44D" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
Thanks for your attention :)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>ai</category>
      <category>programming</category>
      <category>software</category>
    </item>
  </channel>
</rss>
