<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged tauri</title>
<link>https://coderlegion.com/tag/tauri</link>
<description>Powered by Question2Answer</description>
<item>
<title>I built a CLI to test Tauri apps because nothing else worked</title>
<link>https://coderlegion.com/15384/i-built-a-cli-to-test-tauri-apps-because-nothing-else-worked</link>
<description>&lt;p&gt;I spent a weekend trying to set up end-to-end testing for a Tauri v2 app. Two hours into configuring WebdriverIO, I still couldn't get it to connect to the WebView. The official docs show a minimal example that doesn't cover IPC testing. Playwright flat-out doesn't work because Tauri uses WebKitGTK, not Chromium.&lt;/p&gt;
&lt;p&gt;I gave up and wrote my own tool.&lt;/p&gt;
&lt;h3 id=&quot;the-actual-problem&quot;&gt;The actual problem&lt;/h3&gt;
&lt;p&gt;If you search &quot;Tauri e2e testing&quot; on GitHub, you'll find the same question asked over and over. The &lt;a rel=&quot;nofollow&quot; href=&quot;https://v2.tauri.app/develop/tests/&quot;&gt;official docs&lt;/a&gt; split testing into two worlds: Rust unit tests for the backend, and WebDriver-based tests for the frontend. But nobody tells you how to verify that your Tauri IPC commands actually work from the user's perspective. You end up mocking &lt;code&gt;window.__TAURI__&lt;/code&gt; in your frontend tests and hoping production behaves the same way.&lt;/p&gt;
&lt;p&gt;It doesn't always behave the same way.&lt;/p&gt;
&lt;p&gt;What I wanted was simple: connect to a running Tauri app, inspect the UI, click buttons, fill forms, and check that things happened. Like Playwright, but for Tauri. No WebDriver binary. No Selenium. No 200-line config file.&lt;/p&gt;
&lt;h3 id=&quot;what-tauri-pilot-does&quot;&gt;What tauri-pilot does&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mpiton/tauri-pilot&quot;&gt;tauri-pilot&lt;/a&gt; is a Rust CLI that talks to your Tauri app over a Unix socket. You add a plugin to your app (2 lines, debug builds only), install the CLI, and start testing.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tauri-pilot snapshot -i
- heading &quot;PR Dashboard&quot; [ref=e1]
- textbox &quot;Search PRs&quot; [ref=e2] value=&quot;&quot;
- button &quot;Refresh&quot; [ref=e3]
- list &quot;PR List&quot; [ref=e4]
  - listitem &quot;fix: resolve memory leak #142&quot; [ref=e5]
  - listitem &quot;feat: add workspace support #138&quot; [ref=e6]
- button &quot;Load More&quot; [ref=e7]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;code&gt;snapshot&lt;/code&gt; command walks the accessibility tree and gives every interactive element a short ref like &lt;code&gt;@e3&lt;/code&gt;. You use those refs to interact:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tauri-pilot click @e3
ok

$ tauri-pilot fill @e2 &quot;workspace&quot;
ok

$ tauri-pilot assert text @e1 &quot;PR Dashboard&quot;
ok

