<?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: Steven Hans</title>
    <description>The latest articles on DEV Community by Steven Hans (@steven_hans_b26a962c69563).</description>
    <link>https://dev.to/steven_hans_b26a962c69563</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3764453%2Fcb5322f8-a986-49af-8539-78b3705b3093.jpg</url>
      <title>DEV Community: Steven Hans</title>
      <link>https://dev.to/steven_hans_b26a962c69563</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/steven_hans_b26a962c69563"/>
    <language>en</language>
    <item>
      <title>NoamVC v0.3 — We deleted 3,500 lines and the app got better</title>
      <dc:creator>Steven Hans</dc:creator>
      <pubDate>Tue, 17 Feb 2026 20:34:00 +0000</pubDate>
      <link>https://dev.to/steven_hans_b26a962c69563/noamvc-v03-we-deleted-3500-lines-and-the-app-got-better-4nlb</link>
      <guid>https://dev.to/steven_hans_b26a962c69563/noamvc-v03-we-deleted-3500-lines-and-the-app-got-better-4nlb</guid>
      <description>&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%2Fe539cqpqnw2rbzv6vd8t.png" 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%2Fe539cqpqnw2rbzv6vd8t.png" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎙️ What is NoamVC?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NoamVC&lt;/strong&gt; is a &lt;strong&gt;peer-to-peer&lt;/strong&gt; encrypted voice chat desktop app — think Discord, but your voice never touches a server. Audio travels directly between participants via WebRTC with end-to-end encryption.&lt;/p&gt;

&lt;p&gt;Built with &lt;strong&gt;Tauri 2&lt;/strong&gt; (Rust) + &lt;strong&gt;React 19&lt;/strong&gt; + &lt;strong&gt;TypeScript&lt;/strong&gt;. Available for macOS (ARM + Intel) and Windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR of the security model:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P2P audio via &lt;code&gt;RTCPeerConnection&lt;/code&gt; — zero server-side processing&lt;/li&gt;
&lt;li&gt;E2E encryption with Insertable Streams + PBKDF2 (256-bit key, 100K SHA-256 iterations)&lt;/li&gt;
&lt;li&gt;HMAC-SHA256 signed signaling — secret embedded in Rust binary, never touches JS&lt;/li&gt;
&lt;li&gt;Secure storage with IOTA Stronghold — nothing in localStorage&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🆕 What's new in v0.2.1 → v0.3.3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 🚪 Room Admission System (v0.3.0)
&lt;/h3&gt;

&lt;p&gt;The biggest feature in this cycle. Previously, anyone with the room code could join silently. Now the &lt;strong&gt;room creator&lt;/strong&gt; acts as host and must approve every join request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New user → knock → Host sees dialog → Admit / Deny
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first user to enter a room automatically becomes the &lt;strong&gt;host&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Subsequent participants enter a "waiting" state until explicitly admitted.&lt;/li&gt;
&lt;li&gt;The host sees a dialog with the requester's name and avatar, plus admit/deny buttons.&lt;/li&gt;
&lt;li&gt;Denied users get a clear message and return to the lobby.&lt;/li&gt;
&lt;li&gt;Fully managed at the signaling level — &lt;strong&gt;zero changes&lt;/strong&gt; to the WebRTC connection flow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a significant UX and security improvement. In the previous model, knowing the room code was equivalent to being inside. Now there's a human gatekeeper.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 🐛 In-App Bug Reports → Firestore (v0.2.1)
&lt;/h3&gt;

&lt;p&gt;Users can report bugs without leaving the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BugCategory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;audio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;other&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Form with title, description, and category selector.&lt;/li&gt;
&lt;li&gt;Real-time validation (title ≥ 3 chars, description ≥ 10 chars).&lt;/li&gt;
&lt;li&gt;Sent to &lt;strong&gt;Firestore&lt;/strong&gt; via REST API — no heavy Firebase SDK bundled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy-loaded&lt;/strong&gt;: Firebase code doesn't load until the user opens the dialog.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interesting part security-wise: the Firebase API key is embedded in the &lt;strong&gt;Rust binary&lt;/strong&gt; at compile time. It never appears in the JavaScript bundle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FIREBASE_API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FIREBASE_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nd"&gt;#[tauri::command]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_firebase_api_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FIREBASE_API_KEY&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JS side calls this Tauri command on demand, so the key only exists in the Rust binary and only flows to the frontend when needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 🗑️ Embedded Server Removal — The -3,546 LOC Delete (v0.3.1)
&lt;/h3&gt;

