<?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: Vincenzo</title>
    <description>The latest articles on DEV Community by Vincenzo (@vikkio88).</description>
    <link>https://dev.to/vikkio88</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2898%2Ff0bf0c6f-0f56-4b87-a595-1095c669c3f1.png</url>
      <title>DEV Community: Vincenzo</title>
      <link>https://dev.to/vikkio88</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vikkio88"/>
    <language>en</language>
    <item>
      <title>Omarcacca</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Wed, 21 Jan 2026 15:51:20 +0000</pubDate>
      <link>https://dev.to/vikkio88/omarcacca-2g8p</link>
      <guid>https://dev.to/vikkio88/omarcacca-2g8p</guid>
      <description>&lt;p&gt;"Empty barrels always make the most sound" says my co-national Alborosie in &lt;a href="https://open.spotify.com/track/3v41srJ4jzBxzN066bfu9N?si=592fa82e98cf47f9" rel="noopener noreferrer"&gt;Poser&lt;/a&gt;, and I thought this would not apply to &lt;a href="https://dhh.dk/" rel="noopener noreferrer"&gt;DHH&lt;/a&gt;, the creator of &lt;a href="https://rubyonrails.org/" rel="noopener noreferrer"&gt;Ruby on Rails&lt;/a&gt;, because he is not only noisy about his opinions, he is friggin loud as f***.&lt;/p&gt;

&lt;p&gt;I had heard of him a few times before, and only in the last few years really followed him in some interviews/posts where he was just going always in &lt;a href="https://open.spotify.com/album/6W4yNRsa7NUHBQZU27oB8Q?si=cqBGrgWhR2C_KkC807G7ww" rel="noopener noreferrer"&gt;&lt;br&gt;
in an obstinate and contrary direction&lt;/a&gt; (to quote another italian singer/songwriter).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://world.hey.com/dhh/we-have-left-the-cloud-251760fb" rel="noopener noreferrer"&gt;They&lt;/a&gt; left the cloud in 2023.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://world.hey.com/dhh/turbo-8-is-dropping-typescript-70165c01" rel="noopener noreferrer"&gt;They&lt;/a&gt; stopped using typescript.
... and much more, that blog is a goldmine of opinionated opinions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have been using linux since 2006.&lt;br&gt;
Ubuntu, Debian, Slackware, Arch then Ubuntu again, and I have been a big fan of minimal UI/WM/DE since forever.&lt;/p&gt;

&lt;p&gt;In 2008 I started using a netbook, an &lt;a href="https://en.wikipedia.org/wiki/Asus_Eee_PC" rel="noopener noreferrer"&gt;ASUS Eee PC&lt;/a&gt; and since RAM was scarse I had to find a better way to provide myself access to tools, so I discovered and fell in love with &lt;a href="https://fluxbox.org/" rel="noopener noreferrer"&gt;fluxbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Loved it, even wrote a guide on how to configure it (is &lt;a href="https://github.com/ItalianHackersEmbassy/ancient-ezines/blob/aa5cb421463f0fd054ca99746bc4401e7535fe7e/UnderAttHack/num_1.pdf" rel="noopener noreferrer"&gt;here&lt;/a&gt; in Italian).&lt;/p&gt;

&lt;p&gt;When I got less time on my hand I moved to &lt;a href="https://www.xfce.org/" rel="noopener noreferrer"&gt;XFCE&lt;/a&gt; and then just plain &lt;a href="https://www.gnome.org/" rel="noopener noreferrer"&gt;GNOME&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then few years back, in 2015, I got shown &lt;a href="https://i3wm.org/" rel="noopener noreferrer"&gt;i3wm&lt;/a&gt; and used it on my ubuntu-netinstall until 2020, then I switched to &lt;a href="https://ubuntubudgie.org/" rel="noopener noreferrer"&gt;Budgie&lt;/a&gt; and my personal laptop has been using that ever since.&lt;/p&gt;

&lt;p&gt;So yeah I am no DE/WM/Tiling/Linux virgin.&lt;/p&gt;

&lt;p&gt;When last year, around August 2025, I saw that &lt;strong&gt;DHH&lt;/strong&gt; was coming out with a "distro" based on &lt;strong&gt;Arch&lt;/strong&gt; I assumed it would be nice to check it out, so I did.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://omarchy.org/" rel="noopener noreferrer"&gt;Omarchy&lt;/a&gt; looked amazing, it had some rough edges but had everything I needed, and it was flying.&lt;/p&gt;

&lt;p&gt;The most amazing thing I found was the tiling system which I missed so much and did not even realised.&lt;/p&gt;

&lt;p&gt;Few weeks in the first few cracks started to show, as I posted on bluesky &lt;a href="https://bsky.app/profile/vikkio.bsky.social/post/3lzihfyes2s2j" rel="noopener noreferrer"&gt;here&lt;/a&gt;, I had an amazingly looking desktop, but way too many tools that I did not need/want.&lt;br&gt;
Namely: 1Password, Neovim, kdenlive, office, obstudio, obs-studio, whatsapp, Bitwarden, ProtoVPN and a bunch of webapps (HEY, Basecamp, X) that I do not want nor use.&lt;/p&gt;

&lt;p&gt;I found that tool to remove it, but then every few updates I got given something new I did not need. Something else broke, and even though I love to touch configurations I prefer to do it on my own ones, rather than the opinionated one of someone else.&lt;/p&gt;

&lt;p&gt;I had issues where new tools like clipboard manager started to kill some of my personal tools, &lt;a href="https://github.com/vikkio88/ntrallazzu" rel="noopener noreferrer"&gt;ntrallazzu&lt;/a&gt;, then keybinds changed on update and conflicted with some of my custom ones.&lt;/p&gt;

&lt;p&gt;Then &lt;a href="https://github.com/basecamp/omarchy/issues/3891#issuecomment-3702274236" rel="noopener noreferrer"&gt;videos&lt;/a&gt; were not playing on brave/chrome and would only do that if I run it with a custom command, but that broke all of the other webapps.&lt;/p&gt;

&lt;p&gt;I setup my editor to be &lt;a href="https://zed.dev" rel="noopener noreferrer"&gt;zed&lt;/a&gt; instead of neovim but it was still no applying properly for config updates, since it was always using neovim.&lt;/p&gt;

&lt;p&gt;Lastly, two of the applications I use every now and then do not work properly with it at all, &lt;a href="https://godotengine.org/" rel="noopener noreferrer"&gt;Godot4&lt;/a&gt; and &lt;a href="https://www.arduino.cc/en/software/" rel="noopener noreferrer"&gt;ArduinoIDE&lt;/a&gt; are just completely broken and had to jump through so many hoops to just make it work.&lt;/p&gt;

&lt;p&gt;The straw that broke the camels back was forced install of &lt;a href="https://learn.omacom.io/2/the-omarchy-manual/107/ai" rel="noopener noreferrer"&gt;OpenCode&lt;/a&gt;, and then a bunch of more AI things which I never asked for.&lt;/p&gt;

&lt;p&gt;I had enough, I hate microsoft approach of pushing Copilot into things, I am a big &lt;strong&gt;ChatGPT&lt;/strong&gt; user, but I do not want all of that rubbish pre-installed, I just realised that I was in only for the hype and the &lt;a href="https://jie-fang.github.io/blog/basics-of-ricing" rel="noopener noreferrer"&gt;rice&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;F*** that.&lt;/p&gt;

&lt;p&gt;I wiped and installed &lt;a href="https://xubuntu.org/" rel="noopener noreferrer"&gt;xubuntu&lt;/a&gt; minimal, I setup the tiling keybinds, installed a few of the packages I needed, it took me 2 hours in total, instead of the days I spent to setup and chisel away crap I did not need out of &lt;strong&gt;Omarchy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you know what you are doing it wont take much to setup and get your own DE/WM the way you want it, without the opinionated crap someone elses likes to dump on their crappy system.&lt;/p&gt;

&lt;p&gt;Peace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vikkio88/dotfiles/blob/main/xfce/_config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml" rel="noopener noreferrer"&gt;My XFCE keybinds&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/vikkio88/dotfiles/blob/main/xfce/_config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml" rel="noopener noreferrer"&gt;My Panel/Apps Setup&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh forgot, doing webapps is simple as fuck, just bind the keys to &lt;code&gt;brave (or chrome) --app=URL --new-window&lt;/code&gt; done.&lt;/p&gt;

</description>
      <category>omarchy</category>
      <category>ubuntu</category>
      <category>archlinux</category>
      <category>linux</category>
    </item>
    <item>
      <title>My 2025 Tech Resolutions and My Plan for 2026</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Thu, 15 Jan 2026 09:20:20 +0000</pubDate>
      <link>https://dev.to/vikkio88/my-2025-tech-resolutions-and-my-plan-for-2026-4c4o</link>
      <guid>https://dev.to/vikkio88/my-2025-tech-resolutions-and-my-plan-for-2026-4c4o</guid>
      <description>&lt;p&gt;Sup people, last year I posted &lt;a href="https://dev.to/vikkio88/auto-y2025-new-year-resolutions-5fj5"&gt;this&lt;/a&gt; about my 2025 tech year resolutions, so a tech version of things I want to do/learn/try on the next year, and now that I've got a few minutes to reflect I will be doing it in here.&lt;/p&gt;

&lt;h2&gt;
  
  
  2024
&lt;/h2&gt;

&lt;p&gt;In 2024 I said I would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn Rust (for real this time), I abandoned it twice before.
✅❌&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;finish at least one of those sideprojects, or if not finish at least release it in a usable state.&lt;br&gt;
✅&lt;br&gt;
I had finished (and use them daily) 3 of them: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/ntrallazzu" rel="noopener noreferrer"&gt;Ntrallazzu&lt;/a&gt;: a cli tool to manage your sideproject folders, this one I even rewrote it twice, and converted to Typescript.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/kiffari" rel="noopener noreferrer"&gt;Kiffari/kato&lt;/a&gt;: a notion clone meets obsidian but selfhosted and can do jira-like project management. This one is my first seriously big project written with Svelte and Go.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/tinchi" rel="noopener noreferrer"&gt;tinchi&lt;/a&gt;: a kind of little css generator for utilities, a mix of &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;tailwind&lt;/a&gt; and &lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;finish that football manager game you have been working on for the last 10 years with all of the programming languages.&lt;br&gt;&lt;br&gt;
❌&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;finish the &lt;a href="https://godotengine.org/" rel="noopener noreferrer"&gt;Godot4&lt;/a&gt; course and try release a game after that.&lt;br&gt;&lt;br&gt;
❌ I had started really well, but sort of lost interest.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;start to learn something new not tech related necessarily. ✅ &lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I started learning Japanese. Mostly using Duolingo at first, then I bought and read quite a lot of &lt;a href="https://genki3.japantimes.co.jp/en/" rel="noopener noreferrer"&gt;Genki&lt;/a&gt; and &lt;a href="https://www.fromzero.com/" rel="noopener noreferrer"&gt;Japanese from Zero&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also made &lt;a href="https://nisenotori.surge.sh/" rel="noopener noreferrer"&gt;Nise no Tori(Fake Bird)&lt;/a&gt; (&lt;a href="https://github.com/vikkio88/nisenotori" rel="noopener noreferrer"&gt;source&lt;/a&gt;), a little rip off of a few little games to learn Hiragana/Katakana.&lt;/p&gt;

&lt;h2&gt;
  
  
  2025
&lt;/h2&gt;

&lt;p&gt;One of the things I realised in 2025 is that I promised too much for 2024, so I went down another route, promise less.&lt;/p&gt;

&lt;p&gt;How did it go?&lt;/p&gt;

