<?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: Jessica Doering</title>
    <description>The latest articles on DEV Community by Jessica Doering (@sizzlebop).</description>
    <link>https://dev.to/sizzlebop</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%2F2676985%2Fa7882ab0-e15a-497b-9151-aeb4899fcc0f.png</url>
      <title>DEV Community: Jessica Doering</title>
      <link>https://dev.to/sizzlebop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sizzlebop"/>
    <language>en</language>
    <item>
      <title>I Retested My MoE Offloading Benchmarks. Some of My Conclusions Changed.</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Sat, 31 Oct 2026 19:33:06 +0000</pubDate>
      <link>https://dev.to/sizzlebop/i-retested-my-moe-offloading-benchmarks-some-of-my-conclusions-changed-6f4</link>
      <guid>https://dev.to/sizzlebop/i-retested-my-moe-offloading-benchmarks-some-of-my-conclusions-changed-6f4</guid>
      <description>&lt;p&gt;&lt;em&gt;A follow-up to my original 16GB GPU experiment, this time with consistent quantization, repeated benchmarks, and a few unexpected results.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I recently published an article about experimenting with Mixture-of-Experts (MoE) offloading on my laptop.&lt;/p&gt;

&lt;p&gt;I tested five different models, compared traditional layer offloading against selective expert offloading, and came away with some pretty interesting results.&lt;/p&gt;

&lt;p&gt;Some models performed better with selective offloading. Others were considerably faster using traditional layer splitting.&lt;/p&gt;

&lt;p&gt;And one model, LFM2.5, performed so badly with selective offloading that I really wanted to figure out what was going on.&lt;/p&gt;

&lt;p&gt;Well, the article got some great feedback.&lt;/p&gt;

&lt;p&gt;People pointed out things I hadn't properly accounted for, questioned some of my assumptions, and suggested better ways to test what I was seeing.&lt;/p&gt;

&lt;p&gt;Which, honestly, is exactly the kind of feedback I love getting.&lt;/p&gt;

&lt;p&gt;So naturally, I went right back down the rabbit hole.&lt;/p&gt;

&lt;p&gt;And this time, some of the results were very different.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, what needed fixing?
&lt;/h2&gt;

&lt;p&gt;If you haven't read the original article, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/sizzlebop/moe-offloading-isnt-always-faster-i-tested-5-models-on-a-16gb-gpu-498a"&gt;MoE Offloading Isn't Always Faster: I Tested 5 Models on a 16GB GPU&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that experiment, I was testing whether selective MoE offloading could improve performance when running models that were too large to fit entirely in my GPU's VRAM.&lt;/p&gt;

&lt;p&gt;The idea is to keep certain operations running on the GPU while offloading selected expert weights and their computation to the CPU.&lt;/p&gt;

&lt;p&gt;I used &lt;code&gt;llama.cpp&lt;/code&gt; with the &lt;code&gt;--n-cpu-moe&lt;/code&gt; option and compared it against traditional layer splitting using &lt;code&gt;-ngl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But there were a couple of problems with my original testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The models weren't all using the same quantization.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I had Phi-3.5 running at Q4_K_M, Apex at Q5_K_M, Qwen at Q6_K, and Gemma and LFM at Q8_0.&lt;/p&gt;

&lt;p&gt;That made it difficult to know whether the performance differences were related to the model architectures, quantization, or something else.&lt;/p&gt;

&lt;p&gt;A couple of people brought this up in the comments, particularly regarding LFM's terrible performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I also wasn't doing enough repeated measurements.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another person pointed out that laptop thermals, background activity, and ordinary measurement noise could influence the results. He suggested interleaving the configurations rather than running one strategy completely before moving to the other.&lt;/p&gt;

&lt;p&gt;That was a really good point.&lt;/p&gt;

&lt;p&gt;My original benchmarks were useful for spotting interesting behavior, but some of the smaller differences weren't necessarily meaningful.&lt;/p&gt;

&lt;p&gt;So I decided to do another round of testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new test setup
&lt;/h2&gt;

&lt;p&gt;I'm still using the same laptop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GPU:&lt;/strong&gt; NVIDIA RTX 4090 Laptop GPU, 16GB VRAM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CPU:&lt;/strong&gt; Intel Core i9-14900HX, 24 cores / 32 threads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RAM:&lt;/strong&gt; 32GB DDR5&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OS:&lt;/strong&gt; CachyOS / Arch Linux&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inference engine:&lt;/strong&gt; llama.cpp with CUDA and Flash Attention enabled&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I changed several things about the testing process.&lt;/p&gt;

&lt;p&gt;All five models were now running at &lt;strong&gt;Q4_K_M&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I also updated llama.cpp, adjusted the offloading configurations to accommodate the smaller quantized models, and kept enough free VRAM to avoid pushing the GPU right to its memory limit.&lt;/p&gt;

&lt;p&gt;For each model, I used the same prompt:&lt;/p&gt;

&lt;p&gt;"What are 3 practical benefits of using Arch Linux?&lt;/p&gt;

&lt;p&gt;Each configuration received a warmup request before measurement.&lt;/p&gt;

&lt;p&gt;I then ran three repeated measurements per strategy in an interleaved order, with short cooldowns between runs.&lt;/p&gt;

&lt;p&gt;Instead of relying on a single result, I used the median generation speed.&lt;/p&gt;

&lt;p&gt;This doesn't make the experiment perfectly controlled. In particular, changing the quantization, offload settings, and llama.cpp build means I can't attribute every difference to quantization alone.&lt;/p&gt;

&lt;p&gt;But it does give me a much better picture of how these models behave under a consistent Q4_K_M setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new results
&lt;/h2&gt;

&lt;p&gt;Here's what happened with the initial 100-token Q4_K_M tests:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Traditional Split&lt;/th&gt;
&lt;th&gt;Selective MoE&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Phi-3.5-MoE&lt;/td&gt;
&lt;td&gt;6.17 tok/s&lt;/td&gt;
&lt;td&gt;5.15 tok/s&lt;/td&gt;
&lt;td&gt;Traditional +19.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apex-35B&lt;/td&gt;
&lt;td&gt;8.20 tok/s&lt;/td&gt;
&lt;td&gt;9.70 tok/s&lt;/td&gt;
&lt;td&gt;Selective +18.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5-35B&lt;/td&gt;
&lt;td&gt;7.44 tok/s&lt;/td&gt;
&lt;td&gt;9.00 tok/s&lt;/td&gt;
&lt;td&gt;Selective +21.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LFM2.5-24B&lt;/td&gt;
&lt;td&gt;32.96 tok/s&lt;/td&gt;
&lt;td&gt;35.44 tok/s&lt;/td&gt;
&lt;td&gt;Selective +7.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 4 26B&lt;/td&gt;
&lt;td&gt;13.58 tok/s&lt;/td&gt;
&lt;td&gt;13.58 tok/s&lt;/td&gt;
&lt;td&gt;Tie&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Well, that was interesting.&lt;/p&gt;

&lt;p&gt;In my original tests, traditional splitting was faster on Qwen, LFM, and Gemma.&lt;/p&gt;

&lt;p&gt;Now selective offloading was ahead on Qwen and LFM, and Gemma was essentially tied.&lt;/p&gt;

&lt;p&gt;Phi-3.5 had also gone in the opposite direction.&lt;/p&gt;

&lt;p&gt;But I wasn't quite ready to declare those results final.&lt;/p&gt;

&lt;p&gt;Some of the individual runs had pretty significant variation, including one unusually fast Apex result and one unusually slow LFM result.&lt;/p&gt;

&lt;p&gt;So I extended the testing to 512-token generations on a few of the models.&lt;/p&gt;

&lt;p&gt;And that's where things got even more interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qwen: Quantization really does seem to matter
&lt;/h2&gt;

&lt;p&gt;This was probably the result I was most interested in investigating.&lt;/p&gt;

&lt;p&gt;In my original tests, Qwen3.5-35B at Q6_K performed better using traditional layer splitting.&lt;/p&gt;

&lt;p&gt;But Apex-35B, which uses a related 256-expert MoE architecture, performed better with selective offloading at Q5_K_M.&lt;/p&gt;

&lt;p&gt;I wondered whether the quantization difference was contributing to that behavior.&lt;/p&gt;

&lt;p&gt;The new Q4_K_M results certainly suggested it might be.&lt;/p&gt;

&lt;p&gt;So I went a little further.&lt;/p&gt;

&lt;p&gt;I tested &lt;strong&gt;the same Qwen3.5-35B checkpoint at Q4_K_M and Q6_K&lt;/strong&gt;, using the same llama.cpp build and longer 512-token generations.&lt;/p&gt;

&lt;p&gt;Here's what I found:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Quantization&lt;/th&gt;
&lt;th&gt;Traditional Split&lt;/th&gt;
&lt;th&gt;Selective MoE&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Q6_K&lt;/td&gt;
&lt;td&gt;6.79 tok/s&lt;/td&gt;
&lt;td&gt;6.75 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;6.47 tok/s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.38 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At Q6_K, the two strategies were practically tied.&lt;/p&gt;

&lt;p&gt;At Q4_K_M, selective MoE offloading was &lt;strong&gt;29.5% faster&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's a substantial difference.&lt;/p&gt;

&lt;p&gt;And unlike the original Apex-versus-Qwen comparison, this time I was comparing different quantizations of the same model, on the same inference engine build.&lt;/p&gt;

&lt;p&gt;I still can't say quantization was the only factor, because the layer placement also needed adjusting to fit the different model sizes.&lt;/p&gt;

&lt;p&gt;But this is much stronger evidence that the combination of quantization and memory placement has a major influence on selective offloading performance.&lt;/p&gt;

&lt;p&gt;It also changed how I think about fine-grained MoE architectures.&lt;/p&gt;

&lt;p&gt;Originally, I suspected that models with 256 routed experts might be particularly problematic for CPU offloading.&lt;/p&gt;

&lt;p&gt;These results suggest it's not nearly that simple.&lt;/p&gt;

&lt;p&gt;A 256-expert model can perform quite well with selective offloading, depending on the configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  LFM: The biggest surprise needed another look
&lt;/h2&gt;

&lt;p&gt;If you read my first article, you might remember LFM2.5.&lt;/p&gt;

&lt;p&gt;That was the model that managed a rather miserable &lt;strong&gt;2.11 tokens/sec&lt;/strong&gt; with selective offloading at Q8_0.&lt;/p&gt;

&lt;p&gt;Traditional splitting achieved 9.03 tok/s.&lt;/p&gt;

&lt;p&gt;More than four times faster.&lt;/p&gt;

&lt;p&gt;It was such a dramatic difference that several people commented on it.&lt;/p&gt;

&lt;p&gt;Mudassir suggested that the heavier 8-bit expert weights might be putting too much pressure on CPU memory bandwidth.&lt;/p&gt;

&lt;p&gt;I suspected something similar, but didn't have the evidence to separate that from the architecture itself.&lt;/p&gt;

&lt;p&gt;Well, switching to Q4_K_M produced a massive improvement.&lt;/p&gt;

&lt;p&gt;The initial 100-token run reached &lt;strong&gt;35.44 tok/s&lt;/strong&gt; with selective MoE offloading.&lt;/p&gt;

&lt;p&gt;That's approximately 16.8 times the original result.&lt;/p&gt;

&lt;p&gt;Traditional splitting also improved considerably, reaching 32.96 tok/s.&lt;/p&gt;

&lt;p&gt;But there was a problem.&lt;/p&gt;

&lt;p&gt;One of the selective runs dropped all the way to 11.23 tok/s, while the other two were above 35 tok/s.&lt;/p&gt;

&lt;p&gt;That's a pretty ridiculous amount of variation.&lt;/p&gt;

&lt;p&gt;So I repeated the experiment using longer 512-token generations.&lt;/p&gt;

&lt;p&gt;This time, the results looked quite different:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Median Generation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Traditional Split&lt;/td&gt;
&lt;td&gt;21.72 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selective MoE&lt;/td&gt;
&lt;td&gt;21.88 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Essentially a tie.&lt;/p&gt;

&lt;p&gt;The weird 11.23 tok/s dip didn't reappear in those longer runs, but both configurations were considerably slower than their original 100-token medians.&lt;/p&gt;

&lt;p&gt;That raises questions about workload length, sustained performance, and what might be changing during generation.&lt;/p&gt;

&lt;p&gt;What I can say is that LFM clearly isn't inherently terrible at selective expert offloading.&lt;/p&gt;

&lt;p&gt;Under the new Q4_K_M configuration, it performed reasonably well.&lt;/p&gt;

&lt;p&gt;But whether the improvement came primarily from quantization, different layer placement, changes in llama.cpp, or a combination of all three still needs more investigation.&lt;/p&gt;

&lt;p&gt;And the longer test also reminded me of something important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A configuration that looks faster over 100 tokens might not have the same advantage over 512.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's something I'll definitely keep in mind when benchmarking models in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then I tried speculative decoding with Gemma 4
&lt;/h2&gt;

&lt;p&gt;Because apparently five models and two offloading strategies weren't enough to keep me entertained.&lt;/p&gt;

&lt;p&gt;I also wanted to see whether Multi-Token Prediction (MTP) speculative decoding could improve performance when using selective MoE offloading.&lt;/p&gt;

&lt;p&gt;Gemma 4 26B-A4B has a separate MTP drafter that can propose multiple tokens for the main model to verify.&lt;/p&gt;

&lt;p&gt;The idea is that generating and verifying several tokens together can sometimes be faster than generating them individually.&lt;/p&gt;

&lt;p&gt;In theory, that sounded promising.&lt;/p&gt;

&lt;p&gt;In practice, my results were not particularly encouraging.&lt;/p&gt;

&lt;p&gt;Without MTP, selective offloading reached:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13.58 tokens/sec&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With the MTP drafter enabled:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7.24 tokens/sec&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So instead of speeding things up, it reduced throughput by approximately 46.7%.&lt;/p&gt;

&lt;p&gt;I wanted to understand why.&lt;/p&gt;

&lt;p&gt;During a longer 512-token test, I captured the drafter telemetry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;draft acceptance = 0.11678103 accepted / 882 generatedmean len = 1.35
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only &lt;strong&gt;11.68% of the proposed draft tokens were accepted&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's a pretty awful acceptance rate.&lt;/p&gt;

&lt;p&gt;The longer MTP run also measured just 6.03 tok/s.&lt;/p&gt;

&lt;p&gt;Speculative decoding has overhead. If the drafter isn't making predictions that the target model can accept often enough, the extra work can outweigh whatever speedup you hoped to achieve.&lt;/p&gt;

&lt;p&gt;The low acceptance rate gives me a much more concrete reason to investigate the slowdown than simply assuming CPU/GPU synchronization was responsible.&lt;/p&gt;

&lt;p&gt;I still want to check whether the drafter configuration or some other compatibility issue contributed to the poor acceptance rate.&lt;/p&gt;

&lt;p&gt;So I wouldn't conclude from this that speculative decoding and CPU offloading are fundamentally incompatible.&lt;/p&gt;

&lt;p&gt;Just that this particular configuration definitely didn't help.&lt;/p&gt;

&lt;h2&gt;
  
  
  Something else the repeat testing revealed: Noise
&lt;/h2&gt;

&lt;p&gt;One of Riccardo's main suggestions was to account for measurement variation.&lt;/p&gt;

&lt;p&gt;And after seeing these results, I'm glad I did.&lt;/p&gt;

&lt;p&gt;For example, the three Apex selective offloading runs were:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;9.21 tok/s9.70 tok/s25.50 tok/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last run was affected by early end-of-sequence generation, making it a poor comparison with the other runs.&lt;/p&gt;

&lt;p&gt;LFM also produced that unusually slow 11.23 tok/s result.&lt;/p&gt;

&lt;p&gt;And Gemma's traditional offloading runs varied from 8.98 to 16.85 tok/s.&lt;/p&gt;

&lt;p&gt;Those are not small differences.&lt;/p&gt;

&lt;p&gt;Interleaving the configurations helped make the testing process fairer, but it didn't magically remove every source of variation.&lt;/p&gt;

&lt;p&gt;Using medians helped reduce the influence of individual outliers, although three measurements still aren't enough to establish a particularly reliable performance distribution.&lt;/p&gt;

&lt;p&gt;The longer tests were especially useful because they showed that some of the apparent advantages became much smaller when the workload changed.&lt;/p&gt;

&lt;p&gt;Going forward, I think longer generations and more repeated measurements are going to be standard practice for my experiments.&lt;/p&gt;

&lt;p&gt;It's a little more work, but clearly worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what did I actually learn?
&lt;/h2&gt;

&lt;p&gt;I went into the original experiment wanting to find out whether selective MoE offloading was a better way to run large models on a GPU with limited VRAM.&lt;/p&gt;

&lt;p&gt;My first conclusion was that it depended on the model.&lt;/p&gt;

&lt;p&gt;That still seems true, but now I'd add quite a bit more to it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quantization can change the outcome.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qwen went from traditional splitting performing slightly better at Q6_K to selective offloading gaining a substantial advantage at Q4_K_M.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offloading configuration matters.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two configurations using the same model can place very different amounts of work on the CPU and GPU. The amount of VRAM occupied doesn't tell the whole story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Short benchmarks can be misleading.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LFM's apparent 7.5% selective advantage in the 100-token tests practically disappeared over the longer generations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speculative decoding isn't a free speed boost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Gemma's MTP drafter had a very low acceptance rate and made generation considerably slower under my tested setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And perhaps most importantly, a measurement and an explanation aren't the same thing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I can measure that something runs faster or slower.&lt;/p&gt;

&lt;p&gt;Explaining exactly &lt;em&gt;why&lt;/em&gt; sometimes requires considerably more testing.&lt;/p&gt;

&lt;p&gt;That distinction is becoming more obvious the deeper I get into this.&lt;/p&gt;

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

&lt;p&gt;I'm not quite finished experimenting.&lt;/p&gt;

&lt;p&gt;I'd still like to test more quantization levels on the exact same checkpoint, ideally with more carefully controlled offloading configurations.&lt;/p&gt;

&lt;p&gt;I'm also interested in monitoring actual CPU memory bandwidth and GPU behavior during inference.&lt;/p&gt;

&lt;p&gt;That might help answer some of the questions about where these slowdowns are coming from instead of relying on educated guesses.&lt;/p&gt;

&lt;p&gt;And eventually, I still want to repeat some of these tests on a machine with 64GB of RAM.&lt;/p&gt;

&lt;p&gt;I'm especially curious how much more flexibility that provides for keeping expert weights in system memory without running into swap pressure.&lt;/p&gt;

&lt;p&gt;But for now, I think I've learned quite a bit from these two rounds of testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;One of my favorite things about sharing experiments publicly is that sometimes people notice things you missed.&lt;/p&gt;

&lt;p&gt;I thought my original results were interesting, and I still do.&lt;/p&gt;

&lt;p&gt;But several people asked good questions about the methodology, the quantization differences, and whether the measurements were reliable enough to support some of my conclusions.&lt;/p&gt;

&lt;p&gt;They were right to ask.&lt;/p&gt;

&lt;p&gt;And when I went back and tested those things, some of my conclusions changed.&lt;/p&gt;

&lt;p&gt;I'm glad they did.&lt;/p&gt;

&lt;p&gt;I'd much rather discover that my original explanation wasn't quite right than keep repeating it because it sounded reasonable.&lt;/p&gt;

&lt;p&gt;That's half the fun of experimenting with this stuff.&lt;/p&gt;

&lt;p&gt;You start with one question, find an interesting result, and suddenly you're investigating three completely different things you hadn't even considered.&lt;/p&gt;

&lt;p&gt;And occasionally you realize you've spent an entire weekend benchmarking language models instead of doing literally anything else.&lt;/p&gt;