$ tauri-pilot assert visible @e7
ok
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Exit code 0 means pass. Exit code 1 means fail with a message. That's it. No test framework to learn.&lt;/p&gt;
&lt;h3 id=&quot;setup-takes-2-minutes&quot;&gt;Setup takes 2 minutes&lt;/h3&gt;
&lt;p&gt;Add the plugin to your Tauri app:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;// src-tauri/src/main.rs
fn main() {
    let mut builder = tauri::Builder::default();

    #[cfg(debug_assertions)]
    {
        builder = builder.plugin(tauri_plugin_pilot::init());
    }

    builder.run(tauri::generate_context!()).expect(&quot;error running app&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install the CLI:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo install tauri-pilot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run your app in dev mode. That's it. &lt;code&gt;tauri-pilot ping&lt;/code&gt; should respond.&lt;/p&gt;
&lt;p&gt;The plugin only compiles in debug builds. It won't end up in your release binary.&lt;/p&gt;
&lt;h3 id=&quot;why-not-just-use-webdriverio-&quot;&gt;Why not just use WebdriverIO?&lt;/h3&gt;
&lt;p&gt;I tried. Here's what the experience looks like:&lt;/p&gt;
&lt;p&gt;With WebdriverIO, you need to install Node.js dependencies, configure &lt;code&gt;wdio.conf.ts&lt;/code&gt;, point it at your built binary (not the dev server), make sure the WebDriver binary matches your WebKit version, write tests in JavaScript even though your app is in Rust, and deal with flaky selectors that break when your UI changes.&lt;/p&gt;
&lt;p&gt;With tauri-pilot, you run &lt;code&gt;cargo install tauri-pilot&lt;/code&gt;, add 2 lines to your app, and start writing shell commands. The accessibility tree refs (&lt;code&gt;@e1&lt;/code&gt;, &lt;code&gt;@e2&lt;/code&gt;) are stable across renders as long as the element exists. You can use CSS selectors too, or pixel coordinates for edge cases.&lt;/p&gt;
&lt;p&gt;The diff command is something WebdriverIO can't do at all:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tauri-pilot diff -i
+ button &quot;New PR&quot; [ref=e8]
~ list &quot;PR List&quot; [ref=e4]: children 2 → 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It compares the current UI state to the previous snapshot and shows only what changed. When you're debugging a UI issue, that's worth more than any assertion framework.&lt;/p&gt;
&lt;h3 id=&quot;it-s-built-for-ai-agents&quot;&gt;It's built for AI agents&lt;/h3&gt;
&lt;p&gt;I initially built tauri-pilot so Claude Code could interact with my Tauri apps. The output format is designed for LLM consumption: compact accessibility tree, short refs, plain text responses.&lt;/p&gt;
&lt;p&gt;An AI agent's workflow looks like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;snapshot -i&lt;/code&gt; to understand the current page&lt;/li&gt;
&lt;li&gt;Pick a ref from the output and interact with it&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assert&lt;/code&gt; to verify the result&lt;/li&gt;
&lt;li&gt;&lt;code&gt;diff -i&lt;/code&gt; to see what changed without re-reading the entire tree (saves tokens)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code&gt;--json&lt;/code&gt; flag on every command gives structured output for programmatic use.&lt;/p&gt;
&lt;p&gt;But you don't need an AI agent to benefit from this. I use tauri-pilot directly in bash scripts and interactively while developing. It's faster than clicking through the UI manually when I'm testing a form flow for the fifth time.&lt;/p&gt;
&lt;h3 id=&quot;what-s-in-v0-2-0&quot;&gt;What's in v0.2.0&lt;/h3&gt;
&lt;p&gt;The latest release (just shipped) adds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Record/replay&lt;/strong&gt; — &lt;code&gt;tauri-pilot record start&lt;/code&gt;, interact with your app, &lt;code&gt;record stop --output test.json&lt;/code&gt;, then &lt;code&gt;replay test.json&lt;/code&gt; to rerun the whole session. Export to a shell script with &lt;code&gt;replay --export sh&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-window support&lt;/strong&gt; — &lt;code&gt;windows&lt;/code&gt; lists all windows, &lt;code&gt;--window&lt;/code&gt; flag targets a specific one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Form dump&lt;/strong&gt; — &lt;code&gt;forms&lt;/code&gt; grabs all form fields at once instead of calling &lt;code&gt;value&lt;/code&gt; on each input.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;localStorage/sessionStorage access&lt;/strong&gt; — &lt;code&gt;storage get &quot;token&quot;&lt;/code&gt;, &lt;code&gt;storage set &quot;key&quot; &quot;value&quot;&lt;/code&gt;, &lt;code&gt;storage list&lt;/code&gt;, &lt;code&gt;storage clear&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Drag &amp;amp; drop&lt;/strong&gt; — &lt;code&gt;drag @e5 @e6&lt;/code&gt; for sortable lists, &lt;code&gt;drop @e3 --file ./image.png&lt;/code&gt; for file upload zones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DOM watch&lt;/strong&gt; — &lt;code&gt;watch&lt;/code&gt; blocks until a DOM mutation happens, then prints a summary. Good for waiting on async updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The full changelog is on &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mpiton/tauri-pilot/blob/main/CHANGELOG.md&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;how-it-works-under-the-hood&quot;&gt;How it works under the hood&lt;/h3&gt;
&lt;p&gt;The plugin starts a Unix socket server when your app launches. The CLI connects to that socket and sends JSON-RPC messages. The plugin injects a JS bridge (&lt;code&gt;window.__PILOT__&lt;/code&gt;) into the WebView that handles DOM inspection.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/pntlvzI.jpeg&quot; alt=&quot;tauri-pilot architecture diagram&quot;&gt;&lt;/p&gt;
&lt;p&gt;The tricky part was getting return values from &lt;code&gt;webview.eval()&lt;/code&gt;. In Tauri v2, &lt;code&gt;eval()&lt;/code&gt; is fire-and-forget. There's no way to get a result back directly. So every JS evaluation wraps the script in a try/catch, calls back into Rust via IPC (&lt;code&gt;invoke('plugin:pilot|__callback', {id, result})&lt;/code&gt;), and the Rust side waits on a oneshot channel with a 10-second timeout.&lt;/p&gt;
&lt;p&gt;It works reliably. I've been running it daily for weeks.&lt;/p&gt;
&lt;h3 id=&quot;limitations&quot;&gt;Limitations&lt;/h3&gt;
&lt;p&gt;Linux only for now. Tauri uses WebKitGTK on Linux, WKWebView on macOS, and WebView2 on Windows. The socket and JS bridge approach should work on all platforms, but I haven't tested it. macOS and Windows support is planned.&lt;/p&gt;
&lt;p&gt;The screenshot command uses html-to-image bundled into the JS bridge, which means it captures the WebView content but not native window decorations or system dialogs.&lt;/p&gt;
&lt;p&gt;And it's pre-1.0. The API might change. I'm using semver, so minor bumps can include breaking changes until 1.0.&lt;/p&gt;
&lt;h3 id=&quot;try-it&quot;&gt;Try it&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo install tauri-pilot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mpiton/tauri-pilot&quot;&gt;github.com/mpiton/tauri-pilot&lt;/a&gt;&lt;br&gt;
Docs: &lt;a rel=&quot;nofollow&quot; href=&quot;https://mpiton.github.io/tauri-pilot&quot;&gt;mpiton.github.io/tauri-pilot&lt;/a&gt;&lt;br&gt;
crates.io: &lt;a rel=&quot;nofollow&quot; href=&quot;https://crates.io/crates/tauri-plugin-pilot&quot;&gt;crates.io/crates/tauri-plugin-pilot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you're testing a Tauri v2 app on Linux, give it a shot. Issues and PRs are open.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/15384/i-built-a-cli-to-test-tauri-apps-because-nothing-else-worked</guid>
<pubDate>Tue, 21 Apr 2026 10:31:42 +0000</pubDate>
</item>
<item>
<title>Cross-Platform Desktop Wars: Electron vs Tauri: How do you explain the tradeoffs to users?</title>
<link>https://coderlegion.com/14746/cross-platform-desktop-wars-electron-vs-tauri-how-do-you-explain-the-tradeoffs-to-users</link>
<description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;I am writing cause I wanted to get some opinions from folks here that have actually built and shipped with Electron (or Tauri).&lt;/p&gt;
&lt;p&gt;Background: Building an API IDE on Electron. Not really “just an API client”, and not a(nother) thin wrapper around a webapp either. It’s a pretty original desktop tool with a lot of editor/IDE-like behavior - not the typical form centric behavior that postman or others have: local workflows, richer interactions, and some things that honestly would have been much harder for us to build and iterate on this quickly in a more constrained setup. Thats why Electron.&lt;/p&gt;
&lt;p&gt;this is the tool: &lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/VoidenHQ/voiden&quot;&gt;https://github.com/VoidenHQ/voiden&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, as adoption is growing, we are starting to get the usual questions about memory footprint and app size.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wn3k9wmn5jk47qrfe1wy.webp&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;The (slightly) frustrating part is this:&lt;/p&gt;
&lt;p&gt;When the app is actually being used, the app-side memory is often pretty reasonable. In many normal cases we are seeing something like 50–60 MB for the actual usage we care about (even added it in the app itself for people to check it out).&lt;/p&gt;
&lt;p&gt;But then people open Activity Monitor, see all the Chromium/Electron-related processes, and the conversation immediately becomes:&lt;/p&gt;
&lt;p&gt;“yeah but Tauri would use way less”&lt;/p&gt;
&lt;p&gt;And then, without realizing, I suddenly end up talking and philosophizing about Electron, instead of discussing the tool itself (which is what I am passionate about :)&lt;/p&gt;
&lt;p&gt;And of course, I get it. The broader footprint is real. Chromium is not free. Electron has overhead. Pretending otherwise would be foolish. So we are constantly optimizing what we can, and we will keep doing so…&lt;/p&gt;
&lt;p&gt;At the same time, I do feel that a lot of these comparisons feel weirdly flattened. For example people often compare:&lt;/p&gt;
&lt;p&gt;full Electron process footprint VS the smallest possible Tauri/native mental model&lt;/p&gt;
&lt;p&gt;…without always accounting for development speed, cross-platform consistency, ecosystem maturity, plugin/runtime complexity, UI flexibility, and the fact that some apps are doing much more than others. Which is by the way the reason that we went with Electron.&lt;/p&gt;
&lt;p&gt;So all this context to get to my real question, which is:&lt;/p&gt;
&lt;p&gt;How do you explain this tradeoff to users in a way that feels honest and understandable, without sounding like you are making excuses for Electron?&lt;br&gt;
And also, for those of you who have had this conversation a hundred times already:&lt;/p&gt;
&lt;p&gt;What do you say when people reduce the whole discussion to “Electron bad, Tauri good”?&lt;/p&gt;
&lt;p&gt;Have you found a good way to explain footprint in practical terms?&lt;/p&gt;
&lt;p&gt;Where do you think optimization actually matters, vs where people are mostly reacting to the idea of Electron?&lt;/p&gt;
&lt;p&gt;Mostly trying to learn how others think about this , especially those who have built more serious desktop products and had to answer these questions in the wild.&lt;/p&gt;
&lt;p&gt;Would love your thoughts and advice!&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14746/cross-platform-desktop-wars-electron-vs-tauri-how-do-you-explain-the-tradeoffs-to-users</guid>
<pubDate>Tue, 14 Apr 2026 07:12:44 +0000</pubDate>
</item>
<item>
<title>Here is the Kimi Desktop on Ubuntu 26.04 noone asked for..... Because I am creating 1 desktop a day</title>
<link>https://coderlegion.com/14718/here-is-the-kimi-desktop-on-ubuntu-26-04-noone-asked-for-because-i-am-creating-1-desktop-a-day</link>
<description>&lt;hr&gt;
&lt;p&gt;I decided I am going to create 1 desktop app a day for the new Ubuntu release because noone ships linux. It's crazy they expect us to dev in linux but ship for windows and mac but you know what ? I am tired of bouncing back and forth! Linux for this windows for that ohhh check in on the kids switch to mac. It;s enough. So here is app 5 (if you dont count the Voicebox I made earlier today because their junk was busted and their instructions were just build it from source... Yeah thanks Chad...Here ya go. &quot;Kimi Desktop on Ubuntu 26.04: Fixing the Broken .deb with Tauri v2&quot;&lt;/p&gt;
&lt;h3 id=&quot;-the-official-kimi-desktop-app-can-t-install-on-ubuntu-24-04-because-it-depends-on-a-removed-library-here-s-how-i-rebuilt-it-with-tauri-v2-and-pake-v3-to-fix-it-&quot;&gt;&quot;The official Kimi desktop app can't install on Ubuntu 24.04+ because it depends on a removed library. Here's how I rebuilt it with Tauri v2 and Pake v3 to fix it.&quot;&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;You install the official Kimi desktop &lt;code&gt;.deb&lt;/code&gt;, fire &lt;code&gt;sudo dpkg -i&lt;/code&gt;, and boom:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dpkg: dependency problems prevent configuration of kimi:
 kimi depends on libwebkit2gtk-4.0-37; however:
  Package libwebkit2gtk-4.0-37 is not installed.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That library doesn't exist on Ubuntu 24.04, let alone 26.04. It was removed from the repos over a year ago. The official &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/kimi-moonshot/kimi-moonshot&quot;&gt;Kimi desktop package&lt;/a&gt; is built on Tauri v1, which hard-depends on &lt;code&gt;libwebkit2gtk-4.0.so.37&lt;/code&gt; — a library that shipped with webkit2gtk 4.0, superseded by 4.1 and then dropped entirely.&lt;/p&gt;
&lt;p&gt;So the app is just... broken on any modern Ubuntu. Here's how I fixed it.&lt;/p&gt;
&lt;h3 id=&quot;the-problem-in-one-sentence&quot;&gt;The problem in one sentence&lt;/h3&gt;
&lt;p&gt;Tauri v1 → &lt;code&gt;libwebkit2gtk-4.0&lt;/code&gt; → removed from Ubuntu 24.04+ → &lt;code&gt;dpkg&lt;/code&gt; fails.&lt;/p&gt;
&lt;h3 id=&quot;the-fix-rebuild-with-tauri-v2&quot;&gt;The fix: rebuild with Tauri v2&lt;/h3&gt;
&lt;p&gt;Tauri v2 links against &lt;code&gt;libwebkit2gtk-4.1&lt;/code&gt;, which &lt;em&gt;is&lt;/em&gt; the version shipped in Ubuntu 24.04 and 26.04. So the fix is straightforward: rebuild the app with Tauri v2 instead of v1.&lt;/p&gt;
&lt;p&gt;I used &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/tw93/Pake&quot;&gt;Pake&lt;/a&gt; v3, which wraps any web app into a native desktop app using Tauri under the hood. One build script, one config file, and you get a &lt;code&gt;.deb&lt;/code&gt; that actually installs.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get&quot;&gt;What you get&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Tauri v2 runtime&lt;/strong&gt; — Links against &lt;code&gt;libwebkit2gtk-4.1&lt;/code&gt;, the one Ubuntu actually ships&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OAuth / SSO&lt;/strong&gt; — &lt;code&gt;--new-window&lt;/code&gt; flag means Google sign-in works in-app instead of being blocked&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;System tray&lt;/strong&gt; — Desktop integration that works&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1200x780 window&lt;/strong&gt; — Matches the original Kimi desktop dimensions&lt;/p&gt;
&lt;h3 id=&quot;rebuild-it-yourself&quot;&gt;Rebuild it yourself&lt;/h3&gt;
&lt;p&gt;Prerequisites — Rust, Node, and the usual GTK/webkit dev packages:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Rust &amp;gt;= 1.85
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Node.js &amp;gt;= 22 — use nvm, brew, whatever you prefer

# Build deps
sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev \
  libayatana-appindicator3-dev librsvg2-dev

# Pake CLI
npm install -g pake-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then it's one command:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./build.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;.deb&lt;/code&gt; lands in &lt;code&gt;dist/&lt;/code&gt;. Install it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo dpkg -i dist/kimi_1.0.0_amd64.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Done. Kimi runs natively on Ubuntu 26.04 with no missing libraries.&lt;/p&gt;
&lt;h3 id=&quot;the-config-that-makes-it-work&quot;&gt;The config that makes it work&lt;/h3&gt;
&lt;p&gt;Everything lives in &lt;code&gt;config/pake.json&lt;/code&gt;. The important bits:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;windows&quot;: [{
    &quot;url&quot;: &quot;https://kimi.moonshot.cn&quot;,
    &quot;new_window&quot;: true,
    &quot;width&quot;: 1200,
    &quot;height&quot;: 780
  }],
  &quot;user_agent&quot;: {
    &quot;linux&quot;: &quot;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The two things that matter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;new_window: true&lt;/code&gt;&lt;/strong&gt; — Without this, OAuth popups (Google sign-in, etc.) get blocked by the webview's navigation policy. This flag tells Pake/Tauri to open them in a new window instead.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;user_agent.linux&lt;/code&gt;&lt;/strong&gt; — Spoofing a Chrome UA because some OAuth providers reject webview user agents.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;why-not-just-use-the-web-app-in-a-browser-&quot;&gt;Why not just use the web app in a browser?&lt;/h3&gt;
&lt;p&gt;Fair question. A native desktop app gives you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Alt-Tab separation&lt;/strong&gt; — Kimi isn't buried among 40 browser tabs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System tray&lt;/strong&gt; — Quick access, stays running in the background&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Own window chrome&lt;/strong&gt; — Feels like an app, not a tab&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smaller memory footprint&lt;/strong&gt; — Tauri uses the system webview, not a bundled Electron instance&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-repo&quot;&gt;The repo&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/johnohhh1/kimi-app&quot;&gt;github.com/johnohhh1/kimi-app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Clone it, build it, install it. If you're on Ubuntu 24.04+ and want Kimi as a desktop app, this is currently the only way that works.&lt;/p&gt;
&lt;h3 id=&quot;uninstall&quot;&gt;Uninstall&lt;/h3&gt;
&lt;p&gt;If you need to remove it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo dpkg -r kimi
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Kimi is a product of &lt;a rel=&quot;nofollow&quot; href=&quot;https://moonshot.cn&quot;&gt;Moonshot AI&lt;/a&gt;. This project uses the open-source &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/tw93/Pake&quot;&gt;Pake&lt;/a&gt; tool (MIT license) to wrap the Kimi web interface as a native desktop application.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/14718/here-is-the-kimi-desktop-on-ubuntu-26-04-noone-asked-for-because-i-am-creating-1-desktop-a-day</guid>
<pubDate>Tue, 14 Apr 2026 03:17:32 +0000</pubDate>
</item>
</channel>
</rss>