&lt;h3&gt;
  
  
  Become proficient in Rust.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Finish again &lt;a href="https://doc.rust-lang.org/book/" rel="noopener noreferrer"&gt;The Book&lt;/a&gt;. ✅&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finish again the &lt;a href="https://github.com/rust-lang/rustlings" rel="noopener noreferrer"&gt;rustlings&lt;/a&gt;. ✅&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make a Game in Rust with &lt;a href="https://sokoban.iolivia.me/" rel="noopener noreferrer"&gt;this&lt;/a&gt;, as suggested to me by the creator of that guide &lt;a href="https://bsky.app/profile/iolivia.me/post/3lejhbeb5zk2o" rel="noopener noreferrer"&gt;here&lt;/a&gt; ❌&lt;/p&gt;

&lt;p&gt;Did not even touch this :(&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rewrite &lt;a href="https://dev.to/vikkio88/fyne-ill-do-it-myself-adventures-in-desktop-app-development-2di1"&gt;Muscurdi - Password Manager&lt;/a&gt; in Rust with &lt;a href="https://github.com/iced-rs/iced" rel="noopener noreferrer"&gt;iced&lt;/a&gt;, &lt;a href="https://github.com/dioxuslabs/dioxus" rel="noopener noreferrer"&gt;dioxus&lt;/a&gt; and/or &lt;a href="https://github.com/tauri-apps/tauri" rel="noopener noreferrer"&gt;tauri&lt;/a&gt; ❌&lt;/p&gt;

&lt;p&gt;Did not any of those, but I have explored &lt;strong&gt;tauri&lt;/strong&gt; and I am some ideas on some other sideprojects with it.&lt;br&gt;
I did a little &lt;a href="https://github.com/vikkio88/tauri-svelte-todos" rel="noopener noreferrer"&gt;todo-app&lt;/a&gt; in tauri and &lt;strong&gt;svelte&lt;/strong&gt; with a little persistence layer and it is lovely.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Release a little cli tool (maybe a &lt;a href="https://github.com/vikkio88/hygenTemplates" rel="noopener noreferrer"&gt;hygen templates&lt;/a&gt; parser) in Rust. ❌✅&lt;/p&gt;

&lt;p&gt;Released, and I only started on it recently: &lt;a href="https://github.com/vikkio88/ruetta" rel="noopener noreferrer"&gt;ruetta&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Game Programming
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Finish that Godot4 &lt;a href="https://www.gdquest.com/" rel="noopener noreferrer"&gt;course&lt;/a&gt;. ❌&lt;/p&gt;

&lt;p&gt;Did not, too verbose and boring.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finish &lt;a href="https://github.com/vikkio88/nigghiazza" rel="noopener noreferrer"&gt;that&lt;/a&gt; little 2d shooter in Godot. ❌&lt;/p&gt;

&lt;p&gt;Nope&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finish fdSimWeb and see whether is a good idea. ❌&lt;/p&gt;

&lt;p&gt;Nope&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finish &lt;a href="https://github.com/vikkio88/sokkera" rel="noopener noreferrer"&gt;Sokkera&lt;/a&gt; (a little turn based soccer/football game). ❌&lt;/p&gt;

&lt;p&gt;Nopety Nope&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rewrite &lt;a href="https://github.com/vikkio88/ammishka" rel="noopener noreferrer"&gt;Ammishka&lt;/a&gt;, a little WS turn based game framework, in typescript (maybe using deno instead of bun). ✅&lt;/p&gt;

&lt;p&gt;I did &lt;a href="https://github.com/vikkio88/alicarti" rel="noopener noreferrer"&gt;alicarti&lt;/a&gt;, in &lt;strong&gt;bun&lt;/strong&gt; and &lt;strong&gt;svelte&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Side Projects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Write a little Mobile Client for Kato/Kiffari (either react native or kotlin). ✅&lt;/p&gt;

&lt;p&gt;I did better, I wrote a whole new system that uses ideas from Kato but works alongside the codebase you are using storing info in markdown files: &lt;a href="https://dev.to/vikkio88/keep-your-tickets-with-your-code-4iah"&gt;kiffarino&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Little Web interface to publish/read comic books on a static hosting provider. ❌&lt;/p&gt;

&lt;p&gt;Nope&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learning
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Finish at lease one of those courses on Blender you own. ❌&lt;/p&gt;

&lt;p&gt;Did not even install Blender&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Study Statistics, and Applied Statistics. ❌✅&lt;/p&gt;

&lt;p&gt;I did start &lt;strong&gt;Brilliant&lt;/strong&gt; but as all of the learning apps they are just engagement thiefs rather than actual learning tools.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Continue Studying Japanese with the aim to be able to watch some anime without subtitles. ✅&lt;/p&gt;

&lt;p&gt;I did, I have my 650+ days streak on Japanese, but Duolingo is not enough.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Learn a bit of Korean, at least the alphabet and the writing system. ❌✅&lt;/p&gt;

&lt;p&gt;Tried hindi, Arabic and Korean. already forgot everything :D&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Learn and use &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;Neovim&lt;/a&gt;. ❌&lt;/p&gt;

&lt;p&gt;I tried, but then I switched to &lt;a href="https://dev.to/vikkio88/switching-to-zed-made-my-own-vscode-rest-utility-788"&gt;zed&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finish a drawing class/course and start to publish some comic books/comic strips somewhere. ❌&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I did not manage to do much more on this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;So in 2024 I did 2.5/5 things I promised myself I would.&lt;/p&gt;

&lt;p&gt;In 2025 I was a bit more granular and did 5.5/18.&lt;/p&gt;

&lt;p&gt;So from 50% of something really hard I went to 30% of something really granular and spread around load of domains.&lt;/p&gt;

&lt;p&gt;If feels not too much, but I have to say that I have done much more than that, only it was not on my radar when I started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn Zig.&lt;/p&gt;

&lt;p&gt;Did a course, and exercism, never got productive in it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uninstalled Instagram and replaced it with some more learning apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finished a couple of courses on &lt;a href="https://mimo.org/" rel="noopener noreferrer"&gt;Mimo&lt;/a&gt;, Python, Typescript and SQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;revamped and migrated some of my utility tools to bun:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/tinchi" rel="noopener noreferrer"&gt;tinchi&lt;/a&gt; - my personal css framework&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/ntrallazzu" rel="noopener noreferrer"&gt;ntrallazzu&lt;/a&gt; - a source code management tool&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;spiked back my interest in hardware programming, I used back some of the Arduino tools I had brought in 2012.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;switched away from VsCode to zed, I wrote about it in &lt;a href="https://dev.to/vikkio88/switching-to-zed-made-my-own-vscode-rest-utility-788"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  2026 - Here I come with more promises that will be broken
&lt;/h2&gt;

&lt;p&gt;I will now formulate them as if I was speaking to myself, maybe doing so it will be more impactful?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For god sake finish a game dev project and publish it on itch.io.&lt;/li&gt;
&lt;li&gt;Keep rust fresh on your mind and maybe migrate more of your tools to rust.&lt;/li&gt;
&lt;li&gt;Try for real this time to dedicate some time to try out Drawing.&lt;/li&gt;
&lt;li&gt;Make and publish somewhere a post about an hardware prototyping project.&lt;/li&gt;
&lt;li&gt;Maybe stop wasting time on Duolingo and try out a real Japanese course?&lt;/li&gt;
&lt;li&gt;Try to develop a &lt;a href="https://zed.dev/" rel="noopener noreferrer"&gt;Zed&lt;/a&gt; extension.&lt;/li&gt;
&lt;li&gt;Keep an open mind about agentic editors, but keep doing what you enjoy/makes you more productive, do not fall for the FOMO.&lt;/li&gt;
&lt;li&gt;Consume less short-video-format content and read/write more blog posts and watch longer videos.&lt;/li&gt;
&lt;li&gt;Try to refresh some Advanced Math/Statistics with pen and paper exercises.&lt;/li&gt;
&lt;li&gt;Keep spitting out sideprojects, getting those live makes you happy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and that is all, see you in 2027.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>rust</category>
      <category>sideprojects</category>
      <category>devresolutions2026</category>
    </item>
    <item>
      <title>Switching to Zed: Made my own VSCode-Rest utility</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Tue, 25 Nov 2025 11:25:53 +0000</pubDate>
      <link>https://dev.to/vikkio88/switching-to-zed-made-my-own-vscode-rest-utility-788</link>
      <guid>https://dev.to/vikkio88/switching-to-zed-made-my-own-vscode-rest-utility-788</guid>
      <description>&lt;p&gt;I &lt;a href="https://dev.to/vikkio88/how-i-use-llms-badvibez-coding-42o8"&gt;expressed my opinion&lt;/a&gt; about &lt;em&gt;vibecoding&lt;/em&gt; and LLM &lt;em&gt;usage&lt;/em&gt; before, and since then the dev world has gone batshit crazy about it and now every editor, OS, webapp, forces you into having to interact with a stupid AI agent that most of the time is freaking useless.&lt;/p&gt;

&lt;p&gt;AGAIN, I use LLMs (specifically ChatGPT) day in and out, to do boring stuff, like creating tests or solving specifically small problems I can't be bothered to copy paste. ChatGPT is my StackOverflow, I want it out of my editor and possibly on my browser.&lt;/p&gt;

&lt;p&gt;Unfortunately &lt;strong&gt;vscode&lt;/strong&gt;, one day, decided to break my &lt;a href="https://www.youtube.com/watch?v=VmFOsK7IhI4" rel="noopener noreferrer"&gt;VSCode Minimal Setup&lt;/a&gt; I had run for the last few years to add bloody CoPilot bars, tabs and crap all over the place.&lt;/p&gt;

&lt;p&gt;I had enough, so decided to give a serious go to &lt;a href="https://zed.dev/" rel="noopener noreferrer"&gt;zed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I had only used it to try out a faster and more modern vim, so I had activated the &lt;code&gt;vim-mode&lt;/code&gt; and gone ahead and done some coding for a couple of days, then I just uninstalled it.&lt;/p&gt;

&lt;p&gt;after the situation with VSCode ended up like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dbcm43b9e745u6iv4go.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dbcm43b9e745u6iv4go.jpg" alt=" " width="590" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decided to give it another go, especially for an amazing feature, which is vscode is not so obvious.&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.amazonaws.com%2Fuploads%2Farticles%2F5at8mu30wpx2kophifbd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5at8mu30wpx2kophifbd.png" alt=" " width="800" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;or if you speak &lt;code&gt;settings.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"agent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeah I know, Agentic shit is enabled by default, but it has one switch.&lt;br&gt;
I am ok with that approach, I mean, I use &lt;a href="https://brave.com/" rel="noopener noreferrer"&gt;brave&lt;/a&gt; as a browser and I always have to turn off all that crypto rubbish they have leftovers from the good old days where the hypetrain was bloody NFT and CryptoCrap.&lt;/p&gt;

&lt;p&gt;Anyhow, I spent more than 2 weeks using only &lt;code&gt;zed&lt;/code&gt; instead of vscode and I found just a few little issues, but loads of improvements.&lt;/p&gt;

&lt;p&gt;I just set it up to use vscode keybinds and customised the one I had customised in vscode.&lt;/p&gt;

&lt;p&gt;The UI is fast and responsive, it loads superfast both on Linux and Mac, it supports &lt;a href="https://zed.dev/docs/languages" rel="noopener noreferrer"&gt;most languages natively&lt;/a&gt;, without any extensions, I know right?&lt;/p&gt;
&lt;h3&gt;
  
  
  Svelte
&lt;/h3&gt;

&lt;p&gt;The only one I had to install was the &lt;a href="https://zed.dev/docs/languages/svelte" rel="noopener noreferrer"&gt;Svelte language server&lt;/a&gt; with their extension.&lt;/p&gt;
&lt;h3&gt;
  
  
  Finding stuff in .env
&lt;/h3&gt;

&lt;p&gt;By default if you file is in &lt;code&gt;.gitignore&lt;/code&gt; the filescan wont show it nor you can search it, but you can fix it with this setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"file_scan_inclusions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"public/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"data/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".env*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Anything missing?
&lt;/h3&gt;

&lt;p&gt;I was shocked to see how productive I was with little to no extensions installed, until I hit 2 "hurdles".&lt;/p&gt;

&lt;h2&gt;
  
  
  Hurdle 1: Debug
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Debug Tests
&lt;/h3&gt;

&lt;p&gt;I have not had an absolute necessity to debug &lt;code&gt;vitest&lt;/code&gt;, but that is something I use a lot, and I cannot find a way to make it work properly, but have not put myself into it too much.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debug Bun
&lt;/h3&gt;

&lt;p&gt;I use &lt;a href="https://bun.sh/" rel="noopener noreferrer"&gt;bun&lt;/a&gt; for all of my sideprojects, and debugging the main flow works (better than in vscode), but I cannot find for the life of me a way to debug bun:tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hurdle 2: VSCode-rest
&lt;/h2&gt;

&lt;p&gt;I use a nice &lt;strong&gt;vscode&lt;/strong&gt; extension called &lt;a href="https://github.com/Huachao/vscode-restclient" rel="noopener noreferrer"&gt;vscode-rest&lt;/a&gt; and I love it.&lt;/p&gt;

&lt;p&gt;I plop loads of those &lt;code&gt;.http&lt;/code&gt; &lt;a href="https://github.com/vikkio88/kiffarino/blob/main/be/rest/tickets.http" rel="noopener noreferrer"&gt;files&lt;/a&gt; in all of my sideprojects.&lt;/p&gt;

&lt;p&gt;Those files are just a set of http calls, and their setup, they allow me to test some endpoint without switching out of the editor.&lt;/p&gt;

&lt;p&gt;Pity that there was no extension that supports that syntax so I did what every dev on a sideproject does... starts another sideproject to help with the first sideproject.&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.amazonaws.com%2Fuploads%2Farticles%2Fnzcosbgdunvcyn1myczu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnzcosbgdunvcyn1myczu.jpg" alt=" " width="502" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  POSO
&lt;/h2&gt;

&lt;p&gt;I read some info on how to make a &lt;a href="https://zed.dev/docs/extensions/developing-extensions" rel="noopener noreferrer"&gt;zed extension&lt;/a&gt; but it was too long and I decided I NEEDED it NOW.&lt;/p&gt;

&lt;p&gt;So I went off and as I have done with a couple of my side projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/tinchi" rel="noopener noreferrer"&gt;tinchi&lt;/a&gt; - my own compact tailwind&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/ntrallazzu" rel="noopener noreferrer"&gt;ntrallazzu&lt;/a&gt; - my project launcher&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vikkio88/kiffarino" rel="noopener noreferrer"&gt;kiffarino&lt;/a&gt; - my local md files based jira (wrote a post about it &lt;a href="https://dev.to/vikkio88/keep-your-tickets-with-your-code-4iah"&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I created a cli tool installable via &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have build (or migrated to) all of those tools with &lt;strong&gt;bun&lt;/strong&gt;, so I can use typescript without having to build, but then I compile them to a single javascript file that I push to npm.&lt;/p&gt;

&lt;p&gt;I used this pattern so much that I created a little &lt;a href="https://github.com/vikkio88/bun-node-cli-template" rel="noopener noreferrer"&gt;template&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;Anywho what did I want here?&lt;/p&gt;

&lt;p&gt;I just wanted to re-use my &lt;code&gt;http&lt;/code&gt; files really, nothing more complex than that.&lt;/p&gt;

&lt;p&gt;those files are structured like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;### getOne
get http://localhost:3003/api/tickets/01JZ5WE7A0RQTNFY0B188D8HVG

### link
POST  http://localhost:3003/api/tickets/01JZ8CRNQ7S69AHR9X541A97ZR/link
Content-Type: "application/json"

{
    "type": "linked",
    "linkedId": "01JZ8E15XQ8CZ71KXKJT6TXDG6"
}

### unlink
DELETE  http://localhost:3003/api/tickets/01JZ5WE7A1ZKRXG2WW1DWFPJPQ/link/01JZ5WE7A0RQTNFY0B188D8HVG

### udpate
PUT  http://localhost:3003/api/tickets/01JYRK01WZ69BYMSTDHMM5QR80
Content-Type: "application/json"

{
    "type": "bug",
    "status": "inProgress"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;they have sections, you can specify named requests and add body and headers.&lt;/p&gt;

&lt;p&gt;Another thing you can do is specify variables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@apiUrl = my.api.com/api
@someStuff = 185

GET {{apiUrl}}/things/{{someStuff}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and, if you are a poweruser you can calculate those vars from other requests.&lt;/p&gt;

&lt;p&gt;I decided that it was a bit too complicated to start with that depth of support so I focussed on the simpler cases of hardcoded vars, that you could overwrite via flags.&lt;/p&gt;

&lt;p&gt;But yeah, few days in and I've got a &lt;a href="https://www.npmjs.com/package/poso?activeTab=readme" rel="noopener noreferrer"&gt;poso&lt;/a&gt; that can be used.&lt;/p&gt;

&lt;p&gt;And the code is &lt;a href="https://github.com/vikkio88/poso#readme" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now I can forget about vscode, until I find the next hurdle.&lt;/p&gt;

</description>
      <category>zed</category>
      <category>bunjs</category>
      <category>rest</category>
      <category>vscode</category>
    </item>
    <item>
      <title>How I use LLMs: BadVibez Coding</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Sat, 12 Jul 2025 12:24:51 +0000</pubDate>
      <link>https://dev.to/vikkio88/how-i-use-llms-badvibez-coding-42o8</link>
      <guid>https://dev.to/vikkio88/how-i-use-llms-badvibez-coding-42o8</guid>
      <description>&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;LLMs save time and reduce friction, but they do not replace experience. Use them to speed up the parts you already understand, not to blindly build what you cannot explain. Otherwise you might get dumber and lose touch with how things work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve been coding for about 20 years, professionally since around 2009.&lt;/p&gt;

&lt;p&gt;I’ve seen a lot of change in that time. Not as much as someone who lived through the dot-com bubble, but certainly more than people who’ve only ever worked with React.&lt;/p&gt;

&lt;p&gt;I also have a Bachelor's Degree in Computer Engineering (Laurea Triennale in Ingegneria Informatica), so I’ve studied serious math and physics. But what has shaped me most is not just education, it’s the projects, the missteps, and the way the industry keeps evolving.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Last Few Years Feel Different. But Are They?
&lt;/h3&gt;

&lt;p&gt;The past two years, especially the last one, have felt like something big is shifting in our field. But at the same time, I realize this is not entirely new.&lt;/p&gt;

&lt;p&gt;When I was 17 or 18, I was making websites on Ubuntu with HTML, CSS, and some jQuery to handle AJAX. I wrote a bit of PHP and used raw MySQL to generate HTML on the server.&lt;/p&gt;

&lt;p&gt;At one point, someone asked me to build a YouTube clone. So I did.&lt;br&gt;
Users could upload videos via FTP, log in, manage their content, and play videos using some odd Flash player.&lt;/p&gt;

&lt;p&gt;When I delivered it, he told me he would only pay 10 percent of what we agreed on. His reason? He said it was already built, and he could just recreate it in Dreamweaver.&lt;/p&gt;

&lt;p&gt;That was the first time I was told I might be replaced by drag-and-drop tools.&lt;/p&gt;

&lt;p&gt;A few years later, I was told my custom PHP CMS was useless because Joomla could do everything. Then came WordPress. Then came Wix.&lt;/p&gt;

&lt;p&gt;Now we are hearing the same thing again, but this time with AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Hasn’t Changed
&lt;/h3&gt;

&lt;p&gt;The tools change. The trends change. The way we approach problems keeps evolving.&lt;/p&gt;

&lt;p&gt;What doesn’t change is this:&lt;/p&gt;

&lt;p&gt;A curated, well-maintained codebase is always better than something generated by a machine, even when it’s partially reviewed or tweaked by humans.&lt;/p&gt;

&lt;p&gt;No-code and AI can be helpful. Use what gets the job done. But don’t forget that thoughtful engineering still matters. It always has.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vibecoding
&lt;/h3&gt;

&lt;p&gt;When I first saw the term "vibe coding" a few months ago, I was really curious.&lt;/p&gt;

&lt;p&gt;That video blew my mind, not because it introduced a revolutionary technique, but because I recognized the same pattern I had seen many times before.&lt;/p&gt;

&lt;p&gt;As the trend grew, I saw more and more people suggest, or at least imply, that a tool could fully replace human thinking. I was not just skeptical, I was also a bit annoyed by the idea.&lt;/p&gt;

&lt;p&gt;Later, during a hackathon at work, we were given access to Cursor and told to use it to build some prototypes.&lt;/p&gt;

&lt;p&gt;It was great, only it wasn't.&lt;/p&gt;

&lt;p&gt;The project was a cloud-based to-do manager that used another AI service to read your task list out loud each day. Some features worked. Others were clearly borrowed from existing tools or APIs and roughly adapted.&lt;/p&gt;

&lt;p&gt;I added a simple integration with Todoist to handle create and delete operations. That part was fine, although the implementation was a bit messy.&lt;/p&gt;

&lt;p&gt;But as soon as I tried to do something more complex, like keeping track of local updates that were not yet synced to the backend, most of the suggestions I got were hallucinated.&lt;/p&gt;

&lt;p&gt;After tweaking and editing the code, I eventually got it to work, but the result was something I would never want to maintain. Especially the second part, where I tried to connect to the paid tier of ElevenLabs for text-to-speech. Even when I pointed Cursor to the official documentation, it still suggested completely made-up APIs.&lt;/p&gt;

&lt;p&gt;In the end, prototyping with vibe coding can be useful. It can help you prove that an idea might work. But you are the one left cleaning up the mess.&lt;/p&gt;

&lt;p&gt;You get to an MVP quickly, but the cleanup is much harder. When you finally want to move to production, you often do not even know where to begin and what to take apart first, as the code is not at all yours.&lt;/p&gt;

&lt;h3&gt;
  
  
  What do I do instead?
&lt;/h3&gt;

&lt;p&gt;That does not mean that I do not use LLMs in my day to day, quite the opposite.&lt;/p&gt;

&lt;p&gt;What works better for me is taking a bit more time during prototyping. I try to write most of the important parts myself, and I let LLMs help with unit tests or small pieces of logic, asking for partial solutions to small problems, once I already know what I want the overall architecture to look like.&lt;/p&gt;

&lt;p&gt;gnoring the help LLMs can give you is stupid, but so is thinking they can completely replace the input of seasoned engineers. Engineers forged through thousands of hours spent digging through Stack Overflow and GitHub issues.&lt;/p&gt;

&lt;p&gt;That is what LLMs do for me. They replaced my googling. They replaced the time spent writing things I already understand. Now it takes me minutes to solve small problems, not hours.&lt;/p&gt;

&lt;p&gt;They help me set up unit and integration testing quickly. It takes me seconds, not hours.&lt;/p&gt;

&lt;p&gt;I also use them to compare libraries or approaches for solving domain-specific problems.&lt;/p&gt;

&lt;p&gt;But I do the coding. I do the copy pasting. And I know exactly what each line of code does (mostly).&lt;/p&gt;

&lt;p&gt;Here are some example of prompts I have used whilst working on or ideating &lt;a href="https://github.com/vikkio88/kiffarino" rel="noopener noreferrer"&gt;Kiffarino&lt;/a&gt; (&lt;a href="https://dev.to/vikkio88/keep-your-tickets-with-your-code-4iah"&gt;this&lt;/a&gt; is a post on dev.to on what it is and what it does.)&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.amazonaws.com%2Fuploads%2Farticles%2Fjz9vcdca7zp61cp05dyd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz9vcdca7zp61cp05dyd.png" alt=" " width="800" height="602"&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.amazonaws.com%2Fuploads%2Farticles%2Fi90oaii7t3v5ax0top1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi90oaii7t3v5ax0top1e.png" alt=" " width="800" height="500"&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.amazonaws.com%2Fuploads%2Farticles%2F1zqy4ahctcx7y1gv7kg9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zqy4ahctcx7y1gv7kg9.png" alt=" " width="744" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going back to my experience at uni, LLMs are like scientific calculators. You still need to understand the problem and know how to solve it. The calculator just helps you get there faster.&lt;/p&gt;

&lt;p&gt;If you delegate a problem to a calculator without understanding what the solution is, you are not an engineer. You are a manager, a business analyst, a product owner, or one of those startup CEOs with two employees.&lt;/p&gt;

&lt;p&gt;I like to keep using my brain. Delegating too much feels lazy. It makes me feel disconnected, unneeded, and a bit useless.&lt;/p&gt;

&lt;p&gt;Maybe I am a control freak, but I like to understand how things work. That is the main reason I love programming. And if I ever get too comfortable handing off the parts I enjoy, I might as well stop programming altogether.&lt;/p&gt;

&lt;p&gt;To me, it feels like buying a triple A game, ($70) and then watching someone else play it on Twitch.&lt;br&gt;
Something about that just feels lazy and frankly pointless.&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>ai</category>
      <category>llm</category>
      <category>programming</category>
    </item>
    <item>
      <title>Kiffarino: you local trello/jira for your sideprojects.</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Sat, 05 Jul 2025 11:14:34 +0000</pubDate>
      <link>https://dev.to/vikkio88/keep-your-tickets-with-your-code-4iah</link>
      <guid>https://dev.to/vikkio88/keep-your-tickets-with-your-code-4iah</guid>
      <description>&lt;p&gt;Whilst working on a side project, which idea came whilst working on a previous side project, I had an idea again, and this became the sideproject I will be telling you about today.&lt;/p&gt;

&lt;p&gt;I did briefly speak about it in &lt;a href="https://dev.to/vikkio88/monorepo-with-bun-474n"&gt;here&lt;/a&gt; but now I actually finished it as a little MVP.&lt;/p&gt;

&lt;p&gt;Today I present you &lt;a href="https://github.com/vikkio88/kiffarino?tab=readme-ov-file#kiffarinokfr" rel="noopener noreferrer"&gt;Kiffarino&lt;/a&gt;, a local first, file based Project Management Tool.&lt;/p&gt;

&lt;p&gt;(Bun/Svelte5/Typescript/Hono)&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.amazonaws.com%2Fuploads%2Farticles%2Fnpnfwg05kp1n5ww2udqt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnpnfwg05kp1n5ww2udqt.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think about it like your local Trello.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did I do it?
&lt;/h2&gt;

&lt;p&gt;Most of my sideprojects end up with a big &lt;code&gt;readme.md&lt;/code&gt; file with a bunch of TODOs that I end up forgetting what they meant.&lt;/p&gt;

&lt;p&gt;Few years back I created &lt;a href="https://github.com/vikkio88/kiffari?tab=readme-ov-file#kiffarikato" rel="noopener noreferrer"&gt;kiffari/kato&lt;/a&gt;, a self-hosted notion/trello alternative, but even though I use it quite a lot, I would like to have my tickets close to the code, so I can keep them close and never forget what they are for.&lt;/p&gt;

&lt;p&gt;And that was the idea that made me switch side project.&lt;/p&gt;

&lt;p&gt;What if I could run Kiffari, but locally, I could create a little cli utility that uses a set of folders and files to generate a kanban board where I could keep track of my tasks, tickets, docs and all.&lt;/p&gt;

&lt;p&gt;And here it is a little demo of the MVP:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/S4AoggoUElY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What does it do?
&lt;/h2&gt;

&lt;p&gt;Quoting the readme:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kiffarino is a lightweight, local-first project management tool built for developers and small teams who prefer a simple, CLI and Web based workflow tracking tool.&lt;/p&gt;

&lt;p&gt;It lets you manage tasks, tickets, and projects directly within your project folder — no complex setups, cloud services, or external tools required.&lt;/p&gt;

&lt;p&gt;Just fast, minimal, local productivity.&lt;/p&gt;

&lt;p&gt;It's like Jira, but simple and it just works.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🗃️ Local-first ticket and task management — Everything is stored locally in plain files, no cloud required.&lt;/li&gt;
&lt;li&gt;⚡ Lightweight — Minimal dependencies, with a total size of ~420 KB.&lt;/li&gt;
&lt;li&gt;🏷️ Flexible ticketing — Supports tags, filters, and status tracking out of the box.&lt;/li&gt;
&lt;li&gt;🛠️ Modern stack — Built with TypeScript, Bun, and Svelte 5.
📝 Markdown-based tickets — Tickets are just Markdown files you can open and edit manually anytime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You just install it via &lt;code&gt;npm i -g kiffarino&lt;/code&gt; and the command &lt;code&gt;kfr&lt;/code&gt; will be ready for you to use.&lt;/p&gt;

&lt;p&gt;go to a folder where the sideproject is and.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kfr init &lt;span class="c"&gt;# to init the config file (you can edit the folder and project name)&lt;/span&gt;

kfr generate &lt;span class="c"&gt;# to generate the folder structure a a couple of example tickets&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kfr start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to serve the web ui.&lt;/p&gt;

&lt;p&gt;And then you will have your locally running trello/jira without paying and only weighing ~400kb.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where do we go from here?
&lt;/h2&gt;

&lt;p&gt;I might start using it in the project I was working on, but I have a few more ideas to implement first, and all of them are in the README.md.&lt;/p&gt;

&lt;p&gt;Should I use &lt;code&gt;kfr&lt;/code&gt; to manage &lt;code&gt;kiffarino&lt;/code&gt; as a project too? Probably.&lt;/p&gt;

&lt;p&gt;But before using it I want to at least do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement the Docs management (just a set of ui utils to manage markdown files stored in a docs/ folder)&lt;/li&gt;
&lt;li&gt;Use the priority flag in the UI to order tickets.&lt;/li&gt;
&lt;li&gt;Implementing Drag&amp;amp;Drop to move tickets across states in the board&lt;/li&gt;
&lt;li&gt;Move away from zod (it is nice but it takes loads of those 400Kb even minified for just a few schema checks)&lt;/li&gt;
&lt;li&gt;Add Epics/Milestones to categorise tickets under a certain target.&lt;/li&gt;
&lt;li&gt;Tags Autocomplete/Search by Tags.&lt;/li&gt;
&lt;li&gt;A way to restore archived tickets.&lt;/li&gt;
&lt;li&gt;Github binary release so people who do not use &lt;code&gt;npm&lt;/code&gt; nor &lt;code&gt;node&lt;/code&gt; could download it as a standalone binary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know what you think, or open a PR!&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/vikkio88/kiffarino" rel="noopener noreferrer"&gt;github.com/vikkio88/kiffarino&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sideprojects</category>
      <category>svelte</category>
      <category>typescript</category>
      <category>bunjs</category>
    </item>
    <item>
      <title>Monorepo with Bun</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Sun, 22 Jun 2025 09:26:29 +0000</pubDate>
      <link>https://dev.to/vikkio88/monorepo-with-bun-474n</link>
      <guid>https://dev.to/vikkio88/monorepo-with-bun-474n</guid>
      <description>&lt;p&gt;Hello&lt;/p&gt;

&lt;p&gt;Had this idea recently. I built this project management tool kinda like Jira, called &lt;a href="https://github.com/vikkio88/kiffari/?tab=readme-ov-file#kiffarikato" rel="noopener noreferrer"&gt;kiffari&lt;/a&gt;, and now I’m working on turning it into something that runs locally, using markdown files as a database. It’s called &lt;a href="https://github.com/vikkio88/kiffarino" rel="noopener noreferrer"&gt;kiffarino&lt;/a&gt;. The whole point is to keep tickets right next to the code that handles them&lt;/p&gt;

&lt;p&gt;But this post isn’t really about that.&lt;/p&gt;

&lt;p&gt;It’s about how much I’ve gotten used to &lt;a href="https://bun.sh/" rel="noopener noreferrer"&gt;bun&lt;/a&gt; as my go-to JavaScript runtime. I almost forgot it can also transpile TypeScript for Node, work as a package manager, and handle monorepos too. It does all of it.&lt;/p&gt;

&lt;p&gt;Over the past few months I’ve moved most of my stuff to bun. It just makes sense. I love JavaScript. It’s the language I use the most and the one I feel fastest with. TypeScript grew on me too. Not because of the safety everyone talks about, but because the type hints are nice. It’s basically inline docs that actually work&lt;/p&gt;

&lt;p&gt;What used to really piss me off with TypeScript was the setup. Every time I started a new side project it was the same annoying routine&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Init the project with npm or pnpm
&lt;/li&gt;
&lt;li&gt;Copy a massive tsconfig from some other repo
&lt;/li&gt;
&lt;li&gt;Try to run it with ts-node or tsx or figure out how to build it properly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It’s not awful if you have a good starter or template, but still, too much time wasted before you even write a line of code.&lt;/p&gt;

&lt;p&gt;If also you want to have monorepo, with shared libs, the headache gets increasingly bigger, as you need to multiply the effort of all of those boilerplate nonsense.&lt;/p&gt;

&lt;p&gt;I have used &lt;code&gt;pnpm&lt;/code&gt; and &lt;code&gt;nx&lt;/code&gt; for work, it works really well but the boilerplate you need to just get going is just too much.&lt;/p&gt;

&lt;p&gt;Bundle that, build this, transpile that other one and by the time you get going that initial idea is getting boring and your side project is dead.&lt;/p&gt;

&lt;p&gt;I have used bun so far as a runtime, monorepo manager and a package manager, so I decided to give it a go as a transpiler too.&lt;/p&gt;

&lt;p&gt;Long story short, it worked.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;kiffarino&lt;/strong&gt;, I have the following setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;a href="https://hono.dev/" rel="noopener noreferrer"&gt;hono&lt;/a&gt; backend&lt;/li&gt;
&lt;li&gt;a &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;svelte5&lt;/a&gt; spa&lt;/li&gt;
&lt;li&gt;a shared lib to share types and functions between the 2 repos. (Endpoint results for example)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had done that before in other repos (&lt;a href="https://github.com/vikkio88/alicarti" rel="noopener noreferrer"&gt;alicarti&lt;/a&gt; a game framework for websocket games), but using bun as a runtime, so it was all good easy and smooth.&lt;/p&gt;

&lt;p&gt;Here I wanted to create a single executable, to be compatible with node and be able to publish it on npm as a package I can use everywhere.&lt;/p&gt;

&lt;p&gt;And it all just works.&lt;/p&gt;

&lt;p&gt;How did I do that?&lt;/p&gt;

&lt;p&gt;Easy:&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;"build": "bun build ./src/index.ts --outdir ./dist/ --target node"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This just transpiles and makes it runnable by node with only one command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;"build": "bunx --bun vite build"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vite.dev/" rel="noopener noreferrer"&gt;vite&lt;/a&gt; handles it really well but run via &lt;code&gt;bunx&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared libs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@kiffarino/shared"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/bun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"latest"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"peerDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only adding that &lt;code&gt;index.ts&lt;/code&gt; and it looking like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./models&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it allows me to use those libs everywhere in the monorepo.&lt;/p&gt;

&lt;p&gt;It just works wonders and to setup the workspaces, as suggested from their &lt;a href="https://bun.sh/guides/install/workspaces" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, you only need to do two things:&lt;/p&gt;

&lt;p&gt;This in the root &lt;code&gt;packages.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"workspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"be"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and as long as those packages have a &lt;code&gt;name&lt;/code&gt; in them, this what you can put so the subrepo can see stuff exported by other ones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@kiffarino/shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workspace:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and to use them you can just&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Ticket&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@kiffarino/shared&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- isnt this great?&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hono&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[...]&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;[...]&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ticket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="mi"&gt;201&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setup finished.&lt;/p&gt;

&lt;p&gt;How to run scripts concurrently you ask?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dev": "bun --filter '*' dev",
"check": "bun --filter '*' check",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will look in &lt;code&gt;*&lt;/code&gt; all of the workspaces and check if a &lt;code&gt;dev&lt;/code&gt; script is in the package.json and run it.&lt;br&gt;
The second one is to do a typecheck instead.&lt;/p&gt;

&lt;p&gt;In the case of a hono repo is a bit more complex as &lt;code&gt;bun&lt;/code&gt; does not do typechecking.&lt;/p&gt;

&lt;p&gt;But adding this is enough:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"check"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bunx tsc --noEmit -p tsconfig.json"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short, bun has completely changed how I handle JavaScript and TypeScript projects. It cuts through the usual setup headaches, speeds up development, and keeps everything simple—even in monorepos. If you’re tired of wrestling with configs and build pipelines, give bun a shot. It just works.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>bunjs</category>
      <category>monorepo</category>
      <category>typescript</category>
    </item>
    <item>
      <title>auto y2025 = new Year(); // Resolutions</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Thu, 02 Jan 2025 14:19:52 +0000</pubDate>
      <link>https://dev.to/vikkio88/auto-y2025-new-year-resolutions-5fj5</link>
      <guid>https://dev.to/vikkio88/auto-y2025-new-year-resolutions-5fj5</guid>
      <description>&lt;p&gt;Sup people, before the end of the year I went through a mad web search through all of my social media to gather my 2024 resolutions, and I could not find where I had posted them.&lt;/p&gt;

&lt;p&gt;I thought it was &lt;a href="https://livellosegreto.it/@vikkio" rel="noopener noreferrer"&gt;mastodon&lt;/a&gt;, no.&lt;br&gt;
Maybe &lt;a href="https://bsky.app/profile/vikkio.bsky.social" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt;? no.&lt;br&gt;
Facebook? fuck no.&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/vikkio88/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;? Nopety.&lt;br&gt;
Twitter? No fucking way I post in that crap.&lt;/p&gt;

&lt;p&gt;I think it must have been threads, but I have since deleted/nuked my profile since the app was only spamming me with random pointless notifications about posts I did not care about, so yeah I had lost them, so I gathered my memories and tried to think what they were and tried to assess whether I had indeed managed to achieve anything:&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Learn Rust (for real this time), I abandoned it twice before.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;✅❌ Yeah, not really. I did have a good run, but in  the end I caved under an annoying little problem on &lt;a href="https://dev.to/vikkio88/testing-vlang-rust-and-zig-and-more-acn"&gt;one&lt;/a&gt; of my exercises.&lt;/p&gt;

&lt;h3&gt;
  
  
  SideProjects
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;finish at least one of those sideprojects, or if not finish at least release it in a usable state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;✅ OMG did't I do just that? YES!&lt;/p&gt;

&lt;p&gt;I finished (and use them daily) 3 of them: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/vikkio88/ntrallazzu" rel="noopener noreferrer"&gt;Ntrallazzu&lt;/a&gt;: a cli tool to manage your sideproject folders, this one I even rewrote it twice, and converted to Typescript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/vikkio88/kiffari" rel="noopener noreferrer"&gt;Kiffari/kato&lt;/a&gt;: a notion clone meets obsidian but selfhosted and can do jira-like project management. This one is my first seriously big project written with Svelte and Go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/vikkio88/tinchi" rel="noopener noreferrer"&gt;tinchi&lt;/a&gt;: a kind of little css generator for utilities, a mix of &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;tailwind&lt;/a&gt; and &lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Finish that Football manager game
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;finish that football manager game you have been working on for the last 10 years with all of the programming languages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;❌ Nah, I did not do it, in fact I rebooted it once again, after &lt;a href="https://github.com/vikkio88/fdSim" rel="noopener noreferrer"&gt;Avalonia/dotnet&lt;/a&gt; and &lt;a href="https://github.com/vikkio88/fd-sim" rel="noopener noreferrer"&gt;Go/fyne&lt;/a&gt; (this last one being the further away I have even been), I just rebooted it once again as a browser game with bun/hono/solidjs just for fun &lt;a href="https://github.com/vikkio88/fdSimWeb" rel="noopener noreferrer"&gt;fdsimweb&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Godot
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;finish the &lt;a href="https://godotengine.org/" rel="noopener noreferrer"&gt;Godot4&lt;/a&gt; course and try release a game after that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;❌ I had started really well, but sort of lost interest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning/Expand Horizons
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;start to learn something new not tech related necessarily.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;✅ I started learning Japanese. Mostly using Duolingo at first, then I bought and read quite a lot of &lt;a href="https://genki3.japantimes.co.jp/en/" rel="noopener noreferrer"&gt;Genki&lt;/a&gt; and &lt;a href="https://www.fromzero.com/" rel="noopener noreferrer"&gt;Japanese from Zero&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;then of course I had to do something programming-wise and made &lt;a href="https://nisenotori.surge.sh/" rel="noopener noreferrer"&gt;Nise no Tori(Fake Bird)&lt;/a&gt; (&lt;a href="https://github.com/vikkio88/nisenotori" rel="noopener noreferrer"&gt;source&lt;/a&gt;), a little rip off of a few little games to learn Hiragana/Katakana.&lt;/p&gt;

&lt;p&gt;I also got back into drawing (I was doing little comic books when I was 10-14), I am not ready to share &lt;br&gt;
anything though :D.&lt;/p&gt;

&lt;p&gt;Overall not too bad I would say.&lt;/p&gt;

&lt;h2&gt;
  
  
  OMG it's 2025 now
&lt;/h2&gt;

&lt;p&gt;I think one of the best thing that made me go through with some of those resolutions last year was the sheer volume of them, it kept things fresh and made me bore less.&lt;/p&gt;

&lt;p&gt;So I am going to create a new list for next year and save it in here so I can always come back and look to see how I am doing, also I will add little steps so I can kind of track progress and achievements for the main goal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Become proficient in Rust.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Finish again &lt;a href="https://doc.rust-lang.org/book/" rel="noopener noreferrer"&gt;The Book&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Finish again the &lt;a href="https://github.com/rust-lang/rustlings" rel="noopener noreferrer"&gt;rustlings&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Make a Game in Rust with &lt;a href="https://sokoban.iolivia.me/" rel="noopener noreferrer"&gt;this&lt;/a&gt;, as suggested to me by the creator of that guide &lt;a href="https://bsky.app/profile/iolivia.me/post/3lejhbeb5zk2o" rel="noopener noreferrer"&gt;here&lt;/a&gt;
.&lt;/li&gt;
&lt;li&gt;Rewrite &lt;a href="https://dev.to/vikkio88/fyne-ill-do-it-myself-adventures-in-desktop-app-development-2di1"&gt;Muscurdi - Password Manager&lt;/a&gt; in Rust with &lt;a href="https://github.com/iced-rs/iced" rel="noopener noreferrer"&gt;iced&lt;/a&gt;, &lt;a href="https://github.com/dioxuslabs/dioxus" rel="noopener noreferrer"&gt;dioxus&lt;/a&gt; and/or &lt;a href="https://github.com/tauri-apps/tauri" rel="noopener noreferrer"&gt;tauri&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Release a little cli tool (maybe a &lt;a href="https://github.com/vikkio88/hygenTemplates" rel="noopener noreferrer"&gt;hygen templates&lt;/a&gt; parser) in Rust.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Game Programming
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Finish that Godot4 &lt;a href="https://www.gdquest.com/" rel="noopener noreferrer"&gt;course&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Finish &lt;a href="https://github.com/vikkio88/nigghiazza" rel="noopener noreferrer"&gt;that&lt;/a&gt; little 2d shooter in Godot.&lt;/li&gt;
&lt;li&gt;Finish fdSimWeb and see whether is a good idea.&lt;/li&gt;
&lt;li&gt;Finish &lt;a href="https://github.com/vikkio88/sokkera" rel="noopener noreferrer"&gt;Sokkera&lt;/a&gt; (a little turn based soccer/football game).&lt;/li&gt;
&lt;li&gt;Rewrite &lt;a href="https://github.com/vikkio88/ammishka" rel="noopener noreferrer"&gt;Ammishka&lt;/a&gt;, a little WS turn based game framework, in typescript (maybe using deno instead of bun).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Side Projects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write a little Mobile Client for Kato/Kiffari (either react native or kotlin).&lt;/li&gt;
&lt;li&gt;Little Web interface to publish/read comic books on a static hosting provider.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learning
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Finish at lease one of those courses on Blender you own.&lt;/li&gt;
&lt;li&gt;Study Statistics, and Applied Statistics.&lt;/li&gt;
&lt;li&gt;Continue Studying Japanese with the aim to be able to watch some anime without subtitles.&lt;/li&gt;
&lt;li&gt;Learn a bit of Korean, at least the alphabet and the writing system.&lt;/li&gt;
&lt;li&gt;Learn and use &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;Neovim&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Finish a drawing class/course and start to publish some comic books/comic strips somewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;God that is loads, let's see what will happen.&lt;/p&gt;

&lt;p&gt;I will keep it up to date as the year goes, so next year I do not need to go around the world looking for this post.&lt;/p&gt;

</description>
      <category>devresolutions2025</category>
      <category>learning</category>
      <category>sideprojects</category>
      <category>rust</category>
    </item>
    <item>
      <title>OMZ: Some Plugins that I forget about</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Tue, 19 Nov 2024 09:40:25 +0000</pubDate>
      <link>https://dev.to/vikkio88/omz-some-plugins-that-i-forget-about-4hp3</link>
      <guid>https://dev.to/vikkio88/omz-some-plugins-that-i-forget-about-4hp3</guid>
      <description>&lt;p&gt;I have a terrible memory, that is why I posted &lt;a href="https://dev.to/vikkio88/personal-todo-list-on-how-i-set-up-my-dev-machine-3p30"&gt;this&lt;/a&gt; about how I setup my dev machine.&lt;/p&gt;

&lt;p&gt;Recently also I have remember that not only I install &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;ohmyzsh&lt;/a&gt; and set it up as I want, I usually setup some plugins (apart from the git one which comes in enabled as default).&lt;/p&gt;

&lt;h2&gt;
  
  
  Jira
&lt;/h2&gt;

&lt;p&gt;If you have ever worked in IT you know that you have at least once used &lt;a href="https://www.atlassian.com/software/jira" rel="noopener noreferrer"&gt;Jira&lt;/a&gt;, I hate it so much, that is why I started a sideproject to manage my sideprojects &lt;a href="https://github.com/vikkio88/kiffari" rel="noopener noreferrer"&gt;Kato/Kiffari&lt;/a&gt; (but that is something for another post).&lt;/p&gt;

&lt;p&gt;Well one of the thing that &lt;strong&gt;jira&lt;/strong&gt; has is ticket codes, say a project is called WEB PLATFORM, and your ticket is the 187th, your ticket code will be probably &lt;code&gt;WEB-187&lt;/code&gt; or something of the likes.&lt;/p&gt;

&lt;p&gt;If you need to review some info on it, you usually have to go to the board, find your ticket, and click on it, but ohmyzsh has a nice little plugin that will open the ticket for you via shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jira WEB-187
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will open the jira ticket on your default browser as long as you setup a &lt;code&gt;~/.jira-url&lt;/code&gt; file looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~
❯ cat ~/.jira-url
https://YOURCOMPANY.atlassian.net/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How do you get it?&lt;br&gt;
Well if you have ohmyzsh install you already have this plugin, you only need to enable it adding it to the plugin array in &lt;code&gt;~/.zshrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ cat ~/.zshrc
export ZSH="$HOME/.oh-my-zsh"

ZSH_THEME="refined"
plugins=(git jira)
// more stuff here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  NVM
&lt;/h2&gt;

&lt;p&gt;Working with node and some old apps it always means that your default &lt;code&gt;node&lt;/code&gt; version might be a bit too fresh for the project itself.&lt;/p&gt;

&lt;p&gt;Hopefully you use &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;nvm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example in my machine I have set by default the version 23.1.0, the stable one when I setup this machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~
❯ nvm list
       v18.20.4
       v20.18.0
-&amp;gt;      v23.1.0
default -&amp;gt; stable (-&amp;gt; v23.1.0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But on a project I am working on I have a &lt;code&gt;.nvmrc&lt;/code&gt; file that tells me NOPE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;some-project git:chore/some-branch-name
❯ cat .nvmrc
v18.20.4%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The solution to make everything work fine is always to do a good old:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ nvm use
Found '~/code/some-project/.nvmrc' with version &amp;lt;v18.20.4&amp;gt;
Now using node v18.20.4 (npm v10.7.0)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if you have multiple windows/tabs and you need to run scripts elsewhere, it quickly gets annoying to remember to do it.&lt;/p&gt;

&lt;p&gt;Introducing the NVM PLUGIN:&lt;/p&gt;

&lt;p&gt;to enable it as the previous one just add the &lt;code&gt;nvm&lt;/code&gt; string to the plugin folder, plus a little setting I have found useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ cat ~/.zshrc
export ZSH="$HOME/.oh-my-zsh"

ZSH_THEME="refined"
plugins=(git jira nvm)

zstyle ':omz:plugins:nvm' autoload yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This last line makes the plugin autoload the correct node version when you switch in a folder with a &lt;code&gt;.nvmrc&lt;/code&gt; file and switch to the default version when you cd out of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~
❯ cd code/some-project
Found '~/code/some-project/.nvmrc' with version &amp;lt;v18.20.4&amp;gt;
Now using node v18.20.4 (npm v10.7.0)


some-project git:chore/some-branch-name
❯ cd
Reverting to nvm default version
Now using node v23.1.0 (npm v10.9.0)

~
❯
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy peasy and one less thing to type in to get your code going.&lt;/p&gt;

&lt;p&gt;More info on this plugin can be found &lt;a href="https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/nvm" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nvm</category>
      <category>git</category>
      <category>jira</category>
      <category>zsh</category>
    </item>
    <item>
      <title>Personal TODO list on how I set up my dev machine</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Tue, 19 Nov 2024 09:18:22 +0000</pubDate>
      <link>https://dev.to/vikkio88/personal-todo-list-on-how-i-set-up-my-dev-machine-3p30</link>
      <guid>https://dev.to/vikkio88/personal-todo-list-on-how-i-set-up-my-dev-machine-3p30</guid>
      <description>&lt;p&gt;I am a Linux fanboy, I have been using Linux (and especially Debian-based distros) since 2007 more or less. In 2007, I started using &lt;strong&gt;Ubuntu Gutsy Gibbon&lt;/strong&gt; and when I wanted to upgrade to &lt;strong&gt;Ubuntu Intrepid Ibex&lt;/strong&gt; I did it from the package manager, and disaster occurred.&lt;/p&gt;

&lt;p&gt;My machine wouldn't boot up.&lt;/p&gt;

&lt;p&gt;Since then every time there is a need of upgrading the system I have always installed it anew (keeping the /home partition from the old system) using the USB/cd live cd.&lt;/p&gt;

&lt;p&gt;Fast-forward to a few days ago. I've been using Ubuntu 20.04 since 2020, and my package manager went "Yo biatch Ubuntu 22.04 is out, get on it" and even though I had that bad experience in 2008, I thought it was maybe time now to give it a try and upgrade distro while on a distro.&lt;/p&gt;

&lt;p&gt;BAD CHOICE.&lt;/p&gt;

&lt;p&gt;It all seemed like it was working but the day after, the PC was stuck on a boot loop, so I knew I had to reinstall stuff.&lt;/p&gt;

&lt;p&gt;Luckily I am not that much of a paranoid freak, so I do not encrypt my hard disk, I managed to salvage the only 100kb of config files I needed by mounting the had on a live USB stick and put moving those files to a pen drive.&lt;/p&gt;

&lt;p&gt;Yet I had to install stuff back to get them all as I wanted them to be, so I decided to write a small post on how I get my machine set up.&lt;/p&gt;

&lt;p&gt;TODO&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;After a fresh install of Ubuntu I install the DE, I have been using &lt;a href="https://ubuntubudgie.org/" rel="noopener noreferrer"&gt;Budgie&lt;/a&gt; and I love it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://github.com/gnome-terminator" rel="noopener noreferrer"&gt;Terminator&lt;/a&gt; as a terminal emulator, and I set up the keybinds to be the same as iTerm on mac so it is easier to remember when I use my work MacBook.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;strong&gt;zsh&lt;/strong&gt;, switch bash to zsh as my shell and install &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;oh-my-zsh&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I plop my &lt;em&gt;.zshrc&lt;/em&gt; with few shortcut and theme I like in ~.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I am a javascript kind of guy, so I install &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;nvm&lt;/a&gt; first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I install &lt;a href="https://www.hygen.io/" rel="noopener noreferrer"&gt;hygen&lt;/a&gt; that I use to generate source code, and &lt;a href="https://github.com/vikkio88/hygenTemplates" rel="noopener noreferrer"&gt;my templates&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I generate a new set of ssh keys, and add them to Github and on my raspberry pi (so I can ssh into it).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I generate the config for my raspberry pi to connect using identity_key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I install: &lt;a href="https://discord.com/" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, &lt;a href="https://brave.com/" rel="noopener noreferrer"&gt;Brave&lt;/a&gt;, [Telegram(&lt;a href="https://desktop.telegram.org/" rel="noopener noreferrer"&gt;https://desktop.telegram.org/&lt;/a&gt;) and &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt;, which then I sync with my github profile to pull down my settings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I install &lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;go&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I install: &lt;strong&gt;build-essential&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I install &lt;a href="https://httpie.io/" rel="noopener noreferrer"&gt;httpie&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I install &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;docker&lt;/a&gt; (this is quite a boring process, to make it sudoers and so I can run without sudo). On Mac instead I use &lt;a href="https://podman.io/" rel="noopener noreferrer"&gt;podman&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I install &lt;a href="https://snapcraft.io/spotify" rel="noopener noreferrer"&gt;Spotify&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I set up my keybinds on Budgie: I use Super+Shift+Q to close windows, Super+Enter to Open a terminal, and a few other ones that I've been stuck with me since my early fluxbox days.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I troubleshoot why Alt+Ctrl+Arrows keybind doesn't work following a question I have also asked in the past.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a ~/code folder, to keep all my coding stuff in there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the latest tools I have been using/learning: atm &lt;a href="https://godotengine.org/" rel="noopener noreferrer"&gt;Godot&lt;/a&gt;, &lt;strong&gt;rust&lt;/strong&gt; (via &lt;a href="https://rustup.rs/" rel="noopener noreferrer"&gt;rustup&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I lose interest and never want to touch this PC ever again.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that is it. I hope this list would be helpful to someone, it will definitely be helpful to me if in a few years I forgot again NOT to upgrade the distro.&lt;/p&gt;

&lt;p&gt;I keep a little setup installer and info on this &lt;a href="https://github.com/vikkio88/dotfiles" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>setup</category>
      <category>devmachine</category>
      <category>todo</category>
      <category>programming</category>
    </item>
    <item>
      <title>Go(lang) to F*** yourself</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Thu, 08 Feb 2024 10:20:05 +0000</pubDate>
      <link>https://dev.to/vikkio88/golang-to-f-yourself-14h8</link>
      <guid>https://dev.to/vikkio88/golang-to-f-yourself-14h8</guid>
      <description>&lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is only my personal experience and might differ from yours, I do understand and just want to share this point of view.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since the dawn of my time programming, I have never felt like being a fanboy for a certain technology or platform.&lt;/p&gt;

&lt;p&gt;I have preferences, yes, but I have never been #teamJava #teamCPP or anything of the like.&lt;/p&gt;

&lt;p&gt;I think programming languages are tools to solve problems and you use different tools to solve different problems.&lt;/p&gt;

&lt;p&gt;One of the programming languages I have been using more and more in the last few years is &lt;a href="https://go.dev" rel="noopener noreferrer"&gt;go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I love it. the syntax just works so well for me, the simplicity and power of this language are astonishing.&lt;/p&gt;

&lt;p&gt;It is easy to pick up and work with, and since the code is quite simple you can go back after months and still your code is easy to read and the syntax is easy to pick back up.&lt;/p&gt;

&lt;p&gt;The ONLY single flaw I found so far is one, The Community.&lt;/p&gt;

&lt;p&gt;There are great people, but overall every time you ask for info and advice you only get 3 really:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You should rewrite that using only the standard library.&lt;/li&gt;
&lt;li&gt;Read the docs.&lt;/li&gt;
&lt;li&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3f3tiws0d9ljb2cm75qt.png" alt="Image description" width="647" height="187"&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that is not how you deal with people asking questions, I am a polyglot and have been working with different other programming languages and I feel like &lt;strong&gt;Go&lt;/strong&gt; is the best for potential and the worst for community gatekeeping.&lt;/p&gt;

&lt;p&gt;People have been generally unhelpful and a bit patronising, with a slight hint of perceived disgust for someone trying to understand what is the correct way of doing things.&lt;/p&gt;

&lt;p&gt;I think &lt;strong&gt;Go&lt;/strong&gt; would be a great language for everyone to work with, it is far superior than it used to be and even though the tooling is not as good as the one you find in &lt;code&gt;rust&lt;/code&gt; (cargo is the best tool of any programming languages), it has improved massively and now it is quite nice to work with.&lt;/p&gt;

&lt;p&gt;There are loads of packages for anything you need, it is easy to install and use them but the docs are usually lacking in examples and too verbose to be helpful.&lt;/p&gt;

&lt;p&gt;I feel like those who code in Golang would change their attitude towards newbies it will probably benefit the ecosystem with more people working with it and on it.&lt;/p&gt;

&lt;p&gt;Nonetheless, I do feel like the benefits of working with Go outweigh those little problems, and even though is slightly harder to find help it is still worth it.&lt;/p&gt;

&lt;p&gt;Now that I have expressed my feelings about it, I just wanted to know if am I alone in thinking this or did someone else experienced the same?&lt;/p&gt;

</description>
      <category>go</category>
      <category>community</category>
      <category>languages</category>
    </item>
    <item>
      <title>Creating a TODO app in Fyne an Go</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Sun, 21 May 2023 12:24:51 +0000</pubDate>
      <link>https://dev.to/vikkio88/creating-a-todo-app-in-fyne-an-go-2i6a</link>
      <guid>https://dev.to/vikkio88/creating-a-todo-app-in-fyne-an-go-2i6a</guid>
      <description>&lt;p&gt;In this small tutorial I will explain something that usually is the exercise that allow you to understand how to use a UI framework (at least in the web world), and we will end up step by step in building a TODO app in &lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;Go&lt;/a&gt; using the &lt;a href="https://fyne.io/" rel="noopener noreferrer"&gt;Fyne&lt;/a&gt; UI Framework.&lt;/p&gt;

&lt;p&gt;I will assume that you have at least some knowledge of programming, but it would also be great if you have some knowledge of &lt;strong&gt;go&lt;/strong&gt;, personally I found it the easiest Programming language to learn, you can just find more on how to do that in their &lt;a href="https://go.dev/learn/" rel="noopener noreferrer"&gt;learning&lt;/a&gt; resources.&lt;/p&gt;

&lt;p&gt;It would also be better if you follow the installing instruction of &lt;strong&gt;fyne&lt;/strong&gt; in &lt;a href="https://developer.fyne.io/started/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are we going to build
&lt;/h2&gt;

&lt;p&gt;It is simple really, just a small app that will allow you to keep a list of things to do, that you can check off if you once done them.&lt;/p&gt;

&lt;p&gt;It should look like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv65itf96i8h9qlksldc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv65itf96i8h9qlksldc.png" alt="Todo Example" width="364" height="518"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup Project structure
&lt;/h2&gt;

&lt;p&gt;Go has had a bad past for how everything used to be stored in a GOPATH folder, libs, vendors, your own personal projects, but since v1.14, with the introduction of go modules everything makes more sense and is way easier to understand.&lt;/p&gt;

&lt;p&gt;We want to init our project, so create a new folder then init the module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir todoapp &amp;amp;&amp;amp; cd todoapp
$ go mod init todoapp
$ touch main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some people suggest you to call the module with the url of the github repo you will use to version control it, but it does not really matter if you are not planning to use it elsewhere but in this binary.&lt;/p&gt;

&lt;p&gt;open this folder in your favourite code editor and drop this on your &lt;code&gt;main.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fyne.io/fyne/v2/app"&lt;/span&gt;
    &lt;span class="s"&gt;"fyne.io/fyne/v2/widget"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TODO App"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TODOs will go here"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowAndRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now before running it let's reference fyne and tidy the go modules&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go get fyne.io/fyne/v2@latest
$ go mod tidy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that is done, let's try to run it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go run .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see somewhere in your Desktop a small application window that looks like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcmc6uxc3j4rfsiw8bpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcmc6uxc3j4rfsiw8bpt.png" alt="Small Hello world" width="131" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing much to look at, but if you reached this point you are pretty much all set and from now on it will all be great.&lt;/p&gt;

&lt;p&gt;You can now do 2 things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the models for your app to show&lt;/li&gt;
&lt;li&gt;Design the UI&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I tend to create (usually with TDD) the models the app will show first, so I know what I need to bind in the view, especially in this case where we only have 1 model (&lt;code&gt;Todo&lt;/code&gt;) I guess we will be all set quite soon with that.&lt;/p&gt;
&lt;h2&gt;
  
  
  Todo Model
&lt;/h2&gt;

&lt;p&gt;I would make a folder called &lt;code&gt;models&lt;/code&gt; and drop in 2 files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls models   

todo.go
todo_test.go

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I won't go too much into the testing otherwise we will just take forever, so I will just show what todo.go declares&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Done&lt;/span&gt;        &lt;span class="kt"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;by default the constructor will set the &lt;code&gt;Done&lt;/code&gt; property as &lt;code&gt;false&lt;/code&gt;.&lt;br&gt;
I also added a &lt;code&gt;func String() string&lt;/code&gt; function to implement the &lt;a href="https://pkg.go.dev/fmt#Stringer" rel="noopener noreferrer"&gt;Stringer&lt;/a&gt; interface.&lt;br&gt;
So I can stringify my todo if I wanted to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s  - %t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's try to show one in our fyne app, but first maybe, let's make that window a bit bigger&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TODO App"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// ADDING THIS HERE&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it should look more like this&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nvatdiifs0uit1xt8ng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nvatdiifs0uit1xt8ng.png" alt="Bigger app" width="361" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;great, now let's create a TODO and show it in the same window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Show this on the window"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what we get&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flb545fu8sok7y0jr074x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flb545fu8sok7y0jr074x.png" alt="Stringified todo" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Brilliant.&lt;/p&gt;

&lt;p&gt;Now it is time to create the actual Interface.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ux Design
&lt;/h2&gt;

&lt;p&gt;Fyne, like many other Desktop UI frameworks has layouts that can be contained to define how the widgets and items will be positioned around the available space in the window.&lt;/p&gt;

&lt;p&gt;There are loads and they are all showcased in &lt;a href="https://developer.fyne.io/explore/layouts" rel="noopener noreferrer"&gt;here&lt;/a&gt; and in the Containers/Layouts section.&lt;/p&gt;

&lt;p&gt;Let's try one, let's push that todo in the center.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// make sure you import the right one&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fyne.io/fyne/v2/container"&lt;/span&gt;
&lt;span class="c"&gt;// this ↑&lt;/span&gt;

        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowAndRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the api examples you can see that this can also be achieved with this form&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCenterLayout&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowAndRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which I personally dislike, The first one is syntactic sugar for the second one.&lt;/p&gt;

&lt;p&gt;Anyway the app will look like this now:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9a985zihqwfminmp4eo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9a985zihqwfminmp4eo.png" alt="Centered" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice! but we want one Text entry and a button on the side, to input and add the todo to a list don't we? Well let's combine stuff and use the Border layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// TOP of the container&lt;/span&gt;

            &lt;span class="c"&gt;// this will be a the BOTTOM of the container&lt;/span&gt;
            &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add was clicked!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;

            &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// Right&lt;/span&gt;
            &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// Left&lt;/span&gt;

            &lt;span class="c"&gt;// the rest will take all the rest of the space&lt;/span&gt;
            &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowAndRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add a button at the bottom and on click it will print on the console standard output "Add w as clicked!"&lt;/p&gt;

&lt;p&gt;This is what it looks like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm3gsojj8jscibps55eof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm3gsojj8jscibps55eof.png" alt="Image description" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's add the entry at the side of the button, in another container type, HBox, this will stack the item horizontally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// TOP of the container&lt;/span&gt;

            &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewHBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEntry&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add was clicked!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;

            &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// Right&lt;/span&gt;
            &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// Left&lt;/span&gt;

            &lt;span class="c"&gt;// the rest will take all the rest of the space&lt;/span&gt;
            &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowAndRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsoklzks50s1acggtijwd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsoklzks50s1acggtijwd.png" alt="HBox" width="379" height="522"&gt;&lt;/a&gt;&lt;br&gt;
But unfortunately it does not look right, we want them to take all of the space available.&lt;/p&gt;

&lt;p&gt;We can try a few more:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;            &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewGridWithColumns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEntry&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add was clicked!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;            &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// TOP&lt;/span&gt;
                &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// BOTTOM&lt;/span&gt;
                &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// Left&lt;/span&gt;
                &lt;span class="c"&gt;// RIGHT ↓&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add was clicked!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
                &lt;span class="c"&gt;// take the rest of the space&lt;/span&gt;
                &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEntry&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesting another border in the border bottom:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejfasxy6gabgj19dkqo9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejfasxy6gabgj19dkqo9.png" alt="Nested borders" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It does not really matter, it is a matter of personal preference but I will go with this last one.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cleanup and Todo Creation
&lt;/h2&gt;

&lt;p&gt;We now have designed our UI will look like, but let's try to clean up the code as the container tree is quite messy already.&lt;/p&gt;

&lt;p&gt;I will move the button and text entry creation before the &lt;code&gt;.SetContent&lt;/code&gt; call like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEntry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PlaceHolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"New Todo Description..."&lt;/span&gt;
    &lt;span class="n"&gt;addBtn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add was clicked!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// TOP of the container&lt;/span&gt;

            &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// TOP&lt;/span&gt;
                &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// BOTTOM&lt;/span&gt;
                &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// Left&lt;/span&gt;
                &lt;span class="c"&gt;// RIGHT ↓&lt;/span&gt;
                &lt;span class="n"&gt;addBtn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c"&gt;// take the rest of the space&lt;/span&gt;
                &lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;declaring those widget before will allow us to modify properties and add handlers to them before getting them into the actual content tree.&lt;/p&gt;

&lt;p&gt;In this example I added a placeholder to the entry text so it is clearer what it is for:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj02in9j9wkzqi6q5cycd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj02in9j9wkzqi6q5cycd.png" alt="desc placeholder" width="371" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's make the &lt;code&gt;"Add"&lt;/code&gt; button do something, and even disable it if the text is empty or too short.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEntry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PlaceHolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"New Todo Description..."&lt;/span&gt;
    &lt;span class="n"&gt;addBtn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add was clicked!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;addBtn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Disable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnChanged&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;addBtn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Disable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;addBtn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will disable the button if the text length is less than 3 character:&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.amazonaws.com%2Fuploads%2Farticles%2Fmvhi2hs5hh81pcz9v6yi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvhi2hs5hh81pcz9v6yi.png" alt="disabled btn" width="383" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and enable it otherwise&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4chchb9q4q9ag49rge1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4chchb9q4q9ag49rge1b.png" alt="enabled" width="376" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! Now let's try to build the last piece of the UX we are missing, the List of todos.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lists in Fyne
&lt;/h2&gt;

&lt;p&gt;There are 2 types of List widget you can use for this purpose, the first one is a static type of list, the second is one which content is linked to the data it will show.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.fyne.io/widget/list" rel="noopener noreferrer"&gt;Simple List&lt;/a&gt; has a simple API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;            &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="c"&gt;// func that returns the number of items in the list&lt;/span&gt;
                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="c"&gt;// func that returns the component structure of the List Item&lt;/span&gt;
                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"template"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="c"&gt;// func that is called for each item in the list and allows&lt;/span&gt;
                &lt;span class="c"&gt;// you to show the content on the previously defined ui structure&lt;/span&gt;
                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListItemID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in our particular example we want each list item to have a label for the Todo description and a checkbox to show whether the todo is marked as done or not.&lt;/p&gt;

&lt;p&gt;Just to try out what it looks like let's create this &lt;code&gt;data&lt;/code&gt; as a slice of Todos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some stuff"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some more stuff"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some other things"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// then on the last func of list we just replace `data[i]` with&lt;/span&gt;

                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListItemID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it will look like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhpkjsi59o599zo1k3st.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhpkjsi59o599zo1k3st.png" alt="Simple List" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;as you can see there we are getting the &lt;code&gt;o&lt;/code&gt; &lt;code&gt;CanvasObject&lt;/code&gt; and type casting it to a &lt;code&gt;*widget.Label&lt;/code&gt; that is because we know that the function before creates that particular widget, as I said before though we need a &lt;a href="https://developer.fyne.io/widget/label" rel="noopener noreferrer"&gt;Label&lt;/a&gt; and a &lt;a href="https://developer.fyne.io/widget/choices" rel="noopener noreferrer"&gt;Checkbox&lt;/a&gt;, they need to go in a container also, so we can kind of do the same with did with the bottom bar and space them so the label takes most of the space.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="c"&gt;// left of the border&lt;/span&gt;
                        &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}),&lt;/span&gt;
                        &lt;span class="c"&gt;// takes the rest of the space&lt;/span&gt;
                        &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something like this.&lt;/p&gt;

&lt;p&gt;But unfortunately this will throw a compile time as the &lt;code&gt;o CanvasObject&lt;/code&gt; is not a &lt;code&gt;*widget.Label&lt;/code&gt; anymore.&lt;/p&gt;

&lt;p&gt;We need to cast it to a &lt;code&gt;Container&lt;/code&gt;, then get the widgets nested within using indexes, and cast them all to what we know they are (as we defined them we should know).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListItemID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="c"&gt;// ideally we should check `ok` for each one of those casting&lt;/span&gt;
                    &lt;span class="c"&gt;// but we know that they are those types for sure&lt;/span&gt;
                    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Check&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetChecked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and this is what it looks like now&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.amazonaws.com%2Fuploads%2Farticles%2Fz8u28i0pb636mkul89h9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8u28i0pb636mkul89h9.png" alt="with box" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personally I find that casting thing quite weird in the API and getting the order of the components within a container is a bit hit and miss, might need to try compile a couple of time to see whether &lt;code&gt;[1]&lt;/code&gt; is &lt;code&gt;Label&lt;/code&gt; or &lt;code&gt;Check&lt;/code&gt; for real.&lt;/p&gt;

&lt;p&gt;Anyway we got there but if we add another todo to that &lt;code&gt;data&lt;/code&gt; the list won't reflect the changes, as we are just using a static simple list, if we want to make it dynamic, and we need to for our app, we need to use &lt;code&gt;binding&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Binding and Dynamic Lists
&lt;/h2&gt;

&lt;p&gt;Binding is explained in the &lt;a href="https://developer.fyne.io/binding/list" rel="noopener noreferrer"&gt;docs&lt;/a&gt; quite well for simple types, but not at all for Struct types, which is what annoyed me the first time I tried fyne.&lt;/p&gt;

&lt;p&gt;What you do really is create a &lt;code&gt;DataList&lt;/code&gt;, add the items from our slice of todos and use another widget api to render the list.&lt;/p&gt;

&lt;p&gt;It will look quite similar to what we did here, but in our case, since the type of DataList we create will be of &lt;code&gt;Untyped&lt;/code&gt; type, we will have to add one step more than a primitive type, to cast the data item to our own &lt;code&gt;models.Todo&lt;/code&gt; struct.&lt;/p&gt;

&lt;p&gt;here it is how you create the data list&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some stuff"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some more stuff"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some other things"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewUntypedList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it would be nice if you could set the items on creation maybe but the API does not allow to do that yet.&lt;/p&gt;

&lt;p&gt;then this is how the list creation looks like now&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;            &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewListWithData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="c"&gt;// the binding.List type&lt;/span&gt;
                &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c"&gt;// func that returns the component structure of the List Item&lt;/span&gt;
                &lt;span class="c"&gt;// exactly the same as the Simple List&lt;/span&gt;
                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="c"&gt;// left of the border&lt;/span&gt;
                        &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}),&lt;/span&gt;
                        &lt;span class="c"&gt;// takes the rest of the space&lt;/span&gt;
                        &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="c"&gt;// func that is called for each item in the list and allows&lt;/span&gt;
                &lt;span class="c"&gt;// but this time we get the actual DataItem we need to cast&lt;/span&gt;
                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;di&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="c"&gt;// ideally we should check `ok` for each one of those casting&lt;/span&gt;
                    &lt;span class="c"&gt;// but we know that they are those types for sure&lt;/span&gt;
                    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Check&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;diu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Untyped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;diu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                    &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetChecked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this other casting bit is the one I found hard to get right too&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;                    &lt;span class="n"&gt;diu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Untyped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;diu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get a DataItem which is a &lt;code&gt;binding.Untyped&lt;/code&gt; underneath, we need to &lt;code&gt;Get()&lt;/code&gt; it, the cast it to our model, then we can finally use it.&lt;/p&gt;

