<?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: Upendra Dasanayaka</title>
    <description>The latest articles on DEV Community by Upendra Dasanayaka (@kingupe).</description>
    <link>https://dev.to/kingupe</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%2F4098390%2Fca8e7d01-e5f5-411a-aa16-1442b24f86cc.jpg</url>
      <title>DEV Community: Upendra Dasanayaka</title>
      <link>https://dev.to/kingupe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kingupe"/>
    <language>en</language>
    <item>
      <title>Why I Built an Ultra-Lightweight Rust &amp; Tauri Desktop Command Center for Developers</title>
      <dc:creator>Upendra Dasanayaka</dc:creator>
      <pubDate>Fri, 28 Aug 2026 07:34:08 +0000</pubDate>
      <link>https://dev.to/kingupe/why-i-built-an-ultra-lightweight-rust-tauri-desktop-command-center-for-developers-4ijp</link>
      <guid>https://dev.to/kingupe/why-i-built-an-ultra-lightweight-rust-tauri-desktop-command-center-for-developers-4ijp</guid>
      <description>&lt;p&gt;Ever spent 10 minutes debugging an error only to realize &lt;strong&gt;port 3000 was held hostage by a ghost Node.js process&lt;/strong&gt; you thought you killed an hour ago?&lt;br&gt;
Or opened your terminal and struggled to remember which nested subfolder you cloned a repository to last week?&lt;br&gt;
These daily developer friction points led me to build &lt;strong&gt;&lt;a href="https://github.com/KING-UPE/DevDeck" rel="noopener noreferrer"&gt;DevDeck&lt;/a&gt;&lt;/strong&gt; — a fast, open-source desktop command center designed to scan workspaces, run scripts, and kill ghost processes with a single click.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here is why I chose &lt;strong&gt;Rust + Tauri&lt;/strong&gt; over Electron and how the tool was architected.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  ⚡ 1. Why Not Electron? (The Resource Dilemma)
&lt;/h2&gt;

&lt;p&gt;Developer utilities like command centers, process inspectors, and launchers need to &lt;strong&gt;stay open in the background all day&lt;/strong&gt;.&lt;br&gt;
If built with Electron:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛑 &lt;strong&gt;RAM Usage:&lt;/strong&gt; 250MB – 450MB just to display a simple dashboard (shipping a full Chromium + Node runtime).&lt;/li&gt;
&lt;li&gt;🛑 &lt;strong&gt;Binary Size:&lt;/strong&gt; 80MB+ installer.
By building with &lt;strong&gt;Tauri + Rust&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;RAM Usage:&lt;/strong&gt; ~20MB – 35MB idle (using native OS WebViews: WebView2 on Windows, WebKitGTK on Linux, WKWebView on macOS).&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Binary Size:&lt;/strong&gt; Under 10MB installer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  * 🚀 &lt;strong&gt;Native OS Access:&lt;/strong&gt; Direct access to system processes, PIDs, and disk scans via compiled Rust binaries.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🛠️ 2. Core Features &amp;amp; Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A. Instant Workspace Scanner (&lt;code&gt;ignore&lt;/code&gt; &amp;amp; &lt;code&gt;walkdir&lt;/code&gt; in Rust)
&lt;/h3&gt;

&lt;p&gt;DevDeck indexes your projects across multiple drives without lag. Instead of running a heavy recursive JavaScript scan, we delegate filesystem traversal to Rust using the &lt;code&gt;ignore&lt;/code&gt; crate (respecting &lt;code&gt;.gitignore&lt;/code&gt; and skipping &lt;code&gt;node_modules&lt;/code&gt; / &lt;code&gt;.git&lt;/code&gt; folders):&lt;/p&gt;