&lt;p&gt;You know, perfectly normal behavior.&lt;/p&gt;

&lt;p&gt;A big thank you to everyone who took the time to read the original article and offer thoughtful feedback. It genuinely helped make this second round of experiments better.&lt;/p&gt;

&lt;p&gt;And if anyone has suggestions for what I should test next, particularly around quantization, CPU memory bandwidth, or speculative decoding, I'd love to hear them.&lt;/p&gt;

&lt;p&gt;Apparently I haven't spent enough time staring at tokens-per-second measurements yet.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>llm</category>
    </item>
    <item>
      <title>MoE Offloading Isn’t Always Faster: I Tested 5 Models on a 16GB GPU</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Fri, 30 Oct 2026 14:04:55 +0000</pubDate>
      <link>https://dev.to/sizzlebop/moe-offloading-isnt-always-faster-i-tested-5-models-on-a-16gb-gpu-498a</link>
      <guid>https://dev.to/sizzlebop/moe-offloading-isnt-always-faster-i-tested-5-models-on-a-16gb-gpu-498a</guid>
      <description>&lt;p&gt;I do a lot of experimenting with local language models, and I just ended up going down a bit of a rabbit hole.&lt;/p&gt;

&lt;p&gt;It started when I came across an article about running larger Mixture-of-Experts (MoE) models on GPUs that don't have enough VRAM to hold the entire model.&lt;/p&gt;

&lt;p&gt;The idea was pretty simple. Instead of offloading entire model layers to system RAM, you could selectively offload just the MoE experts and leave the rest of the work on the GPU.&lt;/p&gt;

&lt;p&gt;I thought that sounded interesting. And since I have a laptop with 16GB of VRAM and 32GB of RAM, I figured I'd give it a try.&lt;/p&gt;

&lt;p&gt;Well, one model turned into another, which turned into another, and before I knew it, I was benchmarking five different models, comparing offloading strategies, and trying to figure out why some configurations worked so much better than others.&lt;/p&gt;

&lt;p&gt;You know, a perfectly normal way to spend a day.&lt;/p&gt;

&lt;p&gt;And I learned quite a bit along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, what exactly is MoE offloading?
&lt;/h2&gt;

&lt;p&gt;If you've experimented with running local LLMs, you're probably familiar with the problem of trying to load a model that's too large for your GPU.&lt;/p&gt;

&lt;p&gt;You can use CPU offloading to make it fit, but there's usually a pretty significant performance penalty.&lt;/p&gt;

&lt;p&gt;Traditional layer offloading moves entire transformer layers between the GPU and CPU. That means parts of the model that could benefit from GPU acceleration end up running on the CPU instead.&lt;/p&gt;

&lt;p&gt;MoE models give us another option.&lt;/p&gt;

&lt;p&gt;Unlike dense models, where essentially all the model's parameters participate in processing each token, MoE models have multiple experts, and only a subset is activated for each token.&lt;/p&gt;

&lt;p&gt;For example, Microsoft's Phi-3.5-MoE has around &lt;strong&gt;42 billion total parameters&lt;/strong&gt;, but only about &lt;strong&gt;6.6 billion are active per token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That doesn't mean the other parameters disappear. They still need to be stored somewhere.&lt;/p&gt;

&lt;p&gt;But since only certain experts are needed for each token, we can potentially keep some of those expert weights in system RAM while leaving attention and other parts of the model on the GPU.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;llama.cpp&lt;/code&gt;, this is possible using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--n-cpu-moe&lt;/span&gt; N
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;N&lt;/code&gt; specifies how many initial layers will have their MoE expert weights kept on the CPU.&lt;/p&gt;

&lt;p&gt;In theory, this should let you run larger models without sacrificing quite as much performance as traditional layer offloading.&lt;/p&gt;

&lt;p&gt;But I wanted to see how well it actually worked.&lt;/p&gt;

&lt;h2&gt;
  
  
  My test setup
&lt;/h2&gt;

&lt;p&gt;All of these experiments were done on my Acer Predator laptop running CachyOS (Arch Linux).&lt;/p&gt;

&lt;p&gt;Here's the hardware:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPU:&lt;/strong&gt; NVIDIA RTX 4090 Laptop GPU, 16GB VRAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU:&lt;/strong&gt; Intel Core i9-14900HX, 24 cores / 32 threads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAM:&lt;/strong&gt; 32GB DDR5&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference engine:&lt;/strong&gt; llama.cpp with CUDA support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flash Attention:&lt;/strong&gt; Enabled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used GGUF models and ran everything through &lt;code&gt;llama-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I started with Phi-3.5-MoE because it seemed like a good candidate for testing this technique. From there, I added several other MoE models with different architectures and quantization levels.&lt;/p&gt;

&lt;p&gt;For the initial comparisons, I used a 4,096-token context window, a warm-up request, and the same short benchmark prompt.&lt;/p&gt;

&lt;p&gt;This wasn't intended to be some exhaustive scientific benchmark. I wanted to see what actually happened on my hardware and whether the differences were significant enough to investigate further.&lt;/p&gt;

&lt;h2&gt;
  
  
  The models I tested
&lt;/h2&gt;

&lt;p&gt;I ended up testing five models:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Quantization&lt;/th&gt;
&lt;th&gt;GGUF size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Phi-3.5-MoE (42B)&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;24GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apex-35B V1.0&lt;/td&gt;
&lt;td&gt;Q5_K_M&lt;/td&gt;
&lt;td&gt;24GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5-35B-A3B&lt;/td&gt;
&lt;td&gt;Q6_K&lt;/td&gt;
&lt;td&gt;27GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 4 26B A4B&lt;/td&gt;
&lt;td&gt;Q8_0&lt;/td&gt;
&lt;td&gt;26GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LFM2.5-24B-A2B&lt;/td&gt;
&lt;td&gt;Q8_0&lt;/td&gt;
&lt;td&gt;24GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All of them were larger than my available GPU memory.&lt;/p&gt;

&lt;p&gt;That was the whole point of the experiment.&lt;/p&gt;

&lt;p&gt;I wanted to compare two approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Traditional layer offloading:&lt;/strong&gt; Move complete layers to the CPU until the model fits within available VRAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selective MoE offloading:&lt;/strong&gt; Keep GPU-eligible non-expert operations on the GPU while moving selected expert weights and their computation to the CPU.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I adjusted the settings for each model to fit within my memory limits.&lt;/p&gt;

&lt;p&gt;And this is where things started getting interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The results were definitely not what I expected
&lt;/h2&gt;

&lt;p&gt;Here's a comparison of the generation speeds I measured:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Selective MoE&lt;/th&gt;
&lt;th&gt;Traditional offloading&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Phi-3.5-MoE&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5.67 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4.03 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apex-35B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5.18 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3.69 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5-35B&lt;/td&gt;
&lt;td&gt;4.37 tok/s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5.23 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 4 26B&lt;/td&gt;
&lt;td&gt;4.40 tok/s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5.77 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LFM2.5-24B&lt;/td&gt;
&lt;td&gt;2.11 tok/s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9.03 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I originally expected selective MoE offloading to be the better option across the board.&lt;/p&gt;

&lt;p&gt;That was definitely not the case.&lt;/p&gt;

&lt;p&gt;On Phi-3.5-MoE and Apex-35B, selective offloading improved generation speed by around 40%.&lt;/p&gt;

&lt;p&gt;But on Qwen, Gemma, and especially LFM, traditional layer offloading was faster.&lt;/p&gt;

&lt;p&gt;And not just by a little.&lt;/p&gt;

&lt;p&gt;LFM was more than &lt;strong&gt;four times faster&lt;/strong&gt; with traditional offloading.&lt;/p&gt;

&lt;p&gt;That one really caught my attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  More GPU usage doesn't always mean better performance
&lt;/h2&gt;

&lt;p&gt;One of my favorite discoveries came from testing Phi-3.5-MoE.&lt;/p&gt;

&lt;p&gt;I started experimenting with how many expert layers I should keep on the CPU.&lt;/p&gt;

&lt;p&gt;At one point, I had nearly all 16GB of VRAM occupied.&lt;/p&gt;

&lt;p&gt;Here's what happened:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CPU expert layers&lt;/th&gt;
&lt;th&gt;VRAM used&lt;/th&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;15,945 MiB&lt;/td&gt;
&lt;td&gt;5.29 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;13,833 MiB&lt;/td&gt;
&lt;td&gt;4.66 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;11,015 MiB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5.67 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The fastest result came from offloading &lt;em&gt;more&lt;/em&gt; experts to the CPU.&lt;/p&gt;

&lt;p&gt;I actually got better generation speed while using significantly less VRAM.&lt;/p&gt;

&lt;p&gt;Now, I don't want to claim that leaving more VRAM free automatically makes inference faster. There are plenty of things that could affect these results, including CPU/GPU scheduling, memory bandwidth, caching, and normal variations between runs.&lt;/p&gt;

&lt;p&gt;But it was still interesting to see that the configuration using the most GPU memory wasn't necessarily the fastest.&lt;/p&gt;

&lt;p&gt;Sometimes the best configuration isn't the one that pushes your GPU to its absolute limit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quantization might matter more than I realized
&lt;/h2&gt;

&lt;p&gt;Another thing I noticed was how differently models behaved at different quantization levels.&lt;/p&gt;

&lt;p&gt;For example, Qwen3.5-35B at Q6_K performed better with traditional offloading.&lt;/p&gt;

&lt;p&gt;But Apex-35B, which uses a related Qwen3.5 MoE architecture and was quantized to Q5_K_M, performed better with selective MoE offloading.&lt;/p&gt;

&lt;p&gt;That made me wonder whether the additional CPU memory bandwidth needed for higher-precision expert weights was affecting performance.&lt;/p&gt;

&lt;p&gt;It would make sense. When experts are running on the CPU, the amount of data being read from system RAM can become a significant bottleneck.&lt;/p&gt;

&lt;p&gt;But I haven't proven that's the reason yet.&lt;/p&gt;

&lt;p&gt;These are different model checkpoints, and there may be architectural or implementation differences affecting the results too.&lt;/p&gt;

&lt;p&gt;I'd like to test the exact same model at Q4, Q5, and Q6 using both offloading methods. That would be a much better way to isolate the effect of quantization.&lt;/p&gt;

&lt;p&gt;For now, it's an interesting observation rather than a conclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then there was LFM...
&lt;/h2&gt;

&lt;p&gt;I really wasn't expecting this result.&lt;/p&gt;

&lt;p&gt;LFM2.5-24B-A2B has around 24 billion total parameters, with approximately 2 billion active per token.&lt;/p&gt;

&lt;p&gt;You might think that relatively low active parameter count would make it an especially good candidate for selective expert offloading.&lt;/p&gt;

&lt;p&gt;Nope.&lt;/p&gt;

&lt;p&gt;With selective offloading, I got:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.11 tokens/sec&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With traditional layer splitting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.03 tokens/sec&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's a huge difference.&lt;/p&gt;

&lt;p&gt;My suspicion is that the Q8_0 expert weights, CPU memory bandwidth, and repeated synchronization between CPU and GPU may be playing a role.&lt;/p&gt;

&lt;p&gt;But again, I would need more detailed profiling to know exactly what's happening.&lt;/p&gt;

&lt;p&gt;What this really showed me is that the number of active parameters alone doesn't tell you how efficiently a model will run on your hardware.&lt;/p&gt;

&lt;p&gt;The architecture, quantization, and inference implementation all matter.&lt;/p&gt;

&lt;p&gt;And sometimes the approach that sounds better on paper performs much worse in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  I also experimented with context length
&lt;/h2&gt;

&lt;p&gt;After finding a configuration I liked for Phi-3.5-MoE, I wanted to see what would happen when I increased the context window.&lt;/p&gt;

&lt;p&gt;Using Flash Attention, I tested 4K, 8K, and 16K context settings.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Context setting&lt;/th&gt;
&lt;th&gt;VRAM used&lt;/th&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4K&lt;/td&gt;
&lt;td&gt;11,015 MiB&lt;/td&gt;
&lt;td&gt;5.67 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8K&lt;/td&gt;
&lt;td&gt;11,531 MiB&lt;/td&gt;
&lt;td&gt;5.56 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16K&lt;/td&gt;
&lt;td&gt;12,563 MiB&lt;/td&gt;
&lt;td&gt;5.85 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The memory increase was much more manageable than I expected.&lt;/p&gt;

&lt;p&gt;I also tried the same thing with Apex-35B, where the measured VRAM increase from 4K to 16K was only around 252 MiB.&lt;/p&gt;

&lt;p&gt;It's worth mentioning that these tests changed the configured context capacity. They weren't benchmarks of processing prompts that actually contained 16,000 tokens.&lt;/p&gt;

&lt;p&gt;That distinction matters, because processing a genuinely long prompt is a different workload.&lt;/p&gt;

&lt;p&gt;Still, it was encouraging to see how much room I had for larger context settings without immediately running out of VRAM.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about putting all the experts on the CPU?
&lt;/h2&gt;

&lt;p&gt;I tried that too.&lt;/p&gt;

&lt;p&gt;With Phi-3.5-MoE, I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--cpu-moe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, well, that didn't go particularly well.&lt;/p&gt;

&lt;p&gt;The model loaded, but system memory pressure increased enough to cause heavy swapping.&lt;/p&gt;

&lt;p&gt;Generation dropped to around &lt;strong&gt;3.14 tokens/sec&lt;/strong&gt;, and I was seeing approximately 90MB/s of swap activity.&lt;/p&gt;

&lt;p&gt;At that point, my 32GB of RAM was clearly becoming a limitation.&lt;/p&gt;

&lt;p&gt;This doesn't mean full CPU expert offloading is always a bad idea. With more RAM, a different model, or a different quantization, it might be perfectly reasonable.&lt;/p&gt;

&lt;p&gt;But for this particular model and my laptop, selectively offloading only some of the experts worked much better.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, is selective MoE offloading worth using?
&lt;/h2&gt;

&lt;p&gt;I think the answer is yes, but not necessarily for every model.&lt;/p&gt;

&lt;p&gt;That's probably my biggest takeaway from all of this.&lt;/p&gt;

&lt;p&gt;When I started, I was mostly interested in seeing whether I could run models that were too large for my GPU.&lt;/p&gt;

&lt;p&gt;And I can.&lt;/p&gt;

&lt;p&gt;But what I ended up learning was that &lt;strong&gt;getting a model to fit in memory is only half the problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How you distribute its workload between the CPU and GPU can make a surprisingly big difference.&lt;/p&gt;

&lt;p&gt;For Phi-3.5-MoE and Apex-35B, selective offloading gave me better performance.&lt;/p&gt;

&lt;p&gt;For other models, especially LFM2.5, the traditional approach was considerably faster.&lt;/p&gt;

&lt;p&gt;I don't think there's a single offloading configuration that's going to work best for every MoE model.&lt;/p&gt;

&lt;p&gt;At least, that's certainly not what my experiments have shown so far.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few things I still want to test
&lt;/h2&gt;

&lt;p&gt;I'm not quite finished with this rabbit hole yet.&lt;/p&gt;

&lt;p&gt;I'd like to repeat the benchmarks with longer outputs and multiple runs per configuration, rather than relying on one short warm benchmark.&lt;/p&gt;

&lt;p&gt;I also want to compare different quantizations of the &lt;em&gt;same&lt;/em&gt; model to better understand how much precision affects CPU-side expert performance.&lt;/p&gt;

&lt;p&gt;And eventually, I'd love to repeat some of these experiments on a machine with 64GB of RAM to see how much difference the extra memory makes.&lt;/p&gt;

&lt;p&gt;There's also the question of actual usability. Tokens per second is useful, but I'd like to compare how responsive these configurations feel during longer conversations and more complicated tasks.&lt;/p&gt;

&lt;p&gt;For anyone interested in trying this themselves, here's a basic example using &lt;code&gt;llama.cpp&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;llama-server &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-m&lt;/span&gt; /path/to/model.gguf &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-ngl&lt;/span&gt; all &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--n-cpu-moe&lt;/span&gt; 20 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; 8192 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-fa&lt;/span&gt; on
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;20&lt;/code&gt; is just an example, not a magic number. You'll need to adjust it for your model and hardware, and compare it against traditional layer offloading.&lt;/p&gt;

&lt;p&gt;Also, keep an eye on system RAM and swap usage. Just because a model starts successfully doesn't mean it's going to run comfortably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;I went into this experiment thinking I'd learn a neat trick for running bigger models on my laptop.&lt;/p&gt;

&lt;p&gt;Instead, I ended up learning quite a bit about how different MoE architectures behave, how quantization can affect performance, and why CPU/GPU memory placement isn't nearly as straightforward as I originally thought.&lt;/p&gt;

&lt;p&gt;And I still have plenty of questions.&lt;/p&gt;

&lt;p&gt;That's one of the things I enjoy most about experimenting with local LLMs. You can read all the explanations and documentation you want, but sometimes you don't really understand what's happening until you start testing things yourself.&lt;/p&gt;

&lt;p&gt;Even better when the results make you question what you thought you understood in the first place.&lt;/p&gt;

&lt;p&gt;If you've experimented with MoE offloading, I'd love to hear what kind of results you've seen, especially on GPUs with limited VRAM.&lt;/p&gt;

&lt;p&gt;I'm curious whether anyone else has run into such dramatic differences between architectures.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>llm</category>
    </item>
    <item>
      <title>Is Tech Actually Welcoming to Beginners, or Do We Just Say It Is?</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Thu, 29 Oct 2026 16:58:14 +0000</pubDate>
      <link>https://dev.to/sizzlebop/is-tech-actually-welcoming-to-beginners-or-do-we-just-say-it-is-3d6p</link>
      <guid>https://dev.to/sizzlebop/is-tech-actually-welcoming-to-beginners-or-do-we-just-say-it-is-3d6p</guid>
      <description>&lt;p&gt;We hear it all the time in tech.&lt;/p&gt;

&lt;p&gt;Everyone starts somewhere. There are no stupid questions. Don't be afraid to ask for help. Keep learning.&lt;/p&gt;

&lt;p&gt;And I agree with all of that.&lt;/p&gt;

&lt;p&gt;But I've been wondering lately, are we actually as welcoming to beginners as we like to think we are?&lt;/p&gt;

&lt;p&gt;Because telling someone they're welcome is one thing. Making them feel comfortable enough to actually participate is another.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fear of asking a stupid question
&lt;/h2&gt;

&lt;p&gt;When I first started learning to code, I was pretty nervous about asking questions.&lt;/p&gt;

&lt;p&gt;I wasn't necessarily worried that someone would be outright mean to me. I was more worried about looking like I had absolutely no idea what I was doing.&lt;/p&gt;

&lt;p&gt;Which, to be fair, half the time I didn't. That's kind of the point of learning something new, right?&lt;/p&gt;

&lt;p&gt;But that didn't stop me from overthinking things.&lt;/p&gt;

&lt;p&gt;What if this is something I should already know? What if the answer is ridiculously obvious? What if someone wonders why I'm even trying to build things when I don't understand something so basic?&lt;/p&gt;

&lt;p&gt;I can't imagine I'm the only person who's ever felt that way.&lt;/p&gt;

&lt;p&gt;And apparently, I'm not.&lt;/p&gt;

&lt;p&gt;I was looking through the &lt;a href="https://survey.stackoverflow.co/2026/community/data/community-gap" rel="noopener noreferrer"&gt;2026 Stack Overflow Developer Survey&lt;/a&gt;, and a couple of numbers caught my attention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;21.1% of respondents said they worry about being judged or criticized when participating in technical or professional communities.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another &lt;strong&gt;20.1% said they don't feel confident asking questions publicly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, these numbers aren't specifically about beginners. They're from respondents more broadly, and I don't want to misrepresent that.&lt;/p&gt;