&lt;p&gt;I usually move the functions within a list to separate functions and make a small method on the models package to handle that type of casting, so it looks a bit less cluttered.&lt;/p&gt;

&lt;p&gt;something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// in models&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewTodoFromDataItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Untyped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// so in the list function will look like so&lt;/span&gt;
                &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;di&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanvasObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="c"&gt;// ideally we should check `ok` for each one of those casting&lt;/span&gt;
                    &lt;span class="c"&gt;// but we know that they are those types for sure&lt;/span&gt;
                    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Check&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="c"&gt;/*
                        diu, _ := di.(binding.Untyped).Get()
                        todo := diu.(models.Todo)
                    */&lt;/span&gt;
                    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodoFromDataItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetChecked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anyway, now let's do the last step, how to add a new todo?&lt;br&gt;
Just use the data list on the &lt;code&gt;addBtn&lt;/code&gt; &lt;code&gt;func&lt;/code&gt; like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;addBtn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;newtodoDescTxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and once you click on it, it will magically add it to the list, and show a new list item on the List component.&lt;br&gt;
As a small nice feature, we need also to clear the text entry so we are ready to add another one.&lt;/p&gt;

&lt;p&gt;We could also use the &lt;code&gt;Prepend&lt;/code&gt; method instead of &lt;code&gt;Append&lt;/code&gt; so the Todo will take the first place in the list instead of the last.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you want to change the actual items it is better to create a slice of &lt;code&gt;*models.Todo&lt;/code&gt; so they will use the real value of those rather than a clone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is no &lt;code&gt;Remove&lt;/code&gt; api in the DataList for now, so to remove something you need to hack around with the slice within.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// to remove them all for example you should do something like this&lt;/span&gt;
        &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are interested in the code example I uploaded it on my github here: &lt;a href="https://github.com/vikkio88/fyne-tutorials/tree/main/todoapp" rel="noopener noreferrer"&gt;github.com/vikkio88/fyne-tutorials/tree/main/todoapp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to see a more complex example with some syntax sugar and sexy db persistence layer using &lt;a href="https://github.com/ostafen/clover" rel="noopener noreferrer"&gt;clover&lt;/a&gt; you can look at this &lt;a href="https://github.com/vikkio88/gtodos" rel="noopener noreferrer"&gt;gtodos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also added an example branch without the db just for "fun" &lt;a href="https://github.com/vikkio88/gtodos/tree/dbless-example" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally, if you are interested in a more complex app example I posted &lt;a href="https://dev.to/vikkio88/fyne-ill-do-it-myself-adventures-in-desktop-app-development-2di1"&gt;here&lt;/a&gt; about me rewriting a Password Manager in Fyne and managing in a couple of days to create and distribute the app using github actions.&lt;br&gt;