&lt;p&gt;Previous versions of NoamVC bundled an embedded signaling server in the Tauri binary (Axum + Socketioxide) for local/LAN development. We &lt;strong&gt;nuked it entirely&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What was removed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Axum, Socketioxide, tower, and all related Rust dependencies from the desktop app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-3,546 lines&lt;/strong&gt; of code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What replaced it:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The signaling server is now a &lt;strong&gt;standalone Rust service&lt;/strong&gt; (Axum + Socketioxide) deployed on Railway. Same tech, separate repo, clean boundary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The embedded server added ~30s of extra compile time.&lt;/li&gt;
&lt;li&gt;It confused developers about which server was active.&lt;/li&gt;
&lt;li&gt;Nobody used it for LAN in practice.&lt;/li&gt;
&lt;li&gt;Removing it shrinks the binary and reduces the attack surface.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The best code is the code you don't have. &lt;strong&gt;- Someone wise&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. 🔧 Duplicate Peers Fix (v0.3.1)
&lt;/h3&gt;

&lt;p&gt;A subtle race condition: under certain reconnection scenarios, the same peer could appear twice in the participant list. Root cause was the de-duplication logic in the WebRTC hook not accounting for rapid disconnect/reconnect cycles. Fixed with proper peer identity tracking.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. 🔒 CSP Update for Firestore (v0.3.2)
&lt;/h3&gt;

&lt;p&gt;After adding bug reports, Tauri's Content Security Policy was silently blocking requests to Firestore. The fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"connect-src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"... https://firestore.googleapis.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Small change, but a reminder: &lt;strong&gt;Tauri's CSP is strict by default&lt;/strong&gt; (which is good), and every new external endpoint requires explicit allowlisting.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. 🏗️ The CI/CD Bug That Took 3 Releases to Fix (v0.3.2 → v0.3.3)
&lt;/h3&gt;

&lt;p&gt;This one was frustrating. The &lt;code&gt;build.rs&lt;/code&gt; script loaded env vars from &lt;code&gt;.env&lt;/code&gt; for local builds, but in &lt;strong&gt;GitHub Actions&lt;/strong&gt; the variables were in the OS environment and &lt;strong&gt;weren't being forwarded to &lt;code&gt;rustc&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The error:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error: environment variable `FIREBASE_API_KEY` not defined at compile time
 --&amp;gt; src\desktop.rs:11:32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt; — explicitly forward OS env vars to the Rust compiler in &lt;code&gt;build.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cargo:rustc-env={}={}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus the workflow secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;FIREBASE_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FIREBASE_API_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key takeaway for Tauri/Rust devs:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;env!()&lt;/code&gt; reads variables that &lt;strong&gt;Cargo&lt;/strong&gt; knows about, not the shell environment directly. If your CI sets env vars in the usual way, you need &lt;code&gt;cargo:rustc-env&lt;/code&gt; in &lt;code&gt;build.rs&lt;/code&gt; to bridge that gap. This isn't documented prominently and bit us hard.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Numbers for this cycle
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Commits&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files changed&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lines added&lt;/td&gt;
&lt;td&gt;~1,222&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lines deleted&lt;/td&gt;
&lt;td&gt;~4,768&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Net&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;-3,546 lines&lt;/strong&gt; ✂️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We deleted &lt;strong&gt;3.9x more code&lt;/strong&gt; than we wrote. The best kind of release.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19, TypeScript 5.9, Vite 7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styles&lt;/td&gt;
&lt;td&gt;Tailwind CSS 4, shadcn/ui&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Desktop&lt;/td&gt;
&lt;td&gt;Tauri 2 (Rust backend)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signaling&lt;/td&gt;
&lt;td&gt;Rust (Axum + Socketioxide) → Railway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;Insertable Streams + PBKDF2, HMAC-SHA256&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;IOTA Stronghold&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;GitHub Actions → auto draft release&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bug Reports&lt;/td&gt;
&lt;td&gt;Firestore REST API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔜 What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Push-to-talk&lt;/strong&gt; — alternative mode for noisy environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-peer connection quality indicators&lt;/strong&gt; — RTT, packet loss, jitter visualized per participant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BLE data transmission&lt;/strong&gt; — exploring Bluetooth Low Energy as an alternative signaling channel for ultra-local, serverless room setup between nearby devices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux support&lt;/strong&gt; — AppImage / .deb packages&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Landing&lt;/strong&gt;: &lt;a href="https://noamvc.web.app" rel="noopener noreferrer"&gt;noamvc.web.app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;NoamVC is under active development. If you're working with WebRTC, Tauri, or applied cryptography — or just want a voice chat that doesn't route your audio through someone else's server — give it a look. Feedback and contributions welcome.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webrtc</category>
      <category>rust</category>
      <category>tauri</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🚀 Testing NoamVC from Robinson Crusoe Island</title>
      <dc:creator>Steven Hans</dc:creator>
      <pubDate>Fri, 13 Feb 2026 01:43:13 +0000</pubDate>
      <link>https://dev.to/steven_hans_b26a962c69563/testing-noamvc-from-robinson-crusoe-island-k67</link>
      <guid>https://dev.to/steven_hans_b26a962c69563/testing-noamvc-from-robinson-crusoe-island-k67</guid>
      <description>&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%2Fk4arv21qf6fykkou94bv.png" 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%2Fk4arv21qf6fykkou94bv.png" alt=" " width="800" height="827"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yesterday we did something epic: we tested NoamVC from one of the most remote places in Chile, and the results were incredible!&lt;br&gt;