&lt;p&gt;` use std::path::Path;&lt;br&gt;
use ignore::WalkBuilder;&lt;br&gt;
use serde::Serialize;&lt;/p&gt;

&lt;p&gt;pub struct ProjectMetadata {&lt;br&gt;
    pub name: String,&lt;br&gt;
    pub path: String,&lt;br&gt;
    pub project_type: String, // "Node", "Rust", "Python", etc.&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;pub fn scan_workspace(root_dir: String) -&amp;gt; Vec {&lt;br&gt;
    let mut projects = Vec::new();&lt;br&gt;
    for result in WalkBuilder::new(&amp;amp;root_dir).max_depth(Some(4)).build() {&lt;br&gt;
        if let Ok(entry) = result {&lt;br&gt;
            let path = entry.path();&lt;br&gt;
            if path.file_name() == Some(std::ffi::OsStr::new("package.json")) {&lt;br&gt;
                projects.push(ProjectMetadata {&lt;br&gt;
                    name: entry.path().parent().unwrap().file_name().unwrap().to_string_lossy().into(),&lt;br&gt;
                    path: entry.path().parent().unwrap().to_string_lossy().into(),&lt;br&gt;
                    project_type: "Node.js".into(),&lt;br&gt;
                });&lt;br&gt;
            }&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
    projects&lt;br&gt;
} `&lt;/p&gt;

&lt;h3&gt;
  
  
  B. One-Click Ghost Process Killer
&lt;/h3&gt;

&lt;p&gt;When port 3000, 5173, or 8080 is blocked, finding and terminating the process via terminal commands (netstat, lsof -i, kill -9) interrupts your flow.&lt;/p&gt;

&lt;p&gt;In DevDeck, the Rust backend queries listening sockets and exposes a 1-click kill function:&lt;/p&gt;

&lt;p&gt;`rust&lt;/p&gt;

&lt;p&gt;use sysinfo::{Pid, ProcessExt, System, SystemExt};&lt;/p&gt;

&lt;p&gt;pub fn kill_process_by_pid(pid: usize) -&amp;gt; bool {&lt;br&gt;
    let mut sys = System::new_all();&lt;br&gt;
    sys.refresh_all();&lt;br&gt;
    if let Some(process) = sys.process(Pid::from(pid)) {&lt;br&gt;
        return process.kill();&lt;br&gt;
    }&lt;br&gt;
    false&lt;br&gt;
}`&lt;/p&gt;

&lt;h3&gt;
  
  
  C. Live Script Runner with Real-Time Output Streaming
&lt;/h3&gt;

&lt;p&gt;DevDeck parses package.json scripts and Cargo.toml targets, letting you execute commands and stream stdout/stderr live to a unified terminal pane inside the app using Tauri event emitters.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎨 3. The Frontend: Zero-Bloat Glassmorphism
&lt;/h2&gt;

&lt;p&gt;To keep DevDeck blazing fast, the UI was crafted using Vanilla HTML, CSS (Glassmorphism), and modern JavaScript with zero heavy framework overhead. The interface stays buttery smooth while drawing negligible CPU resources in the background.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 4. Cross-Platform &amp;amp; Open Source
&lt;/h2&gt;

&lt;p&gt;DevDeck is 100% open-source and natively built for Windows, macOS, and Linux.&lt;/p&gt;

&lt;p&gt;🌐 Download &amp;amp; Release Assets: &lt;a href="https://king-upe.github.io/DevDeck/download.html" rel="noopener noreferrer"&gt;Download DevDeck&lt;/a&gt;&lt;br&gt;
💻 Source Code: &lt;a href="https://github.com/KING-UPE/DevDeck" rel="noopener noreferrer"&gt;github.com/KING-UPE/DevDeck&lt;/a&gt;&lt;br&gt;
👨‍💻 Author &amp;amp; Portfolio: &lt;a href="https://upendradasanayaka.vercel.app/" rel="noopener noreferrer"&gt;Upendra Dasanayaka&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What features would make your development workflow faster? Let me know in the comments or contribute on GitHub! US THIS PERFECTLY OUTOUTED?&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>productivity</category>
      <category>rust</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How I Built a Zero-Install, Multi-Gigabyte P2P File Transfer Engine in the Browser with WebRTC &amp; File System Access API</title>
      <dc:creator>Upendra Dasanayaka</dc:creator>
      <pubDate>Fri, 28 Aug 2026 07:23:44 +0000</pubDate>
      <link>https://dev.to/kingupe/how-i-built-a-zero-install-multi-gigabyte-p2p-file-transfer-engine-in-the-browser-with-webrtc--1doe</link>
      <guid>https://dev.to/kingupe/how-i-built-a-zero-install-multi-gigabyte-p2p-file-transfer-engine-in-the-browser-with-webrtc--1doe</guid>
      <description>&lt;p&gt;Ever tried sending a &lt;strong&gt;15GB 4K video file or a raw dataset&lt;/strong&gt; to a teammate sitting at the next desk?&lt;/p&gt;