&lt;a href="https://github.com/vikkio88/muscurd-ig" rel="noopener noreferrer"&gt;Muscurd-ig&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That is all folks, please let me know what you think or if something is not clear.&lt;/p&gt;

&lt;p&gt;See you next time.&lt;/p&gt;

</description>
      <category>go</category>
      <category>fyne</category>
      <category>todo</category>
      <category>desktopgui</category>
    </item>
    <item>
      <title>Fyne, I'll do it myself: Adventures in Desktop App development</title>
      <dc:creator>Vincenzo</dc:creator>
      <pubDate>Sat, 20 May 2023 12:26:07 +0000</pubDate>
      <link>https://dev.to/vikkio88/fyne-ill-do-it-myself-adventures-in-desktop-app-development-2di1</link>
      <guid>https://dev.to/vikkio88/fyne-ill-do-it-myself-adventures-in-desktop-app-development-2di1</guid>
      <description>&lt;p&gt;Almost a year ago, I wrote about I was really trying hard to get into Desktop GUI apps development &lt;a href="https://dev.to/vikkio88/my-adventures-in-desktop-gui-app-development-land-59b7"&gt;here&lt;/a&gt;, and someone suggested me to try &lt;a href="https://fyne.io/" rel="noopener noreferrer"&gt;Fyne&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Which I did, and wrote some first impressions about it in &lt;a href="https://dev.to/vikkio88/adventures-in-desktop-app-development-ii-revenge-of-the-gopher-2579"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I said there that the docs weren't really clear and some stuff felt a bit hacky to do, which it is totally still the case, but since then many things have changed.&lt;/p&gt;