&lt;p&gt;But still, roughly one in five people answering that question are worried about what others might think of them.&lt;/p&gt;

&lt;p&gt;That's a pretty significant number of people who might have something to ask, share, or contribute but hesitate to do it.&lt;/p&gt;

&lt;p&gt;It makes me wonder how many people are reading discussions, learning from everyone else, and never saying a word because they're afraid they'll look stupid.&lt;/p&gt;

&lt;h2&gt;
  
  
  You can correct someone without making them feel stupid
&lt;/h2&gt;

&lt;p&gt;I want to be clear about something. I'm not suggesting we should stop correcting people or pretend everything everyone does is amazing.&lt;/p&gt;

&lt;p&gt;That wouldn't help anybody learn.&lt;/p&gt;

&lt;p&gt;I've made plenty of mistakes, written some questionable code, and probably approached things in ways that would make a more experienced developer scratch their head.&lt;/p&gt;

&lt;p&gt;And I'm sure I'll continue doing all three.&lt;/p&gt;

&lt;p&gt;But there's a difference between someone explaining why your approach might not be the best and someone making you feel stupid for trying it in the first place.&lt;/p&gt;

&lt;p&gt;You can point someone toward documentation without the whole "Did you even bother reading the docs?" attitude.&lt;/p&gt;

&lt;p&gt;You can disagree with someone without turning it into a contest over who knows more.&lt;/p&gt;

&lt;p&gt;And you can give someone honest feedback without making them regret asking for it.&lt;/p&gt;

&lt;p&gt;I think sometimes people forget how intimidating tech can be when you're new.&lt;/p&gt;

&lt;p&gt;Things that seem completely obvious to someone who's been programming for ten years might be something a beginner has spent the last three hours trying to figure out.&lt;/p&gt;

&lt;p&gt;And sure, maybe the answer really was in the documentation the whole time.&lt;/p&gt;

&lt;p&gt;We've all been there.&lt;/p&gt;

&lt;p&gt;But nobody learns everything overnight, and making someone feel stupid isn't going to help them learn any faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about women in tech?
&lt;/h2&gt;

&lt;p&gt;This is another part of the conversation I'm interested in.&lt;/p&gt;

&lt;p&gt;I'm a woman who builds things and is still learning all the time, and I can genuinely say that a lot of my experiences in the tech community have been really positive.&lt;/p&gt;

&lt;p&gt;Especially here on DEV.&lt;/p&gt;

&lt;p&gt;I've met some wonderful people, received helpful feedback, and had other developers encourage me to keep building and sharing my projects.&lt;/p&gt;

&lt;p&gt;And I appreciate that more than I probably say.&lt;/p&gt;

&lt;p&gt;But getting comfortable enough to put my work out there in the first place? That took some courage.&lt;/p&gt;

&lt;p&gt;I'm naturally someone who second-guesses herself, and when I first started sharing my projects, I was constantly wondering what people would think.&lt;/p&gt;

&lt;p&gt;Was my code good enough? Was what I built even worth sharing? Would more experienced developers look at it and wonder why I was so excited about something they could probably throw together in an afternoon?&lt;/p&gt;

&lt;p&gt;Looking back, I probably worried about those things a lot more than I needed to.&lt;/p&gt;

&lt;p&gt;But here's where I get curious.&lt;/p&gt;

&lt;p&gt;How much of that hesitation comes from being a beginner? How much comes from personality? And for women, is there sometimes another layer to it?&lt;/p&gt;

&lt;p&gt;I can't honestly say I've experienced some terrible amount of sexism in tech, because I haven't. At least not in the communities I've been participating in.&lt;/p&gt;

&lt;p&gt;But I also know that my experience doesn't represent every woman's experience.&lt;/p&gt;

&lt;p&gt;I'm curious whether other women have felt like they needed to prove they knew what they were talking about before anyone would take them seriously.&lt;/p&gt;

&lt;p&gt;Or whether they've noticed people making assumptions about their abilities.&lt;/p&gt;

&lt;p&gt;And I'm just as interested in hearing from women who've had really positive experiences.&lt;/p&gt;

&lt;p&gt;I don't think this is a conversation where we should assume everyone has had the same experience, because obviously we haven't.&lt;/p&gt;

&lt;p&gt;That's what makes it worth discussing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding your people makes a difference
&lt;/h2&gt;

&lt;p&gt;Something I've learned since I started sharing my work is just how much the right community can change things.&lt;/p&gt;

&lt;p&gt;There are places on the internet where asking a basic question feels like you're volunteering to be publicly roasted.&lt;/p&gt;

&lt;p&gt;And then there are places where people are genuinely excited to see what you're working on, even when it's something small.&lt;/p&gt;

&lt;p&gt;I've been lucky enough to find more of the second kind.&lt;/p&gt;

&lt;p&gt;When I first started posting on DEV, I was nervous.&lt;/p&gt;

&lt;p&gt;Now I'm sharing projects, writing articles, participating in discussions, and occasionally posting something before I've had enough time to talk myself out of it.&lt;/p&gt;

&lt;p&gt;Progress!&lt;/p&gt;

&lt;p&gt;And it's not because I've suddenly become some expert who knows everything.&lt;/p&gt;

&lt;p&gt;Trust me, I definitely haven't.&lt;/p&gt;

&lt;p&gt;I look things up constantly. I make mistakes. I run into problems that leave me staring at my screen wondering what I did wrong.&lt;/p&gt;

&lt;p&gt;But I've learned that I don't need to know everything to have something worth contributing.&lt;/p&gt;

&lt;p&gt;Sometimes you share something you've built and someone teaches you a better way to do it.&lt;/p&gt;

&lt;p&gt;Sometimes someone else is working through the exact same problem you just figured out.&lt;/p&gt;

&lt;p&gt;And sometimes a little project you're proud of inspires another person to try building something of their own.&lt;/p&gt;

&lt;p&gt;That's the kind of interaction that makes people want to participate.&lt;/p&gt;

&lt;h2&gt;
  
  
  We have to do more than say beginners are welcome
&lt;/h2&gt;

&lt;p&gt;I don't think tech is some universally hostile place where everyone is waiting to tear beginners apart.&lt;/p&gt;

&lt;p&gt;There are so many genuinely kind, helpful people out there, and I've met quite a few of them.&lt;/p&gt;

&lt;p&gt;But I also think there's room for improvement.&lt;/p&gt;

&lt;p&gt;We can tell beginners to ask questions all day long, but if the response they get makes them wish they'd kept quiet, what good does that do?&lt;/p&gt;

&lt;p&gt;We can encourage people to share their projects, but if we immediately dismiss anything that isn't particularly advanced, we're not exactly giving them a reason to share the next one.&lt;/p&gt;

&lt;p&gt;And I think it's worth remembering that something simple to you might be a huge accomplishment to someone else.&lt;/p&gt;

&lt;p&gt;Maybe it's their first working app.&lt;/p&gt;

&lt;p&gt;Maybe it's the first bug they managed to track down on their own.&lt;/p&gt;

&lt;p&gt;Maybe they finally understand something that's been confusing them for weeks.&lt;/p&gt;

&lt;p&gt;That excitement is real, even if the accomplishment seems small from where you're standing.&lt;/p&gt;

&lt;p&gt;I still get excited when I figure something out that I probably should have understood ages ago. And I'm not planning to stop anytime soon.&lt;/p&gt;

&lt;p&gt;I think most of us can remember what it felt like when we were first learning something completely unfamiliar.&lt;/p&gt;

&lt;p&gt;We just need to remember that feeling when we're the ones with a little more experience.&lt;/p&gt;

&lt;p&gt;Because a welcoming community isn't really defined by what it says about beginners.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's defined by how it treats them when they actually show up.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  I'm curious what everyone else thinks
&lt;/h2&gt;

&lt;p&gt;I'd really love to hear about your experiences, especially if they've been different from mine.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you were first learning, did you feel comfortable asking questions or sharing your work?&lt;/li&gt;
&lt;li&gt;Have you ever avoided participating in a community because you were afraid of being judged?&lt;/li&gt;
&lt;li&gt;For women in tech, do you feel your experience has been any different, good or bad?&lt;/li&gt;
&lt;li&gt;Are there particular communities that made you feel genuinely welcome?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I know my experience is only one perspective, and I think hearing from people who've had both positive and negative experiences could make for a really interesting discussion.&lt;/p&gt;

&lt;p&gt;After all, if we want tech communities to be welcoming, it probably helps to listen to the people we're trying to welcome.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>beginners</category>
      <category>community</category>
      <category>womenintech</category>
    </item>
    <item>
      <title>I Built Mimu Because Even Taking Notes Is Too Much Work</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Sat, 24 Oct 2026 02:35:32 +0000</pubDate>
      <link>https://dev.to/sizzlebop/i-built-mimu-because-even-taking-notes-is-too-much-work-2dg</link>
      <guid>https://dev.to/sizzlebop/i-built-mimu-because-even-taking-notes-is-too-much-work-2dg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;I have a lot of ideas. Sometimes they're useful. Sometimes they're not. And sometimes I think of something I want to remember while I'm doing something completely unrelated.&lt;/p&gt;

&lt;p&gt;The problem is that stopping to organize those thoughts feels like a whole separate task. Give a note a title, decide where it belongs, add tags, maybe set a reminder... suddenly the tiny thought I wanted to save has homework.&lt;/p&gt;

&lt;p&gt;So when this week's challenge asked us to build something that rewards laziness, I knew exactly which chore I wanted to avoid.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Mimu&lt;/strong&gt;, a little voice-note companion that lets me say what's on my mind and get on with my day. The note-taking is my part. The note-organizing is Mimu's.&lt;/p&gt;

&lt;p&gt;And because I wanted to experiment with open models, the AI runs on devices I control rather than through a paid AI API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mimu remembers for you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On my phone, I tap the microphone, ramble for a few seconds, check the transcript, and save it. Whisper transcribes the audio in the browser. Later, a small Gemma model running on my computer turns that raw thought into a note with a useful title, formatted Markdown, a category, and tags.&lt;/p&gt;

&lt;p&gt;The original transcript stays intact, so I can always see what I actually said. And if I don't feel like talking, I can type instead.&lt;/p&gt;

&lt;p&gt;For example, I might say, "I need to call the dentist Thursday at two." Mimu can save that as an organized note with a due date instead of leaving me to remember which of my 47 scattered notes contains the dentist's appointment.&lt;/p&gt;

&lt;p&gt;It also has a few features I added after getting the basic idea working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ask Mimu:&lt;/strong&gt; Ask questions like "Who do I need to call?" and get an answer based on your saved notes, with links to the notes it used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Morning digest and reminders:&lt;/strong&gt; The desktop model prepares a short summary of what's due today and what I saved yesterday. Due-time reminders can be sent to the phone without needing the desktop to stay on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search and editing:&lt;/strong&gt; Find notes by words, categories, and tags, or fix anything yourself without having the model overwrite it later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline capture:&lt;/strong&gt; Notes wait on the phone if the connection drops and sync when it comes back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markdown export:&lt;/strong&gt; Save one note as &lt;code&gt;.md&lt;/code&gt; or export everything as a ZIP of Markdown files. My notes don't have to live inside Mimu forever.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a responsive web app, so I can capture and browse notes on my phone and work through the library on a bigger screen. I gave it a tiny mascot, too, because apparently I cannot build an app without giving it a face.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Insert mobile screenshots]&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Try Mimu:&lt;/strong&gt; &lt;a href="https://mimu.pinkpixel.dev" rel="noopener noreferrer"&gt;https://mimu.pinkpixel.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I made a hosted demo because I didn't want the first thing a judge had to do to be "create two cloud accounts and configure a database." You can start a demo account or sign in with GitHub and explore sample notes right away.&lt;/p&gt;

&lt;p&gt;To watch your &lt;em&gt;own&lt;/em&gt; notes get organized by AI, you'll need &lt;a href="https://ollama.com/download" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; on a computer. Mimu's Desktop page gives you a command to install and connect the Node worker, which downloads the Gemma model the first time. You can pair your phone by scanning a QR code. The app works as a note library without that worker, but Gemma-powered organizing, Ask, and digests need it running.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/pFlZWNcPq-Y" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F1.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F1.png" alt="Capture screen with the mic button" width="640" height="340"&gt;&lt;/a&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F2.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F2.png" alt="Typing a note instead of speaking" width="640" height="340"&gt;&lt;/a&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F3.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F3.png" alt="Notes list in the Reminders category with a note open" width="640" height="340"&gt;&lt;/a&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F4.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fdesktop%2F4.png" alt="Ask Mimu answering questions about saved notes" width="640" height="340"&gt;&lt;/a&gt;
&lt;/p&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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F2.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F2.png" alt="Typing a note with Save and Discard buttons" width="292" height="633"&gt;&lt;/a&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F3.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F3.png" alt="Mimu mascot hugging a note with the message: Got it. I will remember that." width="292" height="633"&gt;&lt;/a&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F4.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F4.png" alt="Library with search, category filters, the Today digest card, and recent notes with a reminder time" width="292" height="633"&gt;&lt;/a&gt;
&lt;/p&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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F5.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F5.png" alt="Ask screen with the mascot holding a magnifying glass and a question typed in" width="292" height="633"&gt;&lt;/a&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F6.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F6.png" alt="Ask screen while Mimu looks through your notes" width="292" height="633"&gt;&lt;/a&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F7.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%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2Fmain%2Fscreenshots%2Fmobile%2F7.png" alt="Ask Mimu answer summarizing the day with links to the source notes" width="292" height="633"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;One important privacy detail: in the hosted demo, note &lt;em&gt;text&lt;/em&gt; is stored in a separate database for each demo account under my Turso setup. Audio isn't uploaded; it's transcribed on the device and discarded. The language model still runs on the user's own computer. Anyone who prefers their own infrastructure can self-host Mimu instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The source is available here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pinkpixel-dev" rel="noopener noreferrer"&gt;
        pinkpixel-dev
      &lt;/a&gt; / &lt;a href="https://github.com/pinkpixel-dev/mimu" rel="noopener noreferrer"&gt;
        mimu
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Speak a thought, and a local AI sorts it into searchable Markdown notes.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/assets/icon.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fassets%2Ficon.png" alt="Mimu" width="250" height="250"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Mimu&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Mimu remembers for you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mimu is a voice notes app for people with too many ideas and not enough patience for note-taking. You tap the mic on your phone, say whatever's on your mind, and it's saved. Later, a model running on your own computer turns those rambling transcripts into tidy Markdown notes with a title, a category, and tags. You can search them, edit them, and export the whole library as plain Markdown whenever you want.&lt;/p&gt;

&lt;p&gt;The speech recognition runs on your phone, and the organizing runs on your desktop. No paid AI API is involved anywhere.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See it in action&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Here's a quick demo video. Click the thumbnail to watch it on YouTube.&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://youtu.be/pFlZWNcPq-Y" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/c9f8525532802dc01043f69ab1efe5f2b11e424f3ad932229ad5cc3e50c38558/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f70466c5a574e6350712d592f6d617872657364656661756c742e6a7067" alt="Mimu demo video" width="640"&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Desktop&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/desktop/1.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fdesktop%2F1.png" alt="Capture screen with the mic button" width="49%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/desktop/2.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fdesktop%2F2.png" alt="Typing a note instead of speaking" width="49%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/desktop/3.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fdesktop%2F3.png" alt="Notes list in the Reminders category with a note open" width="49%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/desktop/4.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fdesktop%2F4.png" alt="Ask Mimu answering questions about saved notes" width="49%"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Mobile&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/mobile/1.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fmobile%2F1.png" alt="Capture screen with the big mic button and a Type instead option" width="23%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/mobile/2.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fmobile%2F2.png" alt="Typing a note with Save and Discard buttons" width="23%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/mobile/3.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fmobile%2F3.png" alt="Mimu mascot hugging a note with the message: Got it. I will remember that." width="23%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/mobile/4.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fmobile%2F4.png" alt="Library with search, category filters, the Today digest card, and recent notes with a reminder time" width="23%"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/mobile/5.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fmobile%2F5.png" alt="Ask screen with the mascot holding a magnifying glass and a question typed in" width="23%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/mobile/6.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fmobile%2F6.png" alt="Ask screen while Mimu looks through your notes" width="23%"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/pinkpixel-dev/mimu/screenshots/mobile/7.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpinkpixel-dev%2Fmimu%2FHEAD%2Fscreenshots%2Fmobile%2F7.png" alt="Ask Mimu answer summarizing the day with links to the source notes" width="23%"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Try it&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;There's a hosted demo at &lt;strong&gt;&lt;a href="https://mimu.pinkpixel.dev" rel="nofollow noopener noreferrer"&gt;mimu.pinkpixel.dev&lt;/a&gt;&lt;/strong&gt;, so you don't need a Turso or Cloudflare account to try Mimu.&lt;/p&gt;


&lt;ol&gt;