&lt;p&gt;The options are surprisingly clunky:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hunt for a physical USB flash drive.&lt;/li&gt;
&lt;li&gt;Upload it to Google Drive, Dropbox, or Slack (wasting your internet bandwidth, hitting upload limits, and waiting for compression) only for your coworker to spend another 20 minutes downloading it back over the same local network.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted to fix this with a zero-friction experience: &lt;strong&gt;no desktop client installation, no cloud storage limits, and full local network transfer speed directly inside the browser.&lt;/strong&gt;&lt;br&gt;
That led me to build &lt;strong&gt;&lt;a href="https://fluxbykingupe.vercel.app/" rel="noopener noreferrer"&gt;FluX&lt;/a&gt;&lt;/strong&gt; — an open-source, peer-to-peer (P2P) file sharing tool running entirely over WebRTC and modern browser streaming APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here is an architectural deep dive into how FluX streams multi-gigabyte files directly between machines without crashing browser memory.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🏗️ 1. High-Level Architecture: How FluX Works FluX uses a hybrid model:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Signaling Server (Node.js + Socket.io):&lt;/strong&gt; Coordinates peer discovery and exchange of SDP (Session Description Protocol) offers, answers, and ICE candidates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct P2P Data Channel (WebRTC SCTP/DTLS):&lt;/strong&gt; Once the handshake completes, all file bytes travel directly peer-to-peer over the local router/LAN, bypassing the server entirely.
[ Sender Browser ] [ Receiver Browser ] | | |--- 1. SDP Offer &amp;amp; ICE Candidates (via Socket.io) -&amp;gt;| |&amp;lt;-- 2. SDP Answer &amp;amp; ICE Candidates (via Socket.io) -| | | |======= 3. Direct WebRTC Data Channel (LAN) =======&amp;gt;| | [SCTP Chunks -&amp;gt; File System Access API] |&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  ⚡ 2. Solving the 3 Hardest Browser Engineering Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge A: Bypassing the Browser RAM Crash (Direct-to-Disk Streaming)
&lt;/h3&gt;

&lt;p&gt;Traditional browser file downloads build an in-memory &lt;code&gt;Blob&lt;/code&gt; or &lt;code&gt;ArrayBuffer&lt;/code&gt; before triggering a download link. If you transfer a 10GB file, the browser tab consumes 10GB+ of RAM and instantly crashes with an &lt;code&gt;Out of Memory&lt;/code&gt; (OOM) error.&lt;br&gt;
&lt;strong&gt;The Solution:&lt;/strong&gt; The &lt;strong&gt;File System Access API&lt;/strong&gt; (&lt;code&gt;showSaveFilePicker&lt;/code&gt;).&lt;br&gt;
Instead of holding chunks in memory:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The receiver selects a destination file handle on disk.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;FileSystemWritableFileStream&lt;/code&gt; is created.&lt;/li&gt;
&lt;li&gt;Incoming binary chunks from the WebRTC Data Channel are piped directly into disk storage in real time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;javascript&lt;br&gt;
// Request destination file handle from user&lt;br&gt;
const fileHandle = await window.showSaveFilePicker({&lt;br&gt;
  suggestedName: incomingMetadata.name,&lt;br&gt;
});&lt;br&gt;
const writableStream = await fileHandle.createWritable();&lt;br&gt;
// Write incoming WebRTC chunk directly to disk&lt;br&gt;
dataChannel.onmessage = async (event) =&amp;gt; {&lt;br&gt;
  if (event.data instanceof ArrayBuffer) {&lt;br&gt;
    await writableStream.write(event.data);&lt;br&gt;
  } else if (event.data === "TRANSFER_COMPLETE") {&lt;br&gt;
    await writableStream.close();&lt;br&gt;
    console.log("File saved directly to disk!");&lt;br&gt;
  }&lt;br&gt;
};&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge B: Smart Backpressure Management (bufferedAmount)
&lt;/h3&gt;