&lt;p&gt;I tested &lt;a href="https://avaloniaui.net/" rel="noopener noreferrer"&gt;Avalonia&lt;/a&gt; and loved it.&lt;/p&gt;

&lt;p&gt;I even wrote an article &lt;a href="https://dev.to/vikkio88/muscurd-i-my-personal-password-manager-l89"&gt;here&lt;/a&gt; on how I wrote in just under 2 months a multiplatform password manager application, which builds on github action and works on Mac/Win and Linux.&lt;br&gt;
&lt;a href="https://github.com/vikkio88/muscurd-i" rel="noopener noreferrer"&gt;Muscurd-i&lt;/a&gt; is the app, and the codebase is quite huge to be such a simple application.&lt;/p&gt;

&lt;p&gt;Few weeks ago instead I got my coding mojo back and hacked a bit around with rust, vlang and went back to study go once again (I wrote about it in &lt;a href="https://dev.to/vikkio88/testing-vlang-rust-and-zig-and-more-acn"&gt;here&lt;/a&gt; also).&lt;/p&gt;

&lt;p&gt;This is the way I learn programming languages, I do side projects and since then I felt like I had to give fyne another go.&lt;/p&gt;

&lt;p&gt;I finally completed the todo application which I was mentioning on the post before, and I was quite silly not to see why it didn't work before codebase is &lt;a href="https://github.com/vikkio88/gtodos" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now it all works like a charm, and since I was on a roll I decided to give a try to move my password manager to Fyne and golang.&lt;/p&gt;