&lt;li&gt;Open the site and tap &lt;strong&gt;Start a demo&lt;/strong&gt; (or &lt;strong&gt;Continue with&lt;/strong&gt;…&lt;/li&gt;

&lt;/ol&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pinkpixel-dev/mimu" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The README includes the setup instructions, architecture, and a quickstart for deploying your own copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I started on October 20, which happened to be International Sloth Day. Appropriate timing for an app dedicated to doing less.&lt;/p&gt;

&lt;p&gt;My first plan was a phone app &lt;strong&gt;and&lt;/strong&gt; a separate Tauri desktop app. Then I looked at the deadline and remembered that I am, unfortunately, only one person. I went with one React PWA that works on both screens and a headless Node worker on the desktop. It meant I could spend more of the week making the whole experience actually work, rather than maintaining two UIs.&lt;/p&gt;

&lt;p&gt;The main pieces are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Whisper tiny (English)&lt;/strong&gt; through Transformers.js for speech-to-text in the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 4 &lt;code&gt;gemma4:e4b&lt;/code&gt;&lt;/strong&gt; through Ollama on my computer for organizing notes, interpreting dates, writing digests, and answering questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React + Vite&lt;/strong&gt; for the PWA, &lt;strong&gt;Hono on Cloudflare Workers&lt;/strong&gt; for the API, and &lt;strong&gt;Turso/libSQL&lt;/strong&gt; for note storage and full-text search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Node worker&lt;/strong&gt; that picks up pending jobs, talks to Gemma locally, and sends the results back through the API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The audio is handled on the phone. The saved text travels through the API to the database, and the desktop worker reads that text to process it. So this is &lt;strong&gt;local AI inference&lt;/strong&gt;, not an entirely offline app. I think that distinction matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  The bigger model wasn't better
&lt;/h3&gt;

&lt;p&gt;Before settling on Gemma, I tested three sizes against ten messy sample notes, using structured JSON output through Ollama.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gemma model&lt;/th&gt;
&lt;th&gt;Valid JSON&lt;/th&gt;
&lt;th&gt;Median time per note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemma4:e2b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;td&gt;3.2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemma4:e4b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;td&gt;3.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemma4:12b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;td&gt;13.7s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The funny thing is that &lt;strong&gt;all three were worse at organizing categories when I gave them a bad instruction&lt;/strong&gt;. I told them to reuse existing categories "even loosely," and suddenly a grocery list was a "General Thought" and a failing CI build belonged with software ideas.&lt;/p&gt;

&lt;p&gt;A much more specific rule about &lt;em&gt;types&lt;/em&gt; of notes fixed the problem. E4B made six sensible categories in that test, without the extra wait from the 12B model. That was a useful reminder that throwing a bigger model at a vague prompt doesn't necessarily fix the prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  My phone had other plans
&lt;/h3&gt;

&lt;p&gt;I initially tried Whisper with WebGPU. It looked promising until I tested it on my iPhone: the model download hit 100%, Safari reloaded, and I got to repeat the whole experience. No visible error. Just goodbye.&lt;/p&gt;

&lt;p&gt;I added little diagnostic breadcrumbs that survived a reload and tracked the crash to ONNX session setup. The browser could detect a WebGPU adapter, but that didn't mean the model could actually run on it.&lt;/p&gt;

&lt;p&gt;Switching to WASM fixed the issue. On the same phone, the model loaded in about &lt;strong&gt;3.3 seconds&lt;/strong&gt; and transcribed a three-second audio clip in about &lt;strong&gt;1.8 seconds&lt;/strong&gt;. For a model this small, WASM was also competitive on my desktop, so I made it the default everywhere.&lt;/p&gt;

&lt;p&gt;I learned more from testing on a real phone than from a lot of happy-path desktop tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  The tricky part wasn't formatting. It was &lt;em&gt;not making things up&lt;/em&gt;.
&lt;/h3&gt;

&lt;p&gt;At one point, Whisper misheard a phrase and Gemma confidently cleaned it up into something that meant the opposite of what I had said. The resulting note looked wonderfully polished. It was also wrong.&lt;/p&gt;

&lt;p&gt;That's a dangerous failure for an app that's supposed to remember things &lt;em&gt;for&lt;/em&gt; me.&lt;/p&gt;

&lt;p&gt;I experimented with ways to make Gemma flag suspicious transcript fragments instead of quietly repairing them. In a small repeated test with deliberately garbled and clean phrases, asking for uncertainty inside the main organizing call caught only some of the errors. Giving uncertainty detection its &lt;strong&gt;own tiny model pass&lt;/strong&gt; caught all ten garbled examples with no false alarms in that test, at roughly &lt;strong&gt;0.6 seconds more per note&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mimu now has a little &lt;strong&gt;"Mimu wasn't sure about"&lt;/strong&gt; section, and the app verifies that a flagged phrase really appeared in the transcript. It doesn't eliminate every possible transcription error, but it gives me a chance to fix something ambiguous instead of trusting a very convincing invention.&lt;/p&gt;

&lt;h3&gt;
  
  
  I kept giving my lazy app more work
&lt;/h3&gt;

&lt;p&gt;Once the capture-and-organize loop worked, I wanted Mimu to do more than make a neat pile of notes.&lt;/p&gt;

&lt;p&gt;I added natural-language due dates, so "Thursday at two" can become an actual date and time. In my test of 16 phrases run twice, giving Gemma the capture timestamp and timezone produced &lt;strong&gt;32/32 correct date-and-time results&lt;/strong&gt;. Adding a calendar cheat sheet actually made it worse. That one surprised me.&lt;/p&gt;

&lt;p&gt;Then came Ask Mimu, morning digests, and reminders. Ask uses full-text search first, then has Gemma answer from the retrieved notes, with references checked against the notes it received. If the search finds nothing, it says so instead of improvising.&lt;/p&gt;

&lt;p&gt;The final result still has more moving pieces than my original "just let me talk" idea. But they're moving so I don't have to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Mimu wouldn't be the same project if every voice note had to go through a paid transcription API and every bit of organizing required another hosted model call.&lt;/p&gt;

&lt;p&gt;Using open models let me decide &lt;strong&gt;where the work happens&lt;/strong&gt;. Whisper runs right in the browser, so audio doesn't have to leave the phone. Gemma runs on my own computer through Ollama, so I can experiment with prompts, swap model sizes, and keep using the AI features without paying per note or per question.&lt;/p&gt;

&lt;p&gt;It also meant I could test the model's actual behavior instead of treating it like a mysterious service. I could compare sizes, measure timings, change how uncertainty was handled, and build simple checks around what the model returned.&lt;/p&gt;

&lt;p&gt;There are trade-offs. You need a computer capable of running the model, and some features aren't available until the desktop worker connects. The app also uses cloud storage to sync text between devices, so I'm not claiming the whole system is private-by-default or offline. But the audio stays on the phone, inference happens locally, and you can deploy the app under your own accounts. And your notes can leave as Markdown whenever you want.&lt;/p&gt;

&lt;p&gt;That combination of control, portability, and the freedom to tinker is what made this project exciting to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;I haven't done a formal time-savings study, so I'm not going to pretend Mimu saves an exact number of minutes every day. The benefit I was going for is smaller and more familiar: removing the little bits of friction that make me not bother writing something down at all.&lt;/p&gt;

&lt;p&gt;Instead of stopping to decide on a title, folder, tags, and maybe a reminder, I can just talk. And later, I can search for the thought without remembering how I named it. That's the kind of laziness I can get behind.&lt;/p&gt;

&lt;p&gt;I did test the complete flow with a real phone and laptop: start a demo, connect the worker, pair the phone, speak a note, and watch Gemma organize it. I also tested offline capture and resync. Those aren't hypothetical features in a mockup; they worked in my end-to-end tests.&lt;/p&gt;

&lt;p&gt;The part I still want to keep testing is how well it handles real, everyday notes over time. A clean demo with a few examples is one thing. A growing pile of random thoughts from my brain is an entirely different workload.&lt;/p&gt;

&lt;p&gt;Which, conveniently, I can provide in abundance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;I'm entering &lt;strong&gt;&lt;a href="https://dev.to/challenges/hf26#best-use-of-gemma"&gt;Best Use of Gemma&lt;/a&gt;&lt;/strong&gt;. Gemma 4 is the core of Mimu's note organization, date extraction, question-answering, and digests, running locally through Ollama.&lt;/p&gt;




</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Fixed WebGPU on Linux. Then Forgot How I Did It.</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Wed, 21 Oct 2026 21:13:14 +0000</pubDate>
      <link>https://dev.to/sizzlebop/i-fixed-webgpu-on-linux-then-forgot-how-i-did-it-5hjd</link>
      <guid>https://dev.to/sizzlebop/i-fixed-webgpu-on-linux-then-forgot-how-i-did-it-5hjd</guid>
      <description>&lt;p&gt;I spent a ridiculous amount of time trying to get WebGPU working properly on my Linux machine.&lt;/p&gt;

&lt;p&gt;I eventually figured it out, wrote a script to launch Chrome with all the necessary flags, and even made a desktop launcher so I could just click an icon whenever I wanted to run browser-based AI models.&lt;/p&gt;

&lt;p&gt;Problem solved.&lt;/p&gt;

&lt;p&gt;Except recently, I started thinking about all the trouble I'd gone through and realized something.&lt;/p&gt;

&lt;p&gt;I couldn't remember how I'd fixed it.&lt;/p&gt;

&lt;p&gt;Actually, I couldn't even remember where I'd saved the script.&lt;/p&gt;

&lt;p&gt;So I did what any reasonable developer would do in 2026. I sent an AI agent to search my computer for code I'd written myself.&lt;/p&gt;

&lt;p&gt;And what did it find?&lt;/p&gt;

&lt;p&gt;Not only had I saved the script, I'd also written documentation explaining how it worked and backed everything up in TWO different resource directories.&lt;/p&gt;

&lt;p&gt;Apparently, past me was considerably more organized than present me remembered.&lt;/p&gt;

&lt;p&gt;Anyway, since I've already done all the hard work (and then forgotten about it), I figured I might as well share what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  I just wanted to run AI models in my browser
&lt;/h2&gt;

&lt;p&gt;I've spent quite a bit of time experimenting with local AI models, particularly small language models running through Transformers.js and ONNX Runtime.&lt;/p&gt;

&lt;p&gt;I love the idea of running models directly in the browser. No server to maintain, no API calls to pay for, and inference happens right on your own hardware.&lt;/p&gt;

&lt;p&gt;WebGPU makes a lot of that possible by allowing web applications to use the GPU for computation.&lt;/p&gt;

&lt;p&gt;Which sounds great, right?&lt;/p&gt;

&lt;p&gt;Except my setup wasn't exactly cooperating.&lt;/p&gt;

&lt;p&gt;I'm running Arch-based Linux with Wayland on a laptop with hybrid graphics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intel Raptor Lake UHD integrated graphics&lt;/li&gt;
&lt;li&gt;NVIDIA RTX 4090 Laptop GPU&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And getting Chrome, Vulkan, NVIDIA, and Wayland to play nicely together was an absolute pain.&lt;/p&gt;

&lt;p&gt;There are several layers involved. Your GPU drivers need to work, Vulkan needs to find the right device, Chrome needs to use the right graphics backend, and WebGPU needs to initialize successfully.&lt;/p&gt;

&lt;p&gt;And just because one of those things works doesn't mean the next one will.&lt;/p&gt;

&lt;p&gt;I spent a lot of time troubleshooting different configurations before I finally had something reliable enough to use regularly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution that worked for me
&lt;/h2&gt;

&lt;p&gt;Eventually, I ended up with a Bash script that launches a separate Chrome instance configured specifically for WebGPU.&lt;/p&gt;

&lt;p&gt;Here's the script I recovered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="c"&gt;# Launch Google Chrome with NVIDIA PRIME offload + Vulkan + WebGPU on X11.&lt;/span&gt;
&lt;span class="c"&gt;# Dedicated separate profile so it can run alongside normal Chrome.&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nv"&gt;CHROME_PROFILE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.config/chrome-webgpu-nvidia"&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHROME_PROFILE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;VK_LOADER_DRIVERS_SELECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*nvidia*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;__NV_PRIME_RENDER_OFFLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;__GLX_VENDOR_LIBRARY_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nvidia &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;__VK_LAYER_NV_optimus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;NVIDIA_only &lt;span class="se"&gt;\&lt;/span&gt;
google-chrome-stable &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--user-data-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHROME_PROFILE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-unsafe-webgpu&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Vulkan &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ozone-platform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x11 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not particularly complicated to look at.&lt;/p&gt;

&lt;p&gt;But getting to the point where I knew which settings to use was another story.&lt;/p&gt;

&lt;p&gt;I also created a &lt;code&gt;.desktop&lt;/code&gt; launcher for it, so now when I want to experiment with WebGPU, I can just open that version of Chrome without having to remember any of this.&lt;/p&gt;

&lt;p&gt;Which, as we've established, is probably a good thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What all those settings actually do
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Getting Chrome to use the NVIDIA GPU
&lt;/h3&gt;

&lt;p&gt;My laptop has two GPUs. There's the integrated Intel GPU and the dedicated NVIDIA GPU.&lt;/p&gt;

&lt;p&gt;With hybrid graphics, applications don't necessarily use the GPU you'd expect.&lt;/p&gt;

&lt;p&gt;That's a problem when you're trying to run models on your RTX 4090 and your browser decides the integrated GPU looks perfectly adequate.&lt;/p&gt;

&lt;p&gt;So my script sets four environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;VK_LOADER_DRIVERS_SELECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*nvidia*'&lt;/span&gt;
&lt;span class="nv"&gt;__NV_PRIME_RENDER_OFFLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;__GLX_VENDOR_LIBRARY_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nvidia
&lt;span class="nv"&gt;__VK_LAYER_NV_optimus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;NVIDIA_only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what they're for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;VK_LOADER_DRIVERS_SELECT&lt;/code&gt; filters the Vulkan driver manifests so that the NVIDIA driver is selected.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__NV_PRIME_RENDER_OFFLOAD=1&lt;/code&gt; enables NVIDIA PRIME render offloading.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__GLX_VENDOR_LIBRARY_NAME=nvidia&lt;/code&gt; selects NVIDIA for GLX vendor dispatch.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__VK_LAYER_NV_optimus=NVIDIA_only&lt;/code&gt; tells NVIDIA's Optimus Vulkan layer to expose only the NVIDIA GPU.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not all four variables necessarily matter for every application or graphics path, but this combination was part of my working configuration.&lt;/p&gt;

&lt;p&gt;The important thing was making sure Chrome could actually access and use the GPU I wanted.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Making Wayland cooperate by... not using native Wayland
&lt;/h3&gt;

&lt;p&gt;This one still makes me laugh.&lt;/p&gt;

&lt;p&gt;I'm running a Wayland desktop, but my working Chrome launcher includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--ozone-platform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That tells Chrome to use its X11 backend, which runs through XWayland inside my Wayland session.&lt;/p&gt;

&lt;p&gt;At the time, I was running into problems getting Vulkan and Chrome's native Wayland backend to cooperate with NVIDIA.&lt;/p&gt;

&lt;p&gt;Running Chrome through XWayland was the workaround that finally worked for my setup.&lt;/p&gt;

&lt;p&gt;So after all that effort to get things running properly under Wayland, part of my solution was essentially telling Chrome to pretend it was running under X11.&lt;/p&gt;

&lt;p&gt;Sometimes the practical solution isn't the elegant one.&lt;/p&gt;

&lt;p&gt;It's the one that actually works.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Giving Chrome its own profile
&lt;/h3&gt;

&lt;p&gt;This was one of the more useful discoveries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--user-data-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHROME_PROFILE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chrome normally reuses an existing browser instance when you try to launch it again with the same profile.&lt;/p&gt;

&lt;p&gt;So if Chrome is already open and you try launching another window with different GPU flags, you might discover that your new settings aren't actually being applied.&lt;/p&gt;

&lt;p&gt;Using a separate profile directory gives my WebGPU launcher its own Chrome process and GPU configuration.&lt;/p&gt;

&lt;p&gt;That also means I can keep my regular browser open while running a separate instance for development.&lt;/p&gt;

&lt;p&gt;No need to mess with my normal browsing setup every time I want to test something.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Enabling Vulkan and WebGPU
&lt;/h3&gt;

&lt;p&gt;Finally, these two flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--enable-unsafe-webgpu&lt;/span&gt;
&lt;span class="nt"&gt;--enable-features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Vulkan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first enables experimental WebGPU support and bypasses certain GPU restrictions.&lt;/p&gt;

&lt;p&gt;The second enables Chromium's Vulkan graphics feature.&lt;/p&gt;

&lt;p&gt;There's an important distinction here: enabling Vulkan in Chrome doesn't necessarily guarantee that WebGPU itself is using Vulkan through Dawn, Chromium's WebGPU implementation.&lt;/p&gt;

&lt;p&gt;The exact behavior depends on your Chromium version, platform, and graphics configuration.&lt;/p&gt;

&lt;p&gt;Also, &lt;code&gt;--enable-unsafe-webgpu&lt;/code&gt; is intended for development and testing. It's not something I'd recommend casually enabling in your everyday browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A note about newer Chrome versions:&lt;/strong&gt; WebGPU support on Linux has been improving, so you might not need this exact configuration anymore. In particular, newer releases have expanded support for Intel and NVIDIA hardware. Check your current browser and driver support before copying every flag into your own setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check whether it's actually working
&lt;/h2&gt;

&lt;p&gt;After launching Chrome with the script, open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chrome://gpu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the Graphics Feature Status section.&lt;/p&gt;

&lt;p&gt;Ideally, you want to see hardware acceleration enabled for WebGPU and Vulkan rather than software fallbacks.&lt;/p&gt;

&lt;p&gt;It's also worth checking the GPU and driver information to make sure Chrome is using the NVIDIA device instead of Intel or a software renderer like SwiftShader.&lt;/p&gt;

&lt;p&gt;But don't stop there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Being able to see WebGPU listed as hardware accelerated doesn't guarantee your actual application will run correctly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Try running a real WebGPU sample or the model you're planning to use.&lt;/p&gt;

&lt;p&gt;I've learned this the hard way more than once.&lt;/p&gt;

&lt;p&gt;For example, while building my recent Mimu note-taking app, Safari on my iPhone reported that WebGPU was available. But attempting to initialize the Whisper model with WebGPU caused the tab to crash and reload.&lt;/p&gt;

&lt;p&gt;The WASM version worked fine.&lt;/p&gt;

&lt;p&gt;And for that particular small model, WASM was fast enough that using WebGPU wasn't worth the trouble anyway.&lt;/p&gt;

&lt;p&gt;That was another useful reminder that the theoretically faster option isn't always the best one.&lt;/p&gt;

&lt;h2&gt;
  
  
  And then I forgot where I put everything
&lt;/h2&gt;

&lt;p&gt;So here's where this whole thing comes full circle.&lt;/p&gt;

&lt;p&gt;Recently, I've started keeping detailed build logs for my projects.&lt;/p&gt;

&lt;p&gt;Not just what I built, but what broke, what I tried, why I made certain decisions, and what I'd do differently if I approached the same problem again.&lt;/p&gt;

&lt;p&gt;Writing more on DEV has actually encouraged this habit. Thinking about what I might eventually write makes me pay more attention to what I'm doing while I'm building.&lt;/p&gt;

&lt;p&gt;And I've already found myself going back through my notes and reconsidering decisions I made just a day or two earlier.&lt;/p&gt;

&lt;p&gt;Which got me thinking about all those earlier experiences with WebGPU.&lt;/p&gt;

&lt;p&gt;I wished I'd documented them better.&lt;/p&gt;

&lt;p&gt;Turns out, I had.&lt;/p&gt;

&lt;p&gt;I just couldn't remember doing it.&lt;/p&gt;

&lt;p&gt;My AI agent found the original launcher in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.local/bin/chrome-webgpu-nvidia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The desktop entry was in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.local/share/applications/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the documentation and additional copies were sitting in my &lt;code&gt;PINKPIXEL/RESOURCES&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;In two different folders.&lt;/p&gt;

&lt;p&gt;I had already done everything I was wishing past me had done.&lt;/p&gt;

&lt;p&gt;I just hadn't done a particularly good job of making that information easy to find again.&lt;/p&gt;

&lt;p&gt;Which is even funnier considering I'm currently building an app designed to help people capture, organize, and remember things.&lt;/p&gt;

&lt;p&gt;Apparently, I really do need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned from all this
&lt;/h2&gt;

&lt;p&gt;The technical lesson here is that getting WebGPU working on Linux can involve more than just enabling a browser flag, especially with hybrid graphics.&lt;/p&gt;

&lt;p&gt;Depending on your hardware and software versions, you may need to pay attention to which GPU is being selected, which graphics backend Chrome is using, and whether your application is actually getting hardware acceleration.&lt;/p&gt;

&lt;p&gt;But I think the bigger lesson for me has less to do with WebGPU.&lt;/p&gt;

&lt;p&gt;I've built a lot of things over the years. I've solved problems, experimented with technologies, and figured out workarounds that took far more effort than I expected.&lt;/p&gt;

&lt;p&gt;And then I moved on to the next interesting thing.&lt;/p&gt;

&lt;p&gt;I didn't always stop to think about what I'd learned or how useful that experience might be later.&lt;/p&gt;

&lt;p&gt;That's something I've been trying to change.&lt;/p&gt;

&lt;p&gt;Keeping build logs has made me more thoughtful about the decisions I'm making, and writing about my experiences has encouraged me to look at them more closely.&lt;/p&gt;

&lt;p&gt;Sometimes that means discovering a better way to approach something.&lt;/p&gt;

&lt;p&gt;Sometimes it means remembering a useful technique.&lt;/p&gt;

&lt;p&gt;And sometimes it means finding out that I already solved a problem, documented it, backed it up twice, and completely forgot about the whole thing.&lt;/p&gt;

&lt;p&gt;At least now I know where my WebGPU script is.&lt;/p&gt;

&lt;p&gt;For the moment, anyway.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>webdev</category>
      <category>ai</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>In Defense of Being a Little Lazy</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Wed, 21 Oct 2026 02:02:53 +0000</pubDate>
      <link>https://dev.to/sizzlebop/in-defense-of-being-a-little-lazy-1cg9</link>
      <guid>https://dev.to/sizzlebop/in-defense-of-being-a-little-lazy-1cg9</guid>
      <description>&lt;p&gt;This week's DEV challenge is about building something that rewards laziness.&lt;/p&gt;

&lt;p&gt;Which did make me laugh a little bit.&lt;/p&gt;

&lt;p&gt;We're usually encouraged to be more productive, work harder, get more done, and make better use of our time. And now here's a challenge asking us to reward people for being lazy.&lt;/p&gt;

&lt;p&gt;But the more I thought about it, the more I started wondering whether laziness is really such a bad thing.&lt;/p&gt;

&lt;p&gt;Because there are different kinds of laziness.&lt;/p&gt;

&lt;p&gt;There's the kind where you avoid doing something you really should be doing. I'm certainly guilty of that sometimes.&lt;/p&gt;

&lt;p&gt;But then there's the kind that makes you look at a tedious, repetitive task and think, there has got to be a better way to do this.&lt;/p&gt;

&lt;p&gt;And I think that second kind deserves a little more credit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sometimes laziness makes us creative
&lt;/h2&gt;

&lt;p&gt;As developers, we do this all the time.&lt;/p&gt;

&lt;p&gt;We'll spend hours building a tool to automate something that probably only takes a few minutes to do manually.&lt;/p&gt;

&lt;p&gt;Does it always make sense? Absolutely not.&lt;/p&gt;

&lt;p&gt;Do we do it anyway? Of course we do.&lt;/p&gt;

&lt;p&gt;But I think there's something valuable in that instinct. It's not necessarily about being unwilling to work. Sometimes it's about being unwilling to keep doing work that doesn't need to exist.&lt;/p&gt;

&lt;p&gt;That kind of laziness can lead to some pretty clever solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  But what about doing nothing?
&lt;/h2&gt;

&lt;p&gt;Here's where I think it gets even more interesting.&lt;/p&gt;

&lt;p&gt;We've gotten so used to measuring everything in terms of productivity that even our free time sometimes feels like it needs a purpose.&lt;/p&gt;

&lt;p&gt;We take breaks so we can come back refreshed and work harder. We track our sleep so we can perform better. We turn hobbies into projects, projects into products, and sometimes products into businesses.&lt;/p&gt;

&lt;p&gt;And there's nothing inherently wrong with any of that.&lt;/p&gt;

&lt;p&gt;But does everything really need to accomplish something?&lt;/p&gt;

&lt;p&gt;What about doing absolutely nothing just because you feel like it?&lt;/p&gt;

&lt;p&gt;Not to recharge. Not to improve your focus. Not because it's part of some carefully planned routine.&lt;/p&gt;

&lt;p&gt;Just because you want to.&lt;/p&gt;

&lt;p&gt;I think there's value in allowing ourselves that kind of freedom, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maybe it's about choosing where our effort goes
&lt;/h2&gt;

&lt;p&gt;I'm starting to think the good version of laziness isn't really about avoiding effort.&lt;/p&gt;

&lt;p&gt;It's about being more selective with it.&lt;/p&gt;

&lt;p&gt;Sometimes that means finding a smarter way to do something.&lt;/p&gt;

&lt;p&gt;Sometimes it means recognizing that something doesn't need to be done at all.&lt;/p&gt;

&lt;p&gt;And sometimes it means giving yourself permission to spend an afternoon doing something completely unproductive without feeling guilty about it.&lt;/p&gt;

&lt;p&gt;I have been diligently working on my challenge submission, which I suppose is the opposite of being lazy, but the theme for this week got me thinking.&lt;/p&gt;

&lt;p&gt;Maybe laziness has a little more going for it than we give it credit for.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>devjournal</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>What Do You Make When You Can Make Anything?</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Tue, 20 Oct 2026 16:45:47 +0000</pubDate>
      <link>https://dev.to/sizzlebop/what-do-you-make-when-you-can-make-anything-596b</link>
      <guid>https://dev.to/sizzlebop/what-do-you-make-when-you-can-make-anything-596b</guid>
      <description>&lt;p&gt;I have more creative freedom than I've ever had.&lt;/p&gt;

&lt;p&gt;Some days, I have so many ideas that I can't wait to sit down and start building.&lt;/p&gt;

&lt;p&gt;Other days, I open my editor, stare at the empty screen, and can't think of a single thing I want to make.&lt;/p&gt;

&lt;p&gt;It's not because I've run out of possibilities.&lt;/p&gt;

&lt;p&gt;It's because I've got too many.&lt;/p&gt;

&lt;h2&gt;
  
  
  When everything sounds interesting
&lt;/h2&gt;

&lt;p&gt;I've always been someone who likes making things. I get curious about something, start wondering how it works, and before long I'm opening a new project folder.&lt;/p&gt;

&lt;p&gt;Sometimes it's something practical. A tool that solves a problem I've run into, or something I wish existed but haven't been able to find.&lt;/p&gt;

&lt;p&gt;Other times, it's something completely unnecessary that just sounds fun to build.&lt;/p&gt;

&lt;p&gt;And sometimes I don't even care all that much about the finished product. I just want to see if I can make it work.&lt;/p&gt;

&lt;p&gt;That's one of my favorite things about programming. There's always something new to explore, something to figure out, or a random idea that might actually turn into something interesting.&lt;/p&gt;

&lt;p&gt;But there's a downside to being interested in so many things.&lt;/p&gt;

&lt;p&gt;I can sit down with every intention of working on something and find myself mentally bouncing between a dozen different possibilities.&lt;/p&gt;

&lt;p&gt;Maybe I should finish one of my existing projects.&lt;/p&gt;

&lt;p&gt;Maybe I should try that new library I came across yesterday.&lt;/p&gt;

&lt;p&gt;Maybe I should build that little CLI tool I've been thinking about.&lt;/p&gt;

&lt;p&gt;Or maybe I should make something entirely different.&lt;/p&gt;

&lt;p&gt;And somehow, after considering all of those options, I end up doing absolutely none of them.&lt;/p&gt;

&lt;p&gt;Not because I don't want to make something.&lt;/p&gt;

&lt;p&gt;I want to make everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The barriers are disappearing
&lt;/h2&gt;

&lt;p&gt;I think AI has made this feeling even more noticeable for me.&lt;/p&gt;

&lt;p&gt;There was a time when an idea came with a fairly substantial list of things we'd have to figure out before we could even start building it.&lt;/p&gt;

&lt;p&gt;Do we know the language? Could we work with the framework? Would we have to spend weeks learning something new just to get a basic version running?&lt;/p&gt;

&lt;p&gt;Those questions might not necessarily stop us, but they did help narrow down what we were realistically going to attempt.&lt;/p&gt;

&lt;p&gt;Now, a lot of those barriers are smaller.&lt;/p&gt;

&lt;p&gt;I can experiment with a language I'm unfamiliar with, explore a framework I've never used, or take an idea much further than I could have on my own in the same amount of time.&lt;/p&gt;

&lt;p&gt;And I love that.&lt;/p&gt;

&lt;p&gt;I still have plenty to learn, and AI certainly doesn't make the hard parts of building software disappear. But it does make more ideas feel within reach.&lt;/p&gt;

&lt;p&gt;Which means I have fewer reasons to dismiss an idea before I start.&lt;/p&gt;

&lt;p&gt;That sounds great. In theory.&lt;/p&gt;

&lt;p&gt;Most of the time, it is.&lt;/p&gt;

&lt;p&gt;But it also means that almost every passing thought can turn into a potential project.&lt;/p&gt;

&lt;p&gt;And when nearly everything feels possible, choosing what to spend my time on becomes its own challenge.&lt;/p&gt;

&lt;h2&gt;
  
  
  I don't think it's always a creative block
&lt;/h2&gt;

&lt;p&gt;I've been thinking about the difference between having no ideas and having too many.&lt;/p&gt;

&lt;p&gt;Because from the outside, they can look exactly the same.&lt;/p&gt;

&lt;p&gt;You sit there staring at an empty editor, not writing a single line of code.&lt;/p&gt;

&lt;p&gt;But what's happening in your head can be completely different.&lt;/p&gt;

&lt;p&gt;Sometimes I genuinely don't feel inspired. Nothing sounds particularly interesting, and I'd rather go do something else.&lt;/p&gt;

&lt;p&gt;Other times, I have so many ideas competing for my attention that I can't settle on one long enough to begin.&lt;/p&gt;

&lt;p&gt;It's almost like standing in front of an enormous menu where everything looks good.&lt;/p&gt;

&lt;p&gt;You'd think having more choices would make the experience better.&lt;/p&gt;

&lt;p&gt;Instead, you spend twenty minutes trying to decide what you want.&lt;/p&gt;

&lt;p&gt;And the funny thing is, I know perfectly well that I don't have to make the best thing.&lt;/p&gt;

&lt;p&gt;I'm not running a company where every project needs a business case. I'm not trying to build the next big startup every time I sit down at my computer.&lt;/p&gt;

&lt;p&gt;Most of the time, I'm just making things because I enjoy making them.&lt;/p&gt;

&lt;p&gt;So why does choosing sometimes feel like such a big decision?&lt;/p&gt;

&lt;h2&gt;
  
  
  The things I could be making
&lt;/h2&gt;

&lt;p&gt;I think part of it is that every project I choose to work on represents a bunch of other projects I'm not choosing.&lt;/p&gt;

&lt;p&gt;If I spend the night working on a terminal app, I'm not experimenting with that interesting new UI framework.&lt;/p&gt;

&lt;p&gt;If I start something new, I'm not finishing something old.&lt;/p&gt;

&lt;p&gt;If I spend three hours exploring an idea that goes nowhere, I could have spent those three hours improving something I already built.&lt;/p&gt;

&lt;p&gt;And yes, I realize how ridiculous that sounds when I'm talking about something I do for fun.&lt;/p&gt;

&lt;p&gt;But I think that's part of what happens when you're curious about a lot of things and have the tools to pursue them.&lt;/p&gt;

&lt;p&gt;You start feeling the weight of all the things you could be doing.&lt;/p&gt;

&lt;p&gt;Even when nobody is asking you to do any of them.&lt;/p&gt;

&lt;p&gt;I also think there's something strangely exciting about an idea before you start building it.&lt;/p&gt;

&lt;p&gt;In your head, it's full of potential. You can imagine what it might become, all the interesting features you could add, and all the things you'll learn along the way.&lt;/p&gt;

&lt;p&gt;Once you actually start, you have to make decisions. You run into limitations. Some parts are less interesting than you expected.&lt;/p&gt;

&lt;p&gt;The idea becomes a real project, with all the ordinary work that comes with one.&lt;/p&gt;

&lt;p&gt;And meanwhile, somewhere in the back of your mind, another shiny idea is waiting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maybe I don't need to make anything
&lt;/h2&gt;

&lt;p&gt;I love that I can sit down at my computer and turn some random thought into something real.&lt;/p&gt;

&lt;p&gt;I love learning new things, trying unfamiliar technologies, and making tools that probably wouldn't exist if I hadn't decided to build them.&lt;/p&gt;

&lt;p&gt;But I'm starting to wonder if I've gotten so used to having something to work on that sitting down without a project feels like a problem I need to solve.&lt;/p&gt;

&lt;p&gt;Maybe not every ounce of free time needs to become a new repository.&lt;/p&gt;

&lt;p&gt;Maybe sometimes I can just explore something without turning it into an application.&lt;/p&gt;

&lt;p&gt;Or spend some time actually using the things I've already made.&lt;/p&gt;

&lt;p&gt;Or close the editor and do something else entirely.&lt;/p&gt;

&lt;p&gt;I don't think the answer is to stop starting projects. Starting things is one of the ways I learn, and honestly, it's a huge part of what makes programming fun for me.&lt;/p&gt;

&lt;p&gt;And I don't think I need to force myself to finish everything I begin, either. Sometimes an experiment has already given me what I wanted from it, even if it never becomes anything more.&lt;/p&gt;

&lt;p&gt;Maybe the harder thing for me to learn is that having the ability to make something doesn't mean I have to.&lt;/p&gt;

&lt;p&gt;That I can have ten ideas and choose just one of them without worrying about the other nine.&lt;/p&gt;

&lt;p&gt;And that sometimes, when nothing feels quite right, I can simply leave the editor closed.&lt;/p&gt;

&lt;p&gt;Because the possibilities aren't going anywhere.&lt;/p&gt;

&lt;p&gt;Maybe having the freedom to make anything also means having the freedom to make nothing.&lt;/p&gt;

</description>
      <category>creativity</category>
      <category>productivity</category>
      <category>devjournal</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Terminal Made Me a Better Developer (And Not for the Reasons I Expected)</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Mon, 19 Oct 2026 00:36:51 +0000</pubDate>
      <link>https://dev.to/sizzlebop/the-terminal-made-me-a-better-developer-and-not-for-the-reasons-i-expected-nn6</link>
      <guid>https://dev.to/sizzlebop/the-terminal-made-me-a-better-developer-and-not-for-the-reasons-i-expected-nn6</guid>
      <description>&lt;p&gt;When I first started using the terminal, sure, it was useful. I could navigate around directories, install packages, run a dev server, do some Git stuff. But most of those things could also be done by clicking a few buttons.&lt;/p&gt;

&lt;p&gt;And clicking buttons seemed perfectly reasonable to me.&lt;/p&gt;

&lt;p&gt;I wasn't really sure about being one of those people who does absolutely everything from a terminal just because I can.&lt;/p&gt;

&lt;p&gt;But the more I got into development, and especially the more time I spent working with Linux, the more I found myself using it.&lt;/p&gt;

&lt;p&gt;Sometimes because it was faster. Sometimes because whatever I was trying to do didn't have a convenient graphical option. And sometimes because I was following instructions and had absolutely no idea what half the commands were doing.&lt;/p&gt;

&lt;p&gt;Eventually, I started getting curious about that last part.&lt;/p&gt;

&lt;p&gt;What was that command actually doing? Why did it work? Why did it fail? And why was I running it in the first place?&lt;/p&gt;

&lt;p&gt;Somewhere along the way, I realized I was learning a lot more than how to use a command line.&lt;/p&gt;

&lt;p&gt;I was starting to understand how things worked underneath all the nice interfaces I'd gotten used to.&lt;/p&gt;

&lt;p&gt;And that's been far more useful than learning to type commands quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  I started paying more attention to the filesystem
&lt;/h2&gt;

&lt;p&gt;I've always understood files and folders. I think most of us have been moving things around in file managers for years without giving it much thought.&lt;/p&gt;

&lt;p&gt;But working in the terminal made me pay attention to things I normally wouldn't have noticed.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;pwd
ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing exciting there, right?&lt;/p&gt;

&lt;p&gt;But when you're working in the terminal, knowing where you are actually matters.&lt;/p&gt;

&lt;p&gt;I've lost count of how many times I've tried running something only to discover I wasn't in the directory I thought I was.&lt;/p&gt;

&lt;p&gt;Or wondered why a configuration file wasn't showing up, only to remember it was hidden.&lt;/p&gt;

&lt;p&gt;Or had something fail because I used a relative path without thinking about what it was relative &lt;em&gt;to&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;These are pretty basic things, but they're also things I could get away with not thinking about when I was just clicking through folders.&lt;/p&gt;

&lt;p&gt;I started paying more attention to hidden files, symbolic links, absolute versus relative paths, and where applications store their configuration.&lt;/p&gt;

&lt;p&gt;And suddenly, a bunch of little things that used to confuse me started making more sense.&lt;/p&gt;

&lt;p&gt;Not because the terminal magically made me smarter. I just had to understand what I was doing instead of relying on an interface to handle it for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  I finally started understanding processes
&lt;/h2&gt;

&lt;p&gt;This was a big one for me.&lt;/p&gt;

&lt;p&gt;When you open an application normally, you click an icon and it opens. When you're finished, you close it.&lt;/p&gt;

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;p&gt;But there's a lot going on behind that, and I didn't always give it much thought.&lt;/p&gt;

&lt;p&gt;Running things from the terminal made processes a lot more visible.&lt;/p&gt;

&lt;p&gt;Especially when working on web apps.&lt;/p&gt;

&lt;p&gt;If you've spent any time developing with Vite, you've probably encountered the dreaded port-already-in-use situation.&lt;/p&gt;

&lt;p&gt;You try to start your dev server, and something is already sitting on the port you wanted.&lt;/p&gt;

&lt;p&gt;Sometimes it's another instance of your app that you forgot was still running. Ask me how I know.&lt;/p&gt;

&lt;p&gt;Instead of just closing random terminal windows and hoping for the best, I started learning how to see what was actually running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux
pgrep &lt;span class="nt"&gt;-af&lt;/span&gt; node
ss &lt;span class="nt"&gt;-ltnp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if I specifically want to know what's listening on port 5173:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ss &lt;span class="nt"&gt;-ltnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;':5173'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands let me investigate the processes and listening sockets on my system. Depending on permissions, I might not be able to see every process associated with a socket, but it's a useful place to start.&lt;/p&gt;

&lt;p&gt;It seems like a small thing, but understanding the relationship between a running application, its process, and the port it's using helped a lot of other concepts click for me.&lt;/p&gt;

&lt;p&gt;Before, I knew my dev server was running because the browser showed my app.&lt;/p&gt;

&lt;p&gt;Now I had a better idea of what &lt;em&gt;running&lt;/em&gt; actually meant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Permissions started making a lot more sense
&lt;/h2&gt;

&lt;p&gt;Linux permissions were another one of those things I sort of understood in theory.&lt;/p&gt;

&lt;p&gt;Read, write, execute. Got it.&lt;/p&gt;

&lt;p&gt;Except apparently I didn't always get it, because I'd still run into situations where I couldn't modify a file or execute a script and wonder what the hell was going on.&lt;/p&gt;

&lt;p&gt;The terminal made it easier to actually look at what was happening.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; script.sh
&lt;span class="nb"&gt;stat &lt;/span&gt;script.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of just getting a permission-denied message and being annoyed about it, I could check who owned the file and what permissions it had.&lt;/p&gt;

&lt;p&gt;I started understanding why a file might be readable but not writable, or why a script wouldn't execute even though it was sitting right there.&lt;/p&gt;

&lt;p&gt;I also learned that execute permission on a directory doesn't mean quite the same thing as execute permission on a file. On a directory, it's about being able to traverse it.&lt;/p&gt;

&lt;p&gt;That's one of those little Linux details that seems weird until you understand it.&lt;/p&gt;

&lt;p&gt;And then there's &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I think it's pretty easy when you're learning Linux to see a permission error and think, well, I'll just stick sudo in front of it.&lt;/p&gt;

&lt;p&gt;Problem solved!&lt;/p&gt;

&lt;p&gt;Except maybe not.&lt;/p&gt;

&lt;p&gt;You might get the command to work, but you still don't know why it needed elevated permissions. And depending on what you're doing, you might end up creating files owned by root that really shouldn't be.&lt;/p&gt;

&lt;p&gt;I've learned that getting something to work and understanding why it wasn't working are two very different things.&lt;/p&gt;

&lt;p&gt;That lesson has come up quite a bit in development, actually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Networking became a little less mysterious
&lt;/h2&gt;

&lt;p&gt;Networking is one of those subjects where I understood the general concepts long before I felt comfortable troubleshooting anything.&lt;/p&gt;

&lt;p&gt;I knew what DNS was. I knew what ports were. I understood that applications communicate over networks.&lt;/p&gt;

&lt;p&gt;Great.&lt;/p&gt;

&lt;p&gt;But when something wouldn't connect, that knowledge didn't necessarily tell me where to start.&lt;/p&gt;

&lt;p&gt;Was the hostname resolving? Was the server actually responding? Was my application even listening on the port I thought it was?&lt;/p&gt;

&lt;p&gt;Or had I somehow managed to break something entirely unrelated?&lt;/p&gt;

&lt;p&gt;The terminal gave me a way to start narrowing those things down.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig example.com
curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://example.com
ss &lt;span class="nt"&gt;-ltn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands look at different pieces of the puzzle.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dig&lt;/code&gt; lets me check DNS resolution.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl&lt;/code&gt; lets me make an HTTP request and inspect the response.&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;ss&lt;/code&gt; lets me see which TCP ports are listening on my own system.&lt;/p&gt;

&lt;p&gt;None of these commands will magically explain every network problem, obviously. But they give me somewhere to start.&lt;/p&gt;

&lt;p&gt;And I think that's what made the biggest difference.&lt;/p&gt;

&lt;p&gt;I stopped treating every connection failure as one big mysterious problem and started trying to figure out which part was actually failing.&lt;/p&gt;

&lt;p&gt;Because "my app can't connect" could mean quite a few different things.&lt;/p&gt;

&lt;p&gt;And knowing which one you're dealing with makes troubleshooting a whole lot easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  I got better at actually reading errors
&lt;/h2&gt;

&lt;p&gt;This might sound ridiculous, but I think one of the most useful things I've learned from working in the terminal is to actually read what my tools are telling me.&lt;/p&gt;

&lt;p&gt;Not just glance at the error, decide something is broken, and immediately start trying things until it works.&lt;/p&gt;

&lt;p&gt;I mean &lt;em&gt;really&lt;/em&gt; read it.&lt;/p&gt;

&lt;p&gt;When you're working in the terminal, you see a lot of output.&lt;/p&gt;

&lt;p&gt;Compiler errors, dependency warnings, stack traces, server logs, and sometimes an absolutely ridiculous wall of text because one little thing went wrong.&lt;/p&gt;

&lt;p&gt;At first, all that output can be overwhelming.&lt;/p&gt;

&lt;p&gt;And sometimes it still is.&lt;/p&gt;

&lt;p&gt;But the more I worked with it, the more I started recognizing what was worth paying attention to.&lt;/p&gt;

&lt;p&gt;A missing environment variable isn't the same thing as a network request failing.&lt;/p&gt;

&lt;p&gt;A dependency conflict isn't a syntax error.&lt;/p&gt;

&lt;p&gt;And an application that crashes immediately is a very different problem from one that's running perfectly fine but not responding the way you expected.&lt;/p&gt;

&lt;p&gt;I still have plenty of moments where I stare at an error wondering what on earth it's trying to tell me.&lt;/p&gt;

&lt;p&gt;But I'm much more likely now to investigate the actual error instead of immediately throwing another possible solution at it.&lt;/p&gt;

&lt;p&gt;And when I do have to look something up, I usually have a much better idea of &lt;em&gt;what&lt;/em&gt; I need to look up.&lt;/p&gt;

&lt;p&gt;That's made a pretty big difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real benefit has been learning how to investigate things
&lt;/h2&gt;

&lt;p&gt;I think this is the part I didn't expect when I started using the terminal more.&lt;/p&gt;

&lt;p&gt;I thought I'd learn some useful commands. Maybe speed up a few workflows.&lt;/p&gt;

&lt;p&gt;What I didn't expect was how much it would change the way I approached problems.&lt;/p&gt;

&lt;p&gt;Now, when something doesn't work, I'm more likely to start asking questions.&lt;/p&gt;

&lt;p&gt;Where is this command actually running?&lt;/p&gt;

&lt;p&gt;What process is using that port?&lt;/p&gt;

&lt;p&gt;Who owns this file?&lt;/p&gt;

&lt;p&gt;Is the server responding at all?&lt;/p&gt;

&lt;p&gt;What does the error message actually say?&lt;/p&gt;

&lt;p&gt;And I don't mean that I always know how to figure these things out.&lt;/p&gt;

&lt;p&gt;Far from it.&lt;/p&gt;

&lt;p&gt;Half the time I'm still looking up commands, reading documentation, or finding out that the thing I &lt;em&gt;thought&lt;/em&gt; I understood works a little differently than I expected.&lt;/p&gt;

&lt;p&gt;But that's kind of the point.&lt;/p&gt;

&lt;p&gt;I don't think being comfortable with the terminal means memorizing hundreds of commands or being able to type some ridiculous one-liner from memory.&lt;/p&gt;

&lt;p&gt;It means knowing that there's probably a way to investigate what's happening, and being willing to figure out how.&lt;/p&gt;

&lt;p&gt;Sometimes that means using a command I already know.&lt;/p&gt;

&lt;p&gt;Sometimes it means spending twenty minutes reading documentation to figure out why that command didn't do what I expected.&lt;/p&gt;

&lt;p&gt;Both are useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few things worth experimenting with
&lt;/h2&gt;

&lt;p&gt;If you're relatively new to the terminal, or you've mostly been using it to install packages and start development servers, here are a few little exercises worth trying.&lt;/p&gt;

&lt;p&gt;These examples are mostly aimed at Linux, since that's what I use. Some commands will be different on macOS or Windows.&lt;/p&gt;

&lt;p&gt;The goal isn't to memorize them. It's to look at what they show you and try to understand why that information matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Take a closer look at a project directory
&lt;/h3&gt;

&lt;p&gt;Open a terminal inside one of your projects and try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;pwd
ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt;
find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 2 &lt;span class="nt"&gt;-type&lt;/span&gt; f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at where you are, which files are hidden, and how things are organized.&lt;/p&gt;

&lt;p&gt;Try running the commands from different directories and see what changes.&lt;/p&gt;

&lt;p&gt;Pay particular attention to relative paths. They're simple until they're the reason something isn't working.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Find your development server
&lt;/h3&gt;

&lt;p&gt;Start a development server like you normally would.&lt;/p&gt;

&lt;p&gt;Then open another terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pgrep &lt;span class="nt"&gt;-af&lt;/span&gt; node
ss &lt;span class="nt"&gt;-ltnp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using a Node-based development server on Linux, see if you can find its process and the port it's listening on.&lt;/p&gt;

&lt;p&gt;If you can't see the process information you expected, look into why. It might be a permissions issue, or your server might be running through a different executable.&lt;/p&gt;

&lt;p&gt;The investigation is the exercise.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Look at file permissions
&lt;/h3&gt;

&lt;p&gt;Pick a file in your project and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; package.json
&lt;span class="nb"&gt;stat &lt;/span&gt;package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do all those permission bits mean?&lt;/p&gt;

&lt;p&gt;Who owns the file?&lt;/p&gt;

&lt;p&gt;What can the owner do that other users might not be able to?&lt;/p&gt;

&lt;p&gt;You don't need to go changing permissions just to experiment. In fact, I'd recommend understanding what you're looking at before doing that.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. See what happens during an HTTP request
&lt;/h3&gt;

&lt;p&gt;Try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; https://example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's quite a bit of information in that output.&lt;/p&gt;

&lt;p&gt;Look at the connection details, TLS negotiation, request headers, and response headers.&lt;/p&gt;

&lt;p&gt;You don't need to understand every line right away.&lt;/p&gt;

&lt;p&gt;Pick something unfamiliar and look it up.&lt;/p&gt;

&lt;p&gt;That's literally how I've learned a lot of this stuff.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Experiment with pipes
&lt;/h3&gt;

&lt;p&gt;Here's a tiny one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'apple\nbanana\napricot\n'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'^a'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apple
apricot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That little &lt;code&gt;|&lt;/code&gt; sends the output of one command into another command.&lt;/p&gt;

&lt;p&gt;It's such a simple idea, but it's also one of the things that makes Unix-like command-line environments so useful.&lt;/p&gt;

&lt;p&gt;Instead of needing one giant tool that does everything, you can connect smaller tools together.&lt;/p&gt;

&lt;p&gt;Once that concept clicks, a lot of terminal workflows start making more sense.&lt;/p&gt;

&lt;p&gt;And it's worth experimenting with beyond this little example.&lt;/p&gt;

&lt;h2&gt;
  
  
  You don't have to do everything in the terminal
&lt;/h2&gt;

&lt;p&gt;I should probably mention this because I know how these conversations sometimes go.&lt;/p&gt;

&lt;p&gt;I am not suggesting everyone should abandon graphical applications and spend the rest of their lives staring at a terminal window.&lt;/p&gt;

&lt;p&gt;I use graphical applications all the time.&lt;/p&gt;

&lt;p&gt;There are plenty of things I'd rather do with a good interface, and I'm not going to make my life unnecessarily complicated just to prove I can do something from the command line.&lt;/p&gt;

&lt;p&gt;I also don't think using a terminal automatically makes someone a better developer.&lt;/p&gt;

&lt;p&gt;You can copy and paste commands all day without understanding a single thing about what they do. Just like you can click around a graphical interface without really knowing what's happening.&lt;/p&gt;

&lt;p&gt;The difference, at least for me, has been curiosity.&lt;/p&gt;

&lt;p&gt;When I started paying attention to what commands were doing, why they were working, and why they occasionally failed spectacularly, I started learning a lot more.&lt;/p&gt;

&lt;p&gt;The terminal just makes it particularly easy to see some of the things that graphical interfaces usually handle for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's not really about typing faster
&lt;/h2&gt;

&lt;p&gt;I started using the terminal because it was useful.&lt;/p&gt;

&lt;p&gt;And sure, I've gotten faster at certain things. There are plenty of tasks where opening a terminal and typing a command is easier than clicking through a bunch of menus.&lt;/p&gt;

&lt;p&gt;But that hasn't been the most valuable part.&lt;/p&gt;

&lt;p&gt;What's really changed is how I see the software I'm working with.&lt;/p&gt;

&lt;p&gt;An application isn't just something that opens when I click an icon anymore. There are processes running, files being accessed, permissions being checked, network connections being made, and all kinds of smaller things happening behind the scenes.&lt;/p&gt;

&lt;p&gt;And when something goes wrong, I have a much better idea of where to start looking.&lt;/p&gt;

&lt;p&gt;I still have a ridiculous amount to learn. I look things up constantly, experiment with things I don't fully understand yet, and occasionally break something because I was a little too confident.&lt;/p&gt;

&lt;p&gt;But I'm getting better at figuring things out.&lt;/p&gt;

&lt;p&gt;And that's what working in the terminal has really helped me with.&lt;/p&gt;

&lt;p&gt;Not becoming some command-line expert.&lt;/p&gt;

&lt;p&gt;Just becoming a better investigator.&lt;/p&gt;

&lt;p&gt;Which, the more I learn about development, the more I realize is a pretty important skill.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>linux</category>
      <category>beginners</category>
      <category>terminal</category>
    </item>
    <item>
      <title>I Built a New Tab Extension for DEV</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Sun, 18 Oct 2026 17:13:41 +0000</pubDate>
      <link>https://dev.to/sizzlebop/i-built-a-new-tab-extension-for-dev-4kmm</link>
      <guid>https://dev.to/sizzlebop/i-built-a-new-tab-extension-for-dev-4kmm</guid>
      <description>&lt;p&gt;I spend a lot of time on DEV these days. Reading posts, finding interesting projects, participating in challenges, and occasionally writing something myself.&lt;/p&gt;

&lt;p&gt;I also like daily.dev. Having a feed of developer content right there whenever I open a new tab is pretty convenient.&lt;/p&gt;

&lt;p&gt;So naturally, I started thinking... what if I had something like that, but just for DEV?&lt;/p&gt;

&lt;p&gt;And because apparently I can't have an idea without turning it into another project, I built one.&lt;/p&gt;

&lt;p&gt;It's called &lt;strong&gt;DEV Tab&lt;/strong&gt;, and it's a free, open-source browser extension that replaces your new tab page with a feed of posts from DEV.&lt;/p&gt;

&lt;p&gt;It's now available on the Chrome Web Store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://chromewebstore.google.com/detail/dev-tab/mfhbilfjgklgebkclbkabohhkibomnop" rel="noopener noreferrer"&gt;Install DEV Tab for Chrome&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Firefox support is built too, and the add-on is currently awaiting review. I'll update this post with the link once it's approved.&lt;/p&gt;

&lt;p&gt;Firefox was approved!&lt;br&gt;
&lt;strong&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/dev-tab/" rel="noopener noreferrer"&gt;Install for Firefox&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A little more than just a feed
&lt;/h2&gt;

&lt;p&gt;The original idea was pretty simple. Open a new tab, see what's happening on DEV, and click through to anything interesting.&lt;/p&gt;

&lt;p&gt;But, as usual, I kept thinking of things to add.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4b1vtesc6c1jslog8gz.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4b1vtesc6c1jslog8gz.png" alt="DEV Tab showing a grid of DEV posts" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can browse posts from Today, This Week, Rising, and Latest, along with dedicated sections for trends, events, podcasts, and videos.&lt;/p&gt;

&lt;p&gt;There are also tag filters, so you can quickly jump between subjects you're interested in. You can save your favorite tags, hide tags you'd rather not see, and follow posts from specific DEV organizations.&lt;/p&gt;

&lt;p&gt;A few other things I added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search directly from the new tab page.&lt;/li&gt;
&lt;li&gt;Keyboard navigation using arrow keys and Enter.&lt;/li&gt;
&lt;li&gt;A compact view if you'd rather see more posts and fewer images.&lt;/li&gt;
&lt;li&gt;Reaction counts and previews of the three newest comments.&lt;/li&gt;
&lt;li&gt;A shortcut to create a new DEV post.&lt;/li&gt;
&lt;li&gt;Feed caching, so opening a new tab doesn't mean waiting for everything to load again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing particularly revolutionary here. I just wanted a convenient way to explore DEV without having to go looking for things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then I decided it needed a dashboard
&lt;/h2&gt;

&lt;p&gt;This part wasn't in my original plan, but I spend enough time writing on DEV that I thought having a better overview of my own activity would be useful.&lt;/p&gt;

&lt;p&gt;If you add your DEV API key in the extension settings, you unlock some additional features, including a personal dashboard.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5r6ncbj958xadwwbhgg.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5r6ncbj958xadwwbhgg.png" alt="DEV Tab dashboard with example statistics, charts, and post activity" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The dashboard includes your follower count, views, reactions, comments, and new followers, with options to look at the last 7, 30, or 90 days.&lt;/p&gt;

&lt;p&gt;There's also a daily views chart, an activity heatmap that lets you browse previous years, and a list of your published posts and drafts.&lt;/p&gt;

&lt;p&gt;You can see recent followers, top supporters, and where your readers are coming from, too.&lt;/p&gt;

&lt;p&gt;I particularly like having the activity heatmap and post statistics together. It's interesting to look back and see when I was active and how different posts performed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The dashboard screenshot above uses fictional example data, by the way.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting your DEV account is completely optional
&lt;/h2&gt;

&lt;p&gt;You don't need an account or API key to use the extension. The public feeds, search, filters, and other browsing features work without one.&lt;/p&gt;

&lt;p&gt;But if you do connect your DEV account, you also get access to your personal feed based on the tags you follow, your reading list, and semantic search.&lt;/p&gt;

&lt;p&gt;You can generate an API key from your &lt;a href="https://dev.to/settings/extensions"&gt;DEV settings&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The extension doesn't have a backend, analytics, or tracking. Your API key stays in your browser's local extension storage and is only sent to DEV for authenticated API requests.&lt;/p&gt;

&lt;p&gt;I wanted to keep it simple and avoid introducing a separate service just to display information DEV already makes available.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few limitations
&lt;/h2&gt;

&lt;p&gt;There are a couple of things I would have liked to include but couldn't because of the DEV API.&lt;/p&gt;

&lt;p&gt;For example, you can't directly react to posts, leave comments, or save articles to your reading list from the extension.&lt;/p&gt;

&lt;p&gt;You can view reaction counts and preview comments, but interacting with a post opens it on DEV itself.&lt;/p&gt;

&lt;p&gt;I'd love to have those actions directly in the feed someday, but for now, that's a limitation of what's available through the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built with WXT, React, and TypeScript
&lt;/h2&gt;

&lt;p&gt;I used &lt;a href="https://wxt.dev/" rel="noopener noreferrer"&gt;WXT&lt;/a&gt; for the extension framework, along with React and TypeScript.&lt;/p&gt;

&lt;p&gt;This was my first time using WXT, and I really liked being able to build for Chrome and Firefox from the same codebase.&lt;/p&gt;

&lt;p&gt;One thing I spent some time on was making sure the feed wouldn't constantly refetch everything whenever a new tab opened. The first page of each feed gets cached for ten minutes, and previously loaded posts can still appear if you're offline.&lt;/p&gt;

&lt;p&gt;It's a small thing, but when you're replacing something as frequently used as the new tab page, I think it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give it a try!
&lt;/h2&gt;

&lt;p&gt;DEV Tab is open source, so you can take a look at the code, report bugs, suggest features, or contribute if you'd like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://chromewebstore.google.com/detail/dev-tab/mfhbilfjgklgebkclbkabohhkibomnop" rel="noopener noreferrer"&gt;Chrome Web Store&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/pinkpixel-dev/DEV-tab" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Firefox version is currently awaiting approval, and I'll add the link here when it's published.&lt;/p&gt;

&lt;p&gt;This started as one of those little "wouldn't it be nice if..." ideas, and somehow turned into a full browser extension with a personal analytics dashboard.&lt;/p&gt;

&lt;p&gt;I guess that's what happens when you keep finding things you want to build.&lt;/p&gt;

&lt;p&gt;If you use DEV regularly, I'd love to hear what you think! And if there's something you'd find useful in a future version, let me know.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What I Actually Learn When I Build With AI</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Fri, 16 Oct 2026 01:06:09 +0000</pubDate>
      <link>https://dev.to/sizzlebop/what-i-actually-learn-when-i-build-with-ai-1074</link>
      <guid>https://dev.to/sizzlebop/what-i-actually-learn-when-i-build-with-ai-1074</guid>
      <description>&lt;p&gt;I've spent entire nights building something with AI, gotten a bunch of features working, and then realized I couldn't really explain half of what I'd just built.&lt;/p&gt;

&lt;p&gt;And then there are nights when I spend hours trying to figure out one stupid little problem, and somehow end up learning more from that than I did from the entire night before.&lt;/p&gt;

&lt;p&gt;It's kind of funny when you think about it. Both times I was productive. Both times I ended up with working code. But what I actually learned from each experience was completely different.&lt;/p&gt;

&lt;p&gt;I wrote a post recently about how AI is making it way too easy to avoid thinking, and it got me thinking about my own habits. Because I use AI coding tools constantly. I love them. They've helped me build things I probably wouldn't have even attempted otherwise.&lt;/p&gt;

&lt;p&gt;But I'm also still learning. A lot.&lt;/p&gt;

&lt;p&gt;And there is a big difference between just getting something working and actually understanding how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Just because I understand the explanation doesn't mean I understand the code
&lt;/h2&gt;

&lt;p&gt;This probably happens to all of us more than we'd like to admit.&lt;/p&gt;

&lt;p&gt;I might ask AI to explain something, and it'll give me a perfectly reasonable breakdown. Everything makes sense. I can follow along, I understand what each part is doing, and I think, okay, got it.&lt;/p&gt;

&lt;p&gt;Then 3 days later I need to change something, and suddenly I'm staring at the code like I've never seen it before.&lt;/p&gt;

&lt;p&gt;Apparently, I understood it just fine when someone was holding my hand through the entire explanation. &lt;/p&gt;

&lt;p&gt;That is not quite the same thing as actually knowing it, though.&lt;/p&gt;

&lt;p&gt;And I'm not talking about memorizing syntax or remembering every little API detail. I look things up all the time, and I don't see anything wrong with that.&lt;/p&gt;

&lt;p&gt;I'm talking about understanding why something was done a certain way.&lt;/p&gt;

&lt;p&gt;If all I can remember about a feature is that AI wrote it and it worked, I haven't really learned much from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sometimes the interesting part is the problem you didn't know existed
&lt;/h2&gt;

&lt;p&gt;I've been working on a text editor called &lt;a href="https://github.com/pinkpixel-dev/slate" rel="noopener noreferrer"&gt;Slate&lt;/a&gt;, which has been a really interesting learning experience for me.&lt;/p&gt;

&lt;p&gt;One thing I hadn't given much thought to before was what actually happens when you save a file while you're still editing it.&lt;/p&gt;

&lt;p&gt;I mean, saving a file sounds pretty simple, right? Write the contents to disk, mark it as saved, done.&lt;/p&gt;

&lt;p&gt;Except what happens if the user keeps typing while that save is happening?&lt;/p&gt;

&lt;p&gt;The file being written contains the older content, but the editor now has newer changes. So if the save finishes and the editor clears the unsaved indicator, it's basically telling the user everything is saved when it isn't.&lt;/p&gt;

&lt;p&gt;Slate uses revision-based save tracking to handle this. When a save starts, it remembers which revision of the document it's saving. That way, any changes made while the save is happening don't accidentally get marked as saved too.&lt;/p&gt;

&lt;p&gt;Now, AI could have just implemented all of that for me. I could have tested the save button, seen that it worked, and moved on with my life.&lt;/p&gt;

&lt;p&gt;But understanding why that revision tracking matters is what makes it useful to me.&lt;/p&gt;

&lt;p&gt;It's not really about the code itself. It's about recognizing that something can change between the time an operation starts and the time it finishes.&lt;/p&gt;

&lt;p&gt;And that's a problem that could come up in all kinds of applications, not just text editors.&lt;/p&gt;

&lt;p&gt;That's the kind of thing I want to take away from a project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actually experimenting makes a huge difference
&lt;/h2&gt;

&lt;p&gt;I've noticed the same thing when working with local AI models.&lt;/p&gt;

&lt;p&gt;Let's say I run a model and it takes 30 seconds to complete something.&lt;/p&gt;

&lt;p&gt;Okay, so it's slow. Right?&lt;/p&gt;

&lt;p&gt;Well, maybe. But what actually took 30 seconds?&lt;/p&gt;

&lt;p&gt;Was most of that time spent loading the model into memory? Was the actual processing slow? Would running it a second time be significantly faster?&lt;/p&gt;

&lt;p&gt;Those are all things I can test.&lt;/p&gt;

&lt;p&gt;And I find that I learn a lot more when I actually start experimenting instead of just asking AI to explain what's happening.&lt;/p&gt;

&lt;p&gt;Run it again. Measure things separately. Change something. See what happens.&lt;/p&gt;

&lt;p&gt;Sometimes the results are exactly what I expected. Other times they're not even close, which is usually when things get interesting.&lt;/p&gt;

&lt;p&gt;I love that I can use AI to help me figure things out. I can ask what else I should try, or why the result isn't what I expected.&lt;/p&gt;

&lt;p&gt;That makes learning unfamiliar things so much easier.&lt;/p&gt;

&lt;p&gt;But there's a big difference between AI telling me why something should happen and me actually seeing what does happen.&lt;/p&gt;

&lt;p&gt;And sometimes AI's explanation is wrong, too. Which I am sure we all know.&lt;/p&gt;

&lt;h2&gt;
  
  
  I don't necessarily remember the code, but I remember the problem
&lt;/h2&gt;

&lt;p&gt;I think this is probably the biggest thing I've noticed.&lt;/p&gt;

&lt;p&gt;When I really spend time understanding something, I might not remember the exact implementation later. But I remember the problem I was trying to solve and why I solved it that way.&lt;/p&gt;

&lt;p&gt;And that carries over into other projects.&lt;/p&gt;

&lt;p&gt;Maybe I start wondering whether some asynchronous operation could finish after the user has already changed something.&lt;/p&gt;

&lt;p&gt;Or whether a performance issue is actually a startup issue.&lt;/p&gt;

&lt;p&gt;Or whether I'm storing some piece of state that I could just calculate from something else.&lt;/p&gt;

&lt;p&gt;I might still need to look things up. I might still ask AI to help me write the implementation.&lt;/p&gt;

&lt;p&gt;But at least I know what I'm looking for and why it matters.&lt;/p&gt;

&lt;p&gt;If I just accept the generated code without thinking much about it, I miss all of that. The solution is sitting right there in my project, but I might not even recognize the same problem when I run into it somewhere else.&lt;/p&gt;

&lt;p&gt;And considering how often I start new projects, there's a pretty good chance I will run into it somewhere else. Probably next week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Of course, I don't need to turn everything into a learning experience
&lt;/h2&gt;

&lt;p&gt;I also think there's a balance here.&lt;/p&gt;

&lt;p&gt;Sometimes I just want AI to fix the padding on a button.&lt;/p&gt;

&lt;p&gt;I don't need to spend 45 minutes investigating the underlying principles of CSS spacing. I just want the button to look right.&lt;/p&gt;

&lt;p&gt;And there are plenty of things I'm perfectly happy to let AI handle. Boilerplate, repetitive changes, things I've already done a hundred times, or just tedious work I don't feel like doing.&lt;/p&gt;

&lt;p&gt;That's part of why I use these tools in the first place.&lt;/p&gt;

&lt;p&gt;But when I'm building something unfamiliar, or working on functionality that I know I'll need to maintain later, I try to be a little more involved.&lt;/p&gt;

&lt;p&gt;Sometimes that means just asking questions.&lt;/p&gt;

&lt;p&gt;Other times I might just start changing things to see what happens.&lt;/p&gt;

&lt;p&gt;I think even something as simple as predicting what a change will do before running it can make a difference. Because if the result isn't what I expected, now I have something to investigate.&lt;/p&gt;

&lt;p&gt;Do I do this every time? Absolutely not.&lt;/p&gt;

&lt;p&gt;Sometimes I've been staring at something for two hours, AI finally gets it working, and my entire thought process is basically "thank you, finally, moving on."&lt;/p&gt;

&lt;p&gt;I'm not going to pretend otherwise.&lt;/p&gt;

&lt;p&gt;But I am trying to be more conscious of when I'm actually learning something and when I'm just getting something done.&lt;/p&gt;

&lt;p&gt;Because those aren't always the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting something working isn't the same as learning how it works
&lt;/h2&gt;

&lt;p&gt;One of my favorite things about AI coding tools is how much more willing I am to try things I know very little about.&lt;/p&gt;

&lt;p&gt;I've experimented with languages, frameworks, local models, desktop applications, and all kinds of other things that I probably would have put off before.&lt;/p&gt;

&lt;p&gt;Not necessarily because I couldn't learn them, but because getting started on something completely unfamiliar can be a lot of work.&lt;/p&gt;

&lt;p&gt;AI makes that initial hurdle so much smaller, and I think that's genuinely awesome.&lt;/p&gt;

&lt;p&gt;But there's also a temptation to just keep building. One feature works, so you move on to the next one. Then the next. Before you know it, you've got a whole application and only a vague understanding of some pretty important parts of it.&lt;/p&gt;

&lt;p&gt;And it's so easy to confuse all that progress with learning.&lt;/p&gt;

&lt;p&gt;I've definitely done it.&lt;/p&gt;

&lt;p&gt;I think the things that stick with me the most are usually the things I had to investigate a little. Something didn't behave the way I expected, or I got curious about why it worked a certain way, and I spent some time figuring it out.&lt;/p&gt;

&lt;p&gt;Sometimes that investigation only takes a few minutes. Sometimes it sends me down a rabbit hole for the rest of the night.&lt;/p&gt;

&lt;p&gt;Either way, I tend to remember those experiences a lot more than the features that worked perfectly on the first try.&lt;/p&gt;

&lt;p&gt;And that's something I want to keep in mind as I continue building with AI.&lt;/p&gt;

&lt;p&gt;I don't want to stop using these tools or intentionally make everything harder for myself.&lt;/p&gt;

&lt;p&gt;I just don't want to get so caught up in how much I can build that I forget to pay attention to what I'm learning along the way.&lt;/p&gt;

&lt;p&gt;So... what about you? Have you learned something useful while building with AI that you can now troubleshoot or explain yourself? Or have you ever gone back to AI-generated code and realized you had absolutely no idea how it worked?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>learning</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I Built an AI Game That Wants You to Go Outside</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Sat, 10 Oct 2026 03:58:49 +0000</pubDate>
      <link>https://dev.to/sizzlebop/i-built-an-ai-game-that-wants-you-to-go-outside-3a6k</link>
      <guid>https://dev.to/sizzlebop/i-built-an-ai-game-that-wants-you-to-go-outside-3a6k</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I spend way too much time at my computer. Between coding, experimenting with AI models, and starting new projects when I have a perfectly good collection of unfinished ones already, I don't exactly have a shortage of reasons to stay indoors.&lt;/p&gt;

&lt;p&gt;So when I saw that the theme for this week's Hacktoberfest challenge was &lt;strong&gt;Touch Grass&lt;/strong&gt;, I immediately thought it would be fun to build an AI-powered game that encourages people to get &lt;em&gt;away&lt;/em&gt; from their computers.&lt;/p&gt;

&lt;p&gt;Which is a little ironic, considering how many hours I then spent at my computer building it. But anyway.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;Side Quest&lt;/strong&gt;!&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://side-quest.pinkpixel.dev/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;side-quest.pinkpixel.dev&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Side Quest is a little outdoor adventure game powered by Google's Gemma model. The idea is pretty simple: you tell the game a little about where you are and what it's like outside, and Gemma comes up with a small quest for you to complete in the real world.&lt;/p&gt;

&lt;p&gt;Maybe you're walking through a park on a fall afternoon. Maybe you're just hanging out in your backyard. Gemma takes your surroundings, the season, weather, and time of day into account and gives you something to go find.&lt;/p&gt;

&lt;p&gt;You head outside, find whatever it asked for, and take a picture. Then Gemma examines your photo to decide whether you've actually completed the quest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When you successfully complete a quest, you hatch a little creature inspired by whatever you found.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course I had to add a creature collection. I love games where you can discover and collect things, and I thought it would be great to have something to show for all those little outdoor adventures.&lt;/p&gt;

&lt;p&gt;Plus, I liked the idea of making people pay attention to things they might normally walk right past. An interesting looking leaf, an unusual rock, a shape in a tree. The kinds of things you might notice if you weren't staring at your phone.&lt;/p&gt;

&lt;p&gt;Yes, I realize the irony of using your phone to play a game that's supposed to get you to stop staring at your phone.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fotnhh0nm4ns6ads3oaro.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fotnhh0nm4ns6ads3oaro.png" alt="Side Quest homepage with its creature specimen sheet" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;The gameplay is pretty straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set the scene.&lt;/strong&gt; Tell Gemma where you are, what the weather is like, what season it is, and what time of day. You can choose from the options or describe your location yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get your quest.&lt;/strong&gt; Gemma creates a little challenge based on your surroundings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go find it!&lt;/strong&gt; Head outside, explore a bit, and take a photo of whatever you discover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get judged by Gemma.&lt;/strong&gt; The model examines your photo to see whether it matches the challenge. If it doesn't, it'll tell you why, and you can give it another shot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hatch a creature.&lt;/strong&gt; Complete the quest and get a new little companion for your collection.&lt;/li&gt;
&lt;/ol&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4w65km1xpj13o4ea6r91.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4w65km1xpj13o4ea6r91.png" alt="A quest generated for the player's surroundings" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F64yolk1egbrqk08es7ls.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F64yolk1egbrqk08es7ls.png" alt="Submitting photographic proof of a quest" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs3iy1xk7au5fg933z6un.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs3iy1xk7au5fg933z6un.png" alt="Gemma examining a submitted photo" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ozdvt3jtl8lbf40r2nc.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ozdvt3jtl8lbf40r2nc.png" alt="A newly hatched creature" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The creatures were especially fun to work on.&lt;/p&gt;

&lt;p&gt;I didn't want to just make ten pre-designed creatures and randomly hand one out whenever someone completed a quest. That felt a little boring.&lt;/p&gt;

&lt;p&gt;Instead, Gemma looks at the photo and describes characteristics that could inspire a creature. The app then uses those traits to draw a little SVG character.&lt;/p&gt;

&lt;p&gt;The photo also determines a consistent seed, so submitting the same image produces the same creature.&lt;/p&gt;

&lt;p&gt;It's not generating a whole new image through an API. The creatures are actually drawn by the app, using the details Gemma provides.&lt;/p&gt;

&lt;p&gt;I love this because your reward is connected to something you really found outside. And honestly, seeing what kind of little creature is going to hatch is half the fun.&lt;/p&gt;

&lt;p&gt;There's also a collection where you can look through your creatures alongside the original photos. It's basically a nature journal, except everything has adorable little faces.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyeh8enn0scfxnt9694ro.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyeh8enn0scfxnt9694ro.png" alt="The creature collection" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also added a &lt;strong&gt;Scavenger Hunt&lt;/strong&gt; mode!&lt;/p&gt;

&lt;p&gt;Instead of getting one quest at a time, Gemma gives you a list of things to find during a walk. You can take photos of everything and submit the whole collection for judging.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc64o8hdet5noq9dwa7l4.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc64o8hdet5noq9dwa7l4.png" alt="A multi-item scavenger hunt" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted Side Quest to be something that kids and adults could both enjoy. Something you could play with your family, or just by yourself when you need an excuse to get away from your desk for a while.&lt;/p&gt;

&lt;p&gt;It's not trying to be a fitness app. There are no step counts, exercise goals, or leaderboards.&lt;/p&gt;

&lt;p&gt;It's just a little game that makes going outside and exploring your surroundings more interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Play Side Quest:&lt;/strong&gt; &lt;a href="https://side-quest.pinkpixel.dev" rel="noopener noreferrer"&gt;https://side-quest.pinkpixel.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can try Side Quest right in your browser.&lt;/p&gt;

&lt;p&gt;For desktop, you'll need a recent Chrome or Edge browser with WebGPU support. Click &lt;strong&gt;Wake Gemma&lt;/strong&gt;, and the model will load directly into your browser.&lt;/p&gt;

&lt;p&gt;One thing to be aware of: the initial model download is around 3.4 GB. So you'll probably want to be on Wi-Fi for that first visit. Once it's downloaded, the model is cached in your browser.&lt;/p&gt;

&lt;p&gt;The desktop version is great for trying everything out, but obviously, carrying your computer outside to photograph a leaf isn't exactly practical.&lt;/p&gt;

&lt;p&gt;That's where the mobile experience comes in.&lt;/p&gt;

&lt;p&gt;You can use your computer as a &lt;strong&gt;home base&lt;/strong&gt; that runs Gemma while you take your phone outside to complete quests.&lt;/p&gt;

&lt;p&gt;Just sign in with GitHub on your computer, leave Gemma running in the home-base tab, and scan the pairing QR code with your phone.&lt;/p&gt;

&lt;p&gt;Then you're ready to go exploring.&lt;/p&gt;

&lt;p&gt;Your phone handles the quests, photos, and creature collection while your computer does all the heavy AI work.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fin5d5wg5yri31dkzxklz.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fin5d5wg5yri31dkzxklz.png" alt="The desktop home base that runs Gemma for the phone" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvfogv936pnawigt7ds7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvfogv936pnawigt7ds7.png" alt="A quest on the mobile interface" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flq21n0dfgm0qjqncxlyc.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flq21n0dfgm0qjqncxlyc.png" alt="A find sent from the phone to the home base" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fscxxa381nsz3cxqn3v43.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fscxxa381nsz3cxqn3v43.png" alt="A newly hatched creature appearing on mobile" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also made sure the phone can hold onto your photos when you don't have a connection. They'll sit in a local queue and send when you're back online.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/pinkpixel-dev/side-quest" rel="noopener noreferrer"&gt;https://github.com/pinkpixel-dev/side-quest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Side Quest is open source under the Apache 2.0 license.&lt;/p&gt;

&lt;p&gt;The repo includes the React frontend, Gemma inference worker, quest generation and creature logic, Cloudflare Worker backend, optional private home-base server, and tests.&lt;/p&gt;

&lt;p&gt;If you'd like to run the basic solo version locally, it's pretty simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://localhost:5173&lt;/code&gt; in a desktop browser that supports WebGPU.&lt;/p&gt;

&lt;p&gt;The README has more detailed instructions for setting up the hosted features, account authentication, and the private phone-to-desktop option.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Putting Gemma to work
&lt;/h3&gt;

&lt;p&gt;For the AI side of things, I used Gemma 4 E2B, Google's open-weight multimodal model, running with Transformers.js and WebGPU.&lt;/p&gt;

&lt;p&gt;I'm using the 4-bit ONNX version, &lt;code&gt;onnx-community/gemma-4-E2B-it-ONNX&lt;/code&gt;, which loads in a web worker so the model isn't blocking the main UI.&lt;/p&gt;

&lt;p&gt;I've been having a lot of fun experimenting with models running directly in the browser lately, so I was excited to have an excuse to build something a little different with one.&lt;/p&gt;

&lt;p&gt;And Gemma isn't just there to generate some flavor text. It's actually responsible for the main parts of the game.&lt;/p&gt;

&lt;p&gt;It handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quest generation:&lt;/strong&gt; Creating challenges based on your surroundings, weather, season, and time of day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Photo judging:&lt;/strong&gt; Looking at your submitted image and deciding whether you actually found what the quest asked for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creature traits:&lt;/strong&gt; Describing features inspired by your photo that the app can use to draw your new creature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scavenger hunts:&lt;/strong&gt; Coming up with multiple things to find and evaluating the collected photos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I especially like that Gemma evaluates your photo and describes the creature together. Your discovery actually influences what you get as a reward.&lt;/p&gt;

&lt;p&gt;For the rest of the stack, I used React 19, TypeScript, Vite 8, and Tailwind CSS 4.&lt;/p&gt;

&lt;p&gt;IndexedDB handles the local storage for quests, photos, completed finds, and creatures. And the creatures themselves are generated as SVGs, so there's no need for a separate image generation model or service.&lt;/p&gt;

&lt;h3&gt;
  
  
  The part that got complicated
&lt;/h3&gt;

&lt;p&gt;There was one pretty obvious problem with my whole idea.&lt;/p&gt;

&lt;p&gt;I wanted people to use this game while walking around outside. But the Gemma model runs best with a desktop GPU.&lt;/p&gt;

&lt;p&gt;Not exactly ideal for a mobile game.&lt;/p&gt;

&lt;p&gt;Naturally, I decided to see if I could get it running on my iPhone 12 anyway.&lt;/p&gt;

&lt;p&gt;That experiment ended pretty quickly.&lt;/p&gt;

&lt;p&gt;The browser made it about 500 MB into downloading the 3.4 GB model before deciding it had had enough and killing the tab.&lt;/p&gt;

&lt;p&gt;So, there goes that idea.&lt;/p&gt;

&lt;p&gt;I could have switched to a cloud AI API and called it a day. But I really wanted to keep Gemma running locally, and I wasn't ready to give up on that part.&lt;/p&gt;

&lt;p&gt;So I came up with a different approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let the phone do the exploring and let the computer do the thinking.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The desktop browser loads Gemma and acts as a home base. Your phone connects to it and becomes the lightweight interface you actually carry around.&lt;/p&gt;

&lt;p&gt;When you submit a photo, it gets sent back to your home base, where Gemma evaluates it and generates the creature traits. The result then comes back to your phone.&lt;/p&gt;

&lt;p&gt;The model never has to run on the phone, and there's no cloud AI inference service involved.&lt;/p&gt;

&lt;p&gt;I also added some quest pre-generation. The home base prepares a little pool of quests and scavenger hunts ahead of time, so you don't have to stand around waiting for Gemma to think of something every time you want a new one.&lt;/p&gt;

&lt;p&gt;If you change your surroundings or conditions, the old quests get discarded and new ones are generated.&lt;/p&gt;

&lt;p&gt;And because I wanted the game to work when someone loses their signal, the mobile app saves unsent finds in IndexedDB and retries them once the connection returns.&lt;/p&gt;

&lt;p&gt;What started as a simple little outdoor game was suddenly turning into a whole phone-to-desktop AI system.&lt;/p&gt;

&lt;p&gt;You know how these things go. One little feature leads to another, and before you know it, you've built three extra systems just to make the original idea work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making the setup less ridiculous
&lt;/h3&gt;

&lt;p&gt;My original solution used a local Node server and a temporary Cloudflare tunnel to connect the phone to the desktop.&lt;/p&gt;

&lt;p&gt;It worked, and I actually kept that option in the project. You can still run it with &lt;code&gt;npm run home&lt;/code&gt; if you prefer a private, self-hosted setup.&lt;/p&gt;

&lt;p&gt;But then I started thinking about what it would be like for someone who just wanted to try the game.&lt;/p&gt;

&lt;p&gt;Imagine telling someone:&lt;/p&gt;

&lt;p&gt;"Hey, I made this cute little game where you go outside and find things. First, install Node, download some dependencies, run a server, start a tunnel, and pair your phone."&lt;/p&gt;

&lt;p&gt;Yeah. No.&lt;/p&gt;

&lt;p&gt;That's a lot of work just to go look for an interesting rock.&lt;/p&gt;

&lt;p&gt;So I added a hosted option to make the whole process easier.&lt;/p&gt;

&lt;p&gt;It uses a &lt;strong&gt;Cloudflare Worker&lt;/strong&gt; to relay messages between your phone and the home-base browser, &lt;strong&gt;D1&lt;/strong&gt; for account and quest data, and &lt;strong&gt;R2&lt;/strong&gt; for photo storage.&lt;/p&gt;

&lt;p&gt;You sign in with GitHub on your desktop, scan a temporary QR code with your phone, and you're connected.&lt;/p&gt;

&lt;p&gt;Your creature collection can also sync between your signed-in devices.&lt;/p&gt;

&lt;p&gt;The important part is that &lt;strong&gt;Cloudflare isn't running the AI model&lt;/strong&gt;. Gemma still runs locally in your desktop browser using your GPU. The hosted services just handle communication and storage.&lt;/p&gt;

&lt;p&gt;I also wanted to be clear about what happens to your data, because I think that's important when talking about local AI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Solo mode:&lt;/strong&gt; Your photos and game data stay in your browser's local storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted mode:&lt;/strong&gt; Photos go through the Cloudflare Worker and are stored in R2. You can delete your account, including its associated photos and records.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private home-base mode:&lt;/strong&gt; Your photos stay on your own computer instead of being stored in the hosted service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location:&lt;/strong&gt; The game doesn't track your GPS coordinates. If you enter a location, it's just text used to help Gemma create an appropriate quest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So while the AI inference is local, I'm not going to pretend that every part of the hosted experience is completely offline.&lt;/p&gt;

&lt;h3&gt;
  
  
  A few things I learned along the way
&lt;/h3&gt;

&lt;p&gt;One thing that surprised me about this project was how little of the actual work involved getting Gemma to generate text.&lt;/p&gt;

&lt;p&gt;That part was fun, of course. But once I got into the phone-to-desktop setup, I found myself spending a lot more time dealing with state synchronization, queued requests, connection handling, and making sure everything still behaved properly when one device went offline.&lt;/p&gt;

&lt;p&gt;Basically, all the less exciting stuff that has to work before you can enjoy the exciting stuff.&lt;/p&gt;

&lt;p&gt;I also ran into a particularly annoying issue with Cloudflare Worker requests.&lt;/p&gt;

&lt;p&gt;My tests were passing, but when I tried making requests through the actual Vite development proxy, I kept getting &lt;strong&gt;403 errors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It turned out that the test harness and development proxy were presenting different combinations of request URLs and &lt;code&gt;Origin&lt;/code&gt; headers. My origin validation was fine in the tests, but it was rejecting legitimate requests in the browser.&lt;/p&gt;

&lt;p&gt;The fix was to account for the request host or explicitly configured application origin, and to make sure I was testing through the actual development proxy rather than relying entirely on the test harness.&lt;/p&gt;

&lt;p&gt;A good reminder that passing tests don't necessarily mean everything works in the real world.&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;Vitest&lt;/strong&gt; for testing, including Wrangler's test harness with local D1 and R2 bindings for the Cloudflare Worker.&lt;/p&gt;

&lt;p&gt;Not quite as exciting as hatching adorable little creatures, but I suppose the plumbing has to work too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;This is actually one of my favorite things about building projects with open-weight models.&lt;/p&gt;

&lt;p&gt;I love experimenting with AI, especially when I can run models locally and figure out interesting ways to use them.&lt;/p&gt;

&lt;p&gt;And I think projects like Side Quest are a great example of why having access to those models matters.&lt;/p&gt;

&lt;p&gt;Sure, I could have built this game using a hosted vision API. It probably would have been easier in some ways.&lt;/p&gt;

&lt;p&gt;But then every quest, every photo evaluation, and every creature would mean another request to an external AI service.&lt;/p&gt;

&lt;p&gt;With Gemma, I can run the model directly on my own hardware, experiment with how it behaves, and build an entire little game around it without paying for every interaction.&lt;/p&gt;

&lt;p&gt;For the core solo experience, there's no account required, no external AI API, and no server processing your photos. The model runs right in your browser.&lt;/p&gt;

&lt;p&gt;And because the model is available to run myself, I can actually experiment with it.&lt;/p&gt;

&lt;p&gt;I can change the prompts, adjust the structured outputs, fine-tune how quests are judged, and try different approaches to generating creature traits. I could even experiment with other compatible models in the future.&lt;/p&gt;

&lt;p&gt;I'm not limited to whatever features a hosted API happens to expose.&lt;/p&gt;

&lt;p&gt;But I think the most interesting part of this project is how that freedom influenced the design.&lt;/p&gt;

&lt;p&gt;When I realized Gemma wasn't going to run on my phone, I didn't have to abandon local inference entirely.&lt;/p&gt;

&lt;p&gt;Instead, I found a way to use my desktop browser as a tiny personal AI server while my phone handles the actual gameplay.&lt;/p&gt;

&lt;p&gt;And I think that's pretty awesome.&lt;/p&gt;

&lt;p&gt;It also makes me wonder what else you could build using that same approach. A powerful local model running on one device, with lightweight interfaces connecting to it from somewhere else. There's a lot of room to experiment there.&lt;/p&gt;

&lt;p&gt;Of course, local AI isn't without its limitations. The model download is pretty hefty, you need hardware that can run it, and the optional hosted features still involve cloud services.&lt;/p&gt;

&lt;p&gt;But open-weight models give developers more choices about how to build things, and I love that.&lt;/p&gt;

&lt;p&gt;Not everything needs to be another app that sends a prompt to a paid API and displays the response.&lt;/p&gt;

&lt;p&gt;Sometimes you can get a little more creative with it.&lt;/p&gt;

&lt;p&gt;And in this case, I used an AI model to build a game that encourages people to spend &lt;em&gt;less&lt;/em&gt; time interacting with AI.&lt;/p&gt;

&lt;p&gt;I still find that pretty funny.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 4 E2B powers the core gameplay, including context-aware quest generation, multimodal photo judging, scavenger hunts, and creature trait generation. It runs locally in the browser using Transformers.js and WebGPU.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I had a lot of fun building this one!&lt;/p&gt;

&lt;p&gt;It turned out to be a bit more involved than I originally expected, especially once I decided that the game really needed to work on a phone. But figuring out how to make that happen while keeping Gemma running locally was probably the most interesting part of the whole project.&lt;/p&gt;

&lt;p&gt;And I genuinely love the little creatures. I could probably spend a lot of time just seeing what kinds of things Gemma comes up with from different photos.&lt;/p&gt;

&lt;p&gt;I also think it's nice to build something that's just meant to be fun.&lt;/p&gt;

&lt;p&gt;Not every AI project needs to automate your entire life, make you more productive, or solve some enormous problem.&lt;/p&gt;

&lt;p&gt;Sometimes it's perfectly fine to build something that just gets people to go outside and take pictures of leaves.&lt;/p&gt;

&lt;p&gt;If you give Side Quest a try, I'd love to hear what you think! And especially what kind of creatures you end up hatching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://side-quest.pinkpixel.dev" rel="noopener noreferrer"&gt;Play Side Quest&lt;/a&gt;&lt;/strong&gt; | &lt;strong&gt;&lt;a href="https://github.com/pinkpixel-dev/side-quest" rel="noopener noreferrer"&gt;Check out the source on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>showdev</category>
      <category>gemma</category>
    </item>
    <item>
      <title>Learning GPUI by Building My Own Text Editor</title>
      <dc:creator>Jessica Doering</dc:creator>
      <pubDate>Thu, 08 Oct 2026 21:30:39 +0000</pubDate>
      <link>https://dev.to/sizzlebop/learning-gpui-by-building-my-own-text-editor-2pmb</link>
      <guid>https://dev.to/sizzlebop/learning-gpui-by-building-my-own-text-editor-2pmb</guid>
      <description>&lt;p&gt;I've been wanting to experiment with &lt;a href="https://www.gpui.rs/" rel="noopener noreferrer"&gt;GPUI&lt;/a&gt; for a while now. It's the Rust UI framework developed for Zed, and I was curious what it would be like to use it for something of my own.&lt;/p&gt;

&lt;p&gt;So, naturally, I decided to build a text editor.&lt;/p&gt;

&lt;p&gt;Because apparently the best way to learn a new UI framework is to pick a project that already has about a million little details to get right.&lt;/p&gt;

&lt;p&gt;Anyway, the result is &lt;strong&gt;Slate&lt;/strong&gt;, a lightweight, native text editor for Linux, built with Rust and &lt;a href="https://gpui-kit.com/" rel="noopener noreferrer"&gt;GPUI Kit&lt;/a&gt;.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frf4xzh9ihdcf29j85eqb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frf4xzh9ihdcf29j85eqb.png" alt="Slate text editor" width="799" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why GPUI?
&lt;/h2&gt;

&lt;p&gt;Most of the desktop apps I've worked on have used web technologies, so I wanted to try something different.&lt;/p&gt;

&lt;p&gt;GPUI caught my attention because it's the framework behind &lt;a href="https://zed.dev/" rel="noopener noreferrer"&gt;Zed&lt;/a&gt;, and I really like the idea of building native desktop interfaces with Rust.&lt;/p&gt;

&lt;p&gt;Rather than having a web frontend wrapped in a desktop shell, GPUI lets you build the interface directly in Rust.&lt;/p&gt;

&lt;p&gt;Of course, that also means learning a different way of thinking about UI development.&lt;/p&gt;

&lt;p&gt;I was especially interested in seeing how practical it would be to build a complete application with it, rather than just experimenting with a few buttons and windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovering GPUI Kit
&lt;/h2&gt;

&lt;p&gt;One thing I quickly realized is that GPUI itself isn't a complete collection of ready-made application components.&lt;/p&gt;

&lt;p&gt;And writing an entire text editing component from scratch wasn't exactly what I had in mind.&lt;/p&gt;

&lt;p&gt;Thankfully, I found &lt;a href="https://github.com/longbridge/gpui-kit" rel="noopener noreferrer"&gt;GPUI Kit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;GPUI Kit provides a collection of components built on GPUI, including things like tabs, dialogs, menus, trees, themes, and most importantly for this project, an actual text editor component.&lt;/p&gt;

&lt;p&gt;That last part made a huge difference.&lt;/p&gt;

&lt;p&gt;Building a text editor involves a lot more than displaying text and responding to keyboard input. You need to deal with cursor movement, selections, undo history, syntax highlighting, multiple cursors, and all kinds of behavior that people expect to just work.&lt;/p&gt;

&lt;p&gt;GPUI Kit already handles much of that.&lt;/p&gt;

&lt;p&gt;It gave me a foundation to build on so I could focus on making the application I wanted rather than spending forever implementing basic editing functionality.&lt;/p&gt;

&lt;p&gt;That doesn't mean everything was plug-and-play, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Slate
&lt;/h2&gt;

&lt;p&gt;I wanted Slate to fit somewhere between a very basic text editor and a full-featured editor like Kate.&lt;/p&gt;

&lt;p&gt;Something I could open quickly to edit a config file, work on some Markdown, or browse a few source files without launching an entire IDE.&lt;/p&gt;

&lt;p&gt;I also wanted it to look nice. That's important to me, even with small utility apps.&lt;/p&gt;

&lt;p&gt;One of the things I particularly wanted was color-coded tabs. When I have a bunch of files open, I like being able to distinguish them at a glance.&lt;/p&gt;

&lt;p&gt;GPUI Kit has a tab component, but it didn't support the drag-and-drop reordering or colored accent lines I wanted.&lt;/p&gt;

&lt;p&gt;So I built Slate's tab strip myself using GPUI, while still using Kit's components for things like context menus and tooltips.&lt;/p&gt;

&lt;p&gt;That ended up being a pretty good example of how I approached the project: use GPUI Kit wherever it made sense, then build the parts that needed something different.&lt;/p&gt;

&lt;p&gt;The same thing happened with the find and replace bar. GPUI Kit already has the underlying search functionality, but I wanted the interface to sit neatly above the editor instead of floating over it.&lt;/p&gt;

&lt;p&gt;So I reused Kit's search engine and built my own interface around it.&lt;/p&gt;

&lt;p&gt;I actually enjoyed that flexibility quite a bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some things I learned along the way
&lt;/h2&gt;

&lt;p&gt;Working with GPUI and GPUI Kit was interesting, but there were definitely some challenges.&lt;/p&gt;

&lt;p&gt;One of the biggest lessons was learning to work within the public APIs that the component library exposes.&lt;/p&gt;

&lt;p&gt;For example, GPUI Kit supports multiple cursors, but the version I'm using doesn't expose a public method for programmatically adding a selection at a specific range.&lt;/p&gt;

&lt;p&gt;That meant a feature I wanted, &lt;code&gt;Ctrl+D&lt;/code&gt; to select the next occurrence of some text, wasn't something I could easily implement without modifying the library.&lt;/p&gt;

&lt;p&gt;It's on hold for now.&lt;/p&gt;

&lt;p&gt;Another interesting challenge was the minimap.&lt;/p&gt;

&lt;p&gt;I wanted a little overview of the file along the right side, similar to what you see in VS Code.&lt;/p&gt;

&lt;p&gt;The problem was that GPUI Kit's editor doesn't expose all the layout and syntax information needed to draw one directly.&lt;/p&gt;

&lt;p&gt;I ended up creating a custom minimap using GPUI's canvas rendering, with a separate syntax highlighter providing the colors.&lt;/p&gt;

&lt;p&gt;There's also a catch with wrapped lines. Without access to the editor's exact line layout, the minimap's viewport indicator wouldn't always line up correctly.&lt;/p&gt;

&lt;p&gt;Rather than leave something that behaved incorrectly, I decided to hide the minimap when word wrap is enabled.&lt;/p&gt;

&lt;p&gt;Not the most exciting compromise, but it works reliably.&lt;/p&gt;

&lt;p&gt;I ran into some other interesting issues with theme reloading, file watching, keyboard events, and Linux window behavior.&lt;/p&gt;

&lt;p&gt;These are exactly the kinds of details that are easy to overlook until you're building an application that needs to handle them.&lt;/p&gt;

&lt;p&gt;And honestly, working through those problems was a big part of why I wanted to try this project in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Slate can do now
&lt;/h2&gt;

&lt;p&gt;Even though I started Slate as a way to learn GPUI, it ended up becoming a pretty capable little editor.&lt;/p&gt;

&lt;p&gt;Some of the features in the first release include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Syntax highlighting for 23 languages&lt;/strong&gt;, powered by Tree-sitter through GPUI Kit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple tabs&lt;/strong&gt;, including drag-and-drop reordering and customizable tab colors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;39 built-in themes&lt;/strong&gt;, including Catppuccin, Gruvbox, Tokyo Night, and several Slate-specific themes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File sidebar&lt;/strong&gt; with automatic updates, folder navigation, and hidden-file controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find and replace&lt;/strong&gt;, Quick Open, and a searchable command palette&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session restore&lt;/strong&gt;, including unsaved edits, so you can pick up where you left off&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live Markdown preview&lt;/strong&gt; in a split view&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syntax-colored minimap&lt;/strong&gt; for navigating longer files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clickable color swatches&lt;/strong&gt; for editing hex, RGB, and HSL colors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File change detection&lt;/strong&gt;, including the ability to compare your edits against the version on disk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are plenty of smaller conveniences too, like line duplication, moving lines up and down, comment toggling, indentation detection, and opening files directly from the terminal.&lt;/p&gt;

&lt;p&gt;I also made the themes customizable. You can drop a JSON theme file into Slate's themes folder and edit it while the app is running. Slate watches for changes and updates the appearance automatically.&lt;/p&gt;

&lt;p&gt;That was a particularly fun feature to get working.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first release is available
&lt;/h2&gt;

&lt;p&gt;Slate 1.0 is now available on &lt;a href="https://github.com/pinkpixel-dev/slate" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's currently Linux-only, and I've been developing and testing it on CachyOS with the COSMIC desktop.&lt;/p&gt;

&lt;p&gt;If you're using Arch or an Arch-based distribution, you can install it from the AUR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-S&lt;/span&gt; slate-editor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if you'd rather build it yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/pinkpixel-dev/slate.git
&lt;span class="nb"&gt;cd &lt;/span&gt;slate
cargo run &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll need Rust 1.92 or newer and a working Vulkan driver. I've included more detailed requirements and instructions in the README.&lt;/p&gt;

&lt;p&gt;And since this is the first release, I definitely wouldn't claim it's perfect. I've only tested it on my own desktop environment so far, and I'm sure there are things that will need adjusting as it gets used on other systems.&lt;/p&gt;

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

&lt;p&gt;I'm happy with how the first version turned out, but I don't consider Slate finished.&lt;/p&gt;

&lt;p&gt;There are still features and improvements I'd like to explore, especially as GPUI Kit continues developing and potentially exposes more of its editor functionality.&lt;/p&gt;

&lt;p&gt;At the same time, I don't want Slate to turn into another full IDE.&lt;/p&gt;

&lt;p&gt;There are already plenty of excellent editors that do that.&lt;/p&gt;

&lt;p&gt;My goal is to keep it lightweight, useful, and pleasant to work with. Something that does the everyday editing stuff really well without needing a hundred additional features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Building Slate gave me a much better understanding of GPUI and what it's like to develop a native desktop application with Rust.&lt;/p&gt;

&lt;p&gt;I also came away with a lot of appreciation for how much work goes into something as seemingly simple as a text editor.&lt;/p&gt;

&lt;p&gt;It's one of those applications where the interface might look straightforward, but there's an incredible amount happening underneath.&lt;/p&gt;

&lt;p&gt;GPUI Kit made this project much more approachable, and having the option to mix its existing components with custom GPUI interfaces was probably my favorite part of working with it.&lt;/p&gt;

&lt;p&gt;I'm definitely interested in experimenting with GPUI some more.&lt;/p&gt;

&lt;p&gt;If you're curious about the project, the source code is available here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/pinkpixel-dev/slate" rel="noopener noreferrer"&gt;Slate on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And if you've worked with GPUI or GPUI Kit yourself, I'd love to hear what your experience has been like!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>opensource</category>
      <category>linux</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