&lt;p&gt;WebRTC Data Channels have an internal buffer queue. If your disk or local network sends faster than the channel can flush, RTCDataChannel.bufferedAmount skyrockets, leading to packet drops or crashed tabs.&lt;/p&gt;

&lt;p&gt;The Solution: Custom Backpressure Queue.&lt;/p&gt;

&lt;p&gt;We monitor dataChannel.bufferedAmount and pause chunk slicing whenever the buffer exceeds a high-water mark (e.g., 8MB), resuming only when bufferedamountlow fires:&lt;/p&gt;

&lt;p&gt;javascript&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const CHUNK_SIZE = 64 * 1024; // 64 KB per chunk&lt;br&gt;
const BUFFER_THRESHOLD = 8 * 1024 * 1024; // 8 MB high watermark&lt;br&gt;
dataChannel.bufferedAmountLowThreshold = 1 * 1024 * 1024; // 1 MB low watermark&lt;br&gt;
async function sendFile(file, dataChannel) {&lt;br&gt;
  let offset = 0;&lt;br&gt;
  while (offset &amp;lt; file.size) {&lt;br&gt;
    // Check if buffer is backed up&lt;br&gt;
    if (dataChannel.bufferedAmount &amp;gt; BUFFER_THRESHOLD) {&lt;br&gt;
      await new Promise((resolve) =&amp;gt; {&lt;br&gt;
        dataChannel.onbufferedamountlow = () =&amp;gt; {&lt;br&gt;
          dataChannel.onbufferedamountlow = null;&lt;br&gt;
          resolve();&lt;br&gt;
        };&lt;br&gt;
      });[](url)&lt;br&gt;
    }&lt;br&gt;
    const chunk = file.slice(offset, offset + CHUNK_SIZE);&lt;br&gt;
    const buffer = await chunk.arrayBuffer();&lt;br&gt;
    dataChannel.send(buffer);&lt;br&gt;
    offset += CHUNK_SIZE;&lt;br&gt;
  }&lt;br&gt;
  dataChannel.send("TRANSFER_COMPLETE");&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge C: Non-Blocking UI with Web Workers
&lt;/h3&gt;

&lt;p&gt;Calculating cryptographic checksums (SHA-256) and slicing massive files can freeze the React render thread. We offloaded hashing and file chunking into dedicated Web Workers, keeping the Framer Motion animations smooth at 60 FPS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ The Tech Stack&lt;/strong&gt;&lt;br&gt;
Frontend: React 18, Zustand (Atomic state management), Framer Motion, Tailwind CSS.&lt;br&gt;
Protocols: WebRTC (SCTP/DTLS Data Channels), WebSockets (Socket.io).&lt;br&gt;
Browser APIs: File System Access API, Web Workers, Blob slicing.&lt;br&gt;
Signaling Backend: Node.js, Express, Socket.io (Stateless signaling).&lt;/p&gt;

&lt;p&gt;🚀 Try It Out &amp;amp; Source Code&lt;br&gt;
🌐 Live Demo: &lt;a href="//fluxbykingupe.vercel.app"&gt;fluxbykingupe.vercel.app&lt;/a&gt;&lt;br&gt;
💻 GitHub Repository: &lt;a href="//github.com/KING-UPE/FluX"&gt;github.com/KING-UPE/FluX&lt;/a&gt;&lt;br&gt;
👨‍💻 Portfolio &amp;amp; Contact: &lt;a href="https://upendradasanayaka.vercel.app/" rel="noopener noreferrer"&gt;Upendra Dasanayaka&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have feedback or ideas on improving WebRTC throughput? Feel free to drop a comment or open an issue on GitHub!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>webrtc</category>
      <category>react</category>
    </item>
  </channel>
</rss>