&lt;p&gt;I did.&lt;/p&gt;

&lt;p&gt;It took me only 2 days to reach feature parity and a couple of hours to setup a set of github action to build the binaries.&lt;/p&gt;

&lt;p&gt;This is the &lt;a href="https://github.com/vikkio88/muscurd-ig" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;br&gt;
This is what the latest release page looks like &lt;a href="https://github.com/vikkio88/muscurd-ig/releases/latest" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only thing I needed in here which was not supported out of the box with Fyne, was a routing system, which I was shocked to find so easy to create myself using their &lt;a href="https://developer.fyne.io/binding/" rel="noopener noreferrer"&gt;binding apis&lt;/a&gt; and a bit of creativity.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://github.com/vikkio88/muscurd-ig/blob/main/app/app.go#L44" rel="noopener noreferrer"&gt;this&lt;/a&gt; project basically the app creates a context to pass around the views, and maps the string representation of the route to a view which it is "mounted" in the main window content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;        &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AppRoute&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Setup&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetSetupView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Login&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetLoginView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetPasswordListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Details&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetPasswordDetailsView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddUpdate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetPasswordAddUpdateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;About&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAboutView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Getting the view given a route&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;getView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fyne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentRoute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// reacting to the view change&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnRouteChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentRoute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"route state changed %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;