Despite being literally off the mainland, we managed to maintain super smooth communication. Yes, at first Starlink played a trick on us with some satellite synchronization issues (classic for such remote locations), but once it stabilized: decent latency, crystal-clear audio, and a stable connection 👌🏻&lt;/p&gt;

&lt;p&gt;We got valuable feedback: we need an integrated chat to share links and messages instantly, without switching between apps. We're already working on it!&lt;/p&gt;

&lt;p&gt;Want to try it yourself?&lt;/p&gt;

&lt;p&gt;Download NoamVC now, free for life, and tell us about your experience. We want to know how it works in YOUR location, with YOUR connection, under YOUR real-world conditions.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://noamvc.web.app" rel="noopener noreferrer"&gt;https://noamvc.web.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your feedback helps us improve. Let's create the best video calling tool together! 🎯&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🎙️ I built a voice chat app because I wanted to talk to my son while we play online</title>
      <dc:creator>Steven Hans</dc:creator>
      <pubDate>Tue, 10 Feb 2026 14:10:29 +0000</pubDate>
      <link>https://dev.to/steven_hans_b26a962c69563/i-built-a-voice-chat-app-because-i-wanted-to-talk-to-my-son-while-we-play-online-188h</link>
      <guid>https://dev.to/steven_hans_b26a962c69563/i-built-a-voice-chat-app-because-i-wanted-to-talk-to-my-son-while-we-play-online-188h</guid>
      <description>&lt;p&gt;It all started with something simple: my son and I wanted to communicate while playing online together. I tried the existing options — Discord, TeamSpeak, and others — but something always bothered me: ads, data collection, cluttered interfaces, or mediocre audio quality. I just wanted something secure, private, with good audio quality, and free. So I decided to build it myself.&lt;/p&gt;

&lt;p&gt;The result is NoamVC: an open source, peer-to-peer voice chat application with end-to-end encryption.&lt;/p&gt;

&lt;p&gt;What makes it technically different?&lt;br&gt;
🔊 Direct audio, no middlemen&lt;br&gt;
Voice travels directly between participants using native WebRTC — no server processes or stores audio. The server only coordinates the initial connection (signaling).&lt;/p&gt;

&lt;p&gt;🔒 Multi-layered security&lt;/p&gt;

&lt;p&gt;E2E encryption with Insertable Streams API + 256-byte key derived via PBKDF2 (100K iterations, SHA-256)&lt;br&gt;
Signaling signed with HMAC-SHA256, with secret embedded in Rust — never exposed to JavaScript&lt;br&gt;
Anti-replay protection with a 5-minute window&lt;br&gt;
Storage in an encrypted IOTA Stronghold vault — zero data in localStorage&lt;br&gt;
🎧 Optimized Opus codec&lt;br&gt;
32 kbps, mono, with Forward Error Correction (FEC), Discontinuous Transmission (DTX), and 20 ms frames. Minimum bandwidth consumption with maximum clarity.&lt;/p&gt;

&lt;p&gt;🖥️ Native desktop app&lt;br&gt;
Built with Tauri 2 (Rust) for macOS (Apple Silicon + Intel), Windows, and Linux. It's not a heavy Electron app — it's a real native app, lightweight and signed.&lt;/p&gt;

&lt;p&gt;⚡ Modern stack&lt;br&gt;
React 19 · TypeScript 5.9 · Vite 7 · Tailwind CSS 4 · NestJS 11 · Zustand · shadcn/ui&lt;/p&gt;

&lt;p&gt;🎨 Polished design&lt;br&gt;
Dark theme with reactive animated backgrounds that respond when someone speaks: SVG waves, equalizer bars, floating particles, and pulse rings. Real-time speech detection with FFT-256 analyzer. Latency indicator with live RTT.&lt;/p&gt;

&lt;p&gt;🌐 Bilingual&lt;br&gt;
Interface in Spanish and English with automatic system language detection.&lt;/p&gt;

&lt;p&gt;This was definitely a project I really enjoyed building. I gained a ton of learning along the way. I hope you find it useful and that you're encouraged to leave your feedback so I can keep improving it.&lt;/p&gt;

&lt;p&gt;🔗 Project: &lt;a href="https://noamvc.web.app/" rel="noopener noreferrer"&gt;https://noamvc.web.app/&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  OpenSource #WebRTC #Tauri #React #Rust #TypeScript #VoiceChat #P2P #Encryption #DevDad #BuildInPublic
&lt;/h1&gt;

</description>
      <category>opensource</category>
      <category>privacy</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