&lt;span class="c"&gt;// changing a route from any view then looks like this&lt;/span&gt;
    &lt;span class="n"&gt;aboutPageBtn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewButtonWithIcon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InfoIcon&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NavigateTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;About&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was really proud of that, I even did a small change so I could pass a parameter around, for routes with ids for example.&lt;/p&gt;

&lt;p&gt;I know it feels a bit &lt;code&gt;web app&lt;/code&gt;like but every other ui framework has routing systems, that is just the way the UX world goes I guess.&lt;/p&gt;

&lt;p&gt;I also managed, as mentioned before, to setup a whole set of github actions to &lt;a href="https://github.com/vikkio88/muscurd-ig/blob/main/.github/workflows/on-release.yml" rel="noopener noreferrer"&gt;build&lt;/a&gt; the app binary for Win, Linux and Mac, and it took me literally 2 hours without almost no trial and error that usually you end up doing when you work with CI/CD tools.&lt;/p&gt;

&lt;p&gt;The app looks like this on linux after you install it:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3i2rri9rqni4ms97e3jl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3i2rri9rqni4ms97e3jl.png" alt="Image description" width="601" height="365"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftl3em6g77stkkduic8ze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftl3em6g77stkkduic8ze.png" alt="Image description" width="556" height="460"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpez7t1y5zmcdqzzec6vz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpez7t1y5zmcdqzzec6vz.png" alt="Image description" width="664" height="341"&gt;&lt;/a&gt;&lt;br&gt;
Everything just worked and I felt productive like I probably never have on Desktop GUI app development.&lt;/p&gt;

&lt;p&gt;What is next? Maybe I will finally finish one of the projects I tried to do many times before, a Football Manager clone focused on the Players Transfer Market.&lt;/p&gt;

&lt;p&gt;Let's see if this mojo streak lasts.&lt;/p&gt;

&lt;p&gt;And what about you? Have you tried fyne? GO AND DO IT NOW!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
