<?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: Andreas Sander</title>
    <description>The latest articles on DEV Community by Andreas Sander (@andi1984).</description>
    <link>https://dev.to/andi1984</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F182494%2Fec34094f-51d5-4b61-9387-ccff6a33a9fa.png</url>
      <title>DEV Community: Andreas Sander</title>
      <link>https://dev.to/andi1984</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andi1984"/>
    <language>en</language>
    <item>
      <title>Ferrico - Taking My Bookmarks Back Home with Tauri and Rust</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Mon, 15 Jun 2026 20:25:56 +0000</pubDate>
      <link>https://dev.to/andi1984/ferrico-taking-my-bookmarks-back-home-with-tauri-and-rust-524e</link>
      <guid>https://dev.to/andi1984/ferrico-taking-my-bookmarks-back-home-with-tauri-and-rust-524e</guid>
      <description>&lt;p&gt;Hello developers,&lt;/p&gt;

&lt;p&gt;Today I would like to talk about a tool I have been building in the open: &lt;a href="https://github.com/andi1984/ferrico_dot_app" rel="noopener noreferrer"&gt;Ferrico&lt;/a&gt;. It is a desktop bookmark manager, but the interesting part is &lt;em&gt;where&lt;/em&gt; your bookmarks live - and it is not in someone else's cloud.&lt;/p&gt;

&lt;p&gt;The itch was a very ordinary one. My bookmarks were scattered across three browsers, two devices and one read-it-later service that had quietly started rate-limiting my free account. Every one of them wanted an account, sold me &lt;em&gt;sync&lt;/em&gt; as a feature, and politely held my own links hostage behind a login. So I did what I always end up doing: I built my own thing and learned a lot on the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does "local-first" even mean?
&lt;/h2&gt;

&lt;p&gt;Before we dive into code, let us define the term, because the whole project hangs on it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Local-first software [...] gives users full agency over their own data. [...] The availability of another computer should never prevent you from working.&lt;br&gt;
-- &lt;cite&gt;&lt;a href="https://www.inkandswitch.com/local-first/" rel="noopener noreferrer"&gt;Ink &amp;amp; Switch, "Local-first software"&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the whole pitch. Ferrico stores everything in a single SQLite file on &lt;em&gt;your&lt;/em&gt; machine. No account, no telemetry, no Ferrico-operated backend anywhere. The network is something you can &lt;em&gt;opt into&lt;/em&gt;, never something you depend on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why build my own (again)?
&lt;/h2&gt;

&lt;p&gt;Let us be honest - the world does not need another bookmark manager. But I wanted three things at once, and nothing on the market gave me all of them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ownership&lt;/strong&gt;: my links in a file format I can read, back up and &lt;code&gt;grep&lt;/code&gt; ten years from now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A native footprint&lt;/strong&gt;: not a 300 MB Electron app idling at 400 MB of RAM to show me a list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Something to learn&lt;/strong&gt;: I had been itching to write real &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; instead of toy examples.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That third point is the honest one. Just like with &lt;a href="https://github.com/andi1984/back2roots" rel="noopener noreferrer"&gt;Back2Roots&lt;/a&gt;, my home-grown static site generator, half the motivation was simply to get my fingers dirty with a stack I wanted to understand better.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shell&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://tauri.app/" rel="noopener noreferrer"&gt;Tauri 2&lt;/a&gt; (Rust)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19, TypeScript, Vite, Tailwind 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;SQLite via &lt;a href="https://github.com/rusqlite/rusqlite" rel="noopener noreferrer"&gt;&lt;code&gt;rusqlite&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extension&lt;/td&gt;
&lt;td&gt;A loopback &lt;a href="https://github.com/tokio-rs/axum" rel="noopener noreferrer"&gt;&lt;code&gt;axum&lt;/code&gt;&lt;/a&gt; server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tooling&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://bun.sh/" rel="noopener noreferrer"&gt;Bun&lt;/a&gt; for the JS side&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://tauri.app/" rel="noopener noreferrer"&gt;Tauri&lt;/a&gt; is the star here. Instead of bundling a whole Chromium like Electron does, it uses the operating system's &lt;em&gt;own&lt;/em&gt; webview and ships a small Rust binary next to it. You write your UI in plain web tech, and anything that touches the disk, the database or the OS goes through Rust commands. The result is an installer measured in single-digit megabytes instead of hundreds.&lt;/p&gt;

&lt;h2&gt;
  
  
  A single file you actually own
&lt;/h2&gt;

&lt;p&gt;The data layer is intentionally boring, and that is the point. One SQLite database, in the place your OS expects it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linux    ~/.local/share/ferrico/ferrico.db
macOS    ~/Library/Application Support/ferrico/ferrico.db
Windows  %APPDATA%\ferrico\ferrico.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because it is just SQLite, fuzzy search across titles, URLs and page content is a query, not a service. Import and export are &lt;em&gt;lossless&lt;/em&gt; JSON snapshots, so you are never locked in - and for the migration day there is Netscape HTML, OPML and CSV on top. A bookmark manager whose export button actually round-trips: revolutionary, I know.&lt;/p&gt;

&lt;h2&gt;
  
  
  The browser extension problem
&lt;/h2&gt;

&lt;p&gt;Here is the part I found genuinely fun to solve. A bookmark manager is useless if saving the current tab means alt-tabbing to a separate app. You want a button &lt;em&gt;in the browser&lt;/em&gt;. But the browser and a native Tauri app live in two different worlds and cannot just call each other.&lt;/p&gt;

&lt;p&gt;The trick: Ferrico runs a tiny HTTP server inside the Rust process, bound to loopback only.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bound to 127.0.0.1 - never reachable from the network.&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1:59432"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Manifest V3 extension then &lt;code&gt;POST&lt;/code&gt;s the current tab to &lt;code&gt;http://127.0.0.1:59432&lt;/code&gt;, authenticated with a token you copy out of the app's settings. Two important properties fall out of this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It never leaves your machine.&lt;/strong&gt; The socket is bound to &lt;code&gt;127.0.0.1&lt;/code&gt;, so nothing on your LAN - let alone the internet - can reach it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is explicit.&lt;/strong&gt; No pairing handshake, no account; the extension only works once &lt;em&gt;you&lt;/em&gt; paste the token.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Loopback-only plus a shared secret is a humble pattern, but for a one-user desktop tool it is exactly the right amount of security: enough to stop a random page from talking to your library, not so much that you need a login server to manage it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional, never required
&lt;/h2&gt;

&lt;p&gt;Two features deliberately sit &lt;em&gt;outside&lt;/em&gt; the local core, and both are off by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud sync&lt;/strong&gt; is a lossless JSON snapshot in &lt;em&gt;your&lt;/em&gt; Google Drive, using OAuth credentials &lt;em&gt;you&lt;/em&gt; create, scoped to &lt;code&gt;drive.file&lt;/code&gt; so the app can only touch its own files. Conflict resolution is deliberately dumb - last write wins, one machine at a time. No clever CRDT, no Ferrico server in the middle. You own the OAuth app; I never see a byte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI features&lt;/strong&gt; lean on the &lt;a href="https://claude.com/claude-code" rel="noopener noreferrer"&gt;Claude CLI&lt;/a&gt; if - and only if - it happens to be on your &lt;code&gt;PATH&lt;/code&gt;. Natural-language search, auto-sorting the inbox, mapping messy CSV columns on import. When you explicitly invoke one of these, the relevant bookmark metadata is handed to your &lt;em&gt;local&lt;/em&gt; &lt;code&gt;claude&lt;/code&gt; binary, which talks to Anthropic on your behalf. No invocation, no network call. The intelligence is a guest in the house, not the landlord.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let us be honest about the trade-offs
&lt;/h2&gt;

&lt;p&gt;No free lunch, as always:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sync is primitive on purpose.&lt;/strong&gt; Last-write-wins means if you edit on two machines between syncs, one set of edits loses. For a personal bookmark stash that is a fine trade; for a shared team tool it would not be.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local-first means &lt;em&gt;you&lt;/em&gt; own the backups too.&lt;/strong&gt; There is no magical cloud safety net unless you switch one on. Your file, your responsibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is young.&lt;/strong&gt; Ferrico is happily sitting at v0.x (currently &lt;code&gt;v0.9.0&lt;/code&gt;). Desktop runs on macOS, Linux and Windows; Android is still very much a work in progress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for me the deal is worth it. My bookmarks are a file I can see, search instantly, back up however I like, and read without asking anyone's permission.&lt;/p&gt;

&lt;h2&gt;
  
  
  It is open-source!
&lt;/h2&gt;

&lt;p&gt;Ferrico is published on &lt;a href="https://github.com/andi1984/ferrico_dot_app" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; under the &lt;a href="https://www.gnu.org/licenses/gpl-3.0.en.html" rel="noopener noreferrer"&gt;GPL-3.0-or-later&lt;/a&gt; license, and there is a &lt;a href="https://andi1984.github.io/ferrico_dot_app/" rel="noopener noreferrer"&gt;live demo&lt;/a&gt; if you would like to click around before installing anything. Want to build it yourself? It is the usual two lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun &lt;span class="nb"&gt;install
&lt;/span&gt;bun tauri dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to fork it, file an issue, or send a feature request. And if you have been looking for an excuse to write some Rust - this is a very welcoming one.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Andi 🔖&lt;/p&gt;

</description>
      <category>rust</category>
      <category>tauri</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Tue, 12 May 2026 23:16:08 +0000</pubDate>
      <link>https://dev.to/andi1984/-o94</link>
      <guid>https://dev.to/andi1984/-o94</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/digitalocean/python-decorators-from-basics-to-real-world-use-cases-n5f" class="crayons-story__hidden-navigation-link"&gt;Python Decorators: From Basics to Real-World Use Cases&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/digitalocean"&gt;
            &lt;img alt="DigitalOcean logo" 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%2Forganization%2Fprofile_image%2F175%2F369f1227-0eac-4a88-8d3c-08851bf0b117.png" class="crayons-logo__image" width="180" height="180"&gt;
          &lt;/a&gt;

          &lt;a href="/digitalocean_staff" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F64516%2Fa0c9989b-6d18-46c7-bc66-4c2c1580534e.jpg" alt="digitalocean_staff profile" class="crayons-avatar__image" width="400" height="400"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/digitalocean_staff" class="crayons-story__secondary fw-medium m:hidden"&gt;
              DigitalOcean
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                DigitalOcean
                
              
              &lt;div id="story-author-preview-content-3658826" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/digitalocean_staff" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F64516%2Fa0c9989b-6d18-46c7-bc66-4c2c1580534e.jpg" class="crayons-avatar__image" alt="" width="400" height="400"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;DigitalOcean&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/digitalocean" class="crayons-story__secondary fw-medium"&gt;DigitalOcean&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/digitalocean/python-decorators-from-basics-to-real-world-use-cases-n5f" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 12&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/digitalocean/python-decorators-from-basics-to-real-world-use-cases-n5f" id="article-link-3658826"&gt;
          Python Decorators: From Basics to Real-World Use Cases
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/learning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;learning&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/digitalocean/python-decorators-from-basics-to-real-world-use-cases-n5f" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/digitalocean/python-decorators-from-basics-to-real-world-use-cases-n5f#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            11 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>A Letter to My Younger Self</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Thu, 15 Jan 2026 17:15:09 +0000</pubDate>
      <link>https://dev.to/andi1984/a-letter-to-my-younger-self-3if5</link>
      <guid>https://dev.to/andi1984/a-letter-to-my-younger-self-3if5</guid>
      <description>&lt;p&gt;This could be a letter to my younger self as a starting frontend developer, sharing insights and lessons learned over the years. But maybe it could also be a letter to anyone starting out in the field, offering encouragement and advice.&lt;/p&gt;




&lt;p&gt;Dear Younger Me,&lt;/p&gt;

&lt;p&gt;I hope this letter finds you well. As I sit down to write this, I am reflecting on the journey I have taken as a frontend developer. It has been a transformative experience, and I am grateful for the lessons I have learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embrace A Healthy Portion of Curiosity
&lt;/h2&gt;

&lt;p&gt;Curiosity and willingness to explore new technologies and approaches are essential traits for any developer due to the nature of software development. Don't be afraid to experiment with things outside your comfort zone, but keep it on a healthy level. Don't get lost in the endless sea of new frameworks and libraries; instead, focus on mastering the fundamentals first. In the beginning the &lt;em&gt;fear of missing out&lt;/em&gt; (short FOMO) can be overwhelming, but remember that true growth comes from deep understanding, not just surface-level knowledge of the latest trends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Focus on Fundamentals
&lt;/h2&gt;

&lt;p&gt;During your career you will &lt;strong&gt;ALWAYS&lt;/strong&gt; come back to the fundamentals. Whether it is a specific piece of code of a framework that you are using, or a general concept like accessibility or performance optimization, the fundamentals will always be your foundation. Invest time in understanding HTML, CSS, and JavaScript deeply. These are the building blocks of everything you will create. And believe me that browsing &lt;a href="https://developer.mozilla.org/" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt; will always bring new HTML tags, CSS properties, and JavaScript functions to your attention. For fun and learning you can try something like Powerpoint karaoke: Pick a random MDN article and talk about it for a few minutes as if you were teaching it to someone else – &lt;a href="https://workingdraft.de/gluecksrad/" rel="noopener noreferrer"&gt;The WorkingDraft "Gluecksrad"&lt;/a&gt; is your friend here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Side Projects Whenever Possible
&lt;/h2&gt;

&lt;p&gt;Side projects are invaluable for learning and growth. They allow you to apply what you've learned in a practical way and explore new ideas without the constraints of a work environment. Don't be afraid to start small; even simple projects can teach you a lot. Over time, these side projects will become a portfolio that showcases your skills and creativity. You will never imagine that a weekend project will end up in &lt;a href="https://marketplace.visualstudio.com/items?itemName=andi1984.tinypng" rel="noopener noreferrer"&gt;a tool used by thousands of developers worldwide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network and Connect with Others
&lt;/h2&gt;

&lt;p&gt;Go to meetups, join conferences and try to keep in touch with those people you meet and feel connected to. The developer community is full of talented and passionate individuals who are eager to share their knowledge and experiences. Building a network of peers can provide support, inspiration, and opportunities for collaboration. Don't hesitate to reach out to others for advice or mentorship; most people are happy to help. Especially if you are an introvert like me, try to push yourself a little bit out of your comfort zone. The connections you make can lead to new opportunities and friendships that will enrich your career and personal life.&lt;/p&gt;

&lt;p&gt;Between meeting offline, consider also joining online communities like &lt;a href="https://dev.to/"&gt;Dev.to&lt;/a&gt;, &lt;a href="https://hashnode.com/" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt; where you can engage in discussions, ask questions, and share your own experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use AI as a further tool in your toolbox
&lt;/h2&gt;

&lt;p&gt;Instead of vibe coding all the way down, be eager to &lt;em&gt;learn how AI can help me&lt;/em&gt;. Use it as a further tool in your toolbox, not as a replacement for your own skills. Also review with care and always keep understanding of what is generated. But be open to embrace AI tools as any other tool that can help you as a developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a counterpart outside of coding
&lt;/h2&gt;

&lt;p&gt;In the tech industry it is easy to get lost in the code and the next &lt;em&gt;big thing&lt;/em&gt;, especially when you work remotely where boundaries between work and private life can blur.&lt;/p&gt;

&lt;p&gt;Your private life and human, non-digital interactions are essential for your well-being and overall happiness. Make sure to nurture relationships outside of work, pursue hobbies, and take time to disconnect from screens. Your back, eyes and in general your body will thank you.&lt;/p&gt;

&lt;p&gt;A balanced life will not only make you a happier person but also a more effective and creative developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desk work is poison for your body
&lt;/h2&gt;

&lt;p&gt;Remember to take care of your physical health. Sitting for long hours can lead to various health issues. Make it a habit to take breaks, stretch, and move around regularly. Consider incorporating exercise into your routine, whether it's a daily walk, having a big garden or hitting the gym. Following this in your 20s and 30s will pay off in your 40s and 50s.&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>lessonslearned</category>
      <category>careerdevelopment</category>
    </item>
    <item>
      <title>Self-hosting a Mastodon Instance on a Hetzner Server</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Sun, 10 Aug 2025 20:23:07 +0000</pubDate>
      <link>https://dev.to/andi1984/self-hosting-a-mastodon-instance-on-a-hetzner-server-1fhl</link>
      <guid>https://dev.to/andi1984/self-hosting-a-mastodon-instance-on-a-hetzner-server-1fhl</guid>
      <description>&lt;p&gt;Running your own Mastodon instance gives you full control over moderation, data storage, and community tone.  This guide walks through the basic steps to deploy Mastodon on a Hetzner virtual server using a generic domain such as &lt;code&gt;example.social&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Prepare the server
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Provision an Ubuntu 22.04 LTS VPS at your provider of choice.&lt;/li&gt;
&lt;li&gt;Update packages and install the dependencies listed in the &lt;a href="https://docs.joinmastodon.org/admin/install/#installing-the-last-dependencies" rel="noopener noreferrer"&gt;official installation guide&lt;/a&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
   &lt;span class="c"&gt;# install packages as described in the docs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a dedicated user and switch to it:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;adduser mastodon
   &lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;mastodon
   su - mastodon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Install Mastodon
&lt;/h2&gt;

&lt;p&gt;Clone the repository and install Ruby/Node dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/mastodon/mastodon.git live
&lt;span class="nb"&gt;cd &lt;/span&gt;live
&lt;span class="c"&gt;# checkout latest stable tag&lt;/span&gt;
git checkout &lt;span class="si"&gt;$(&lt;/span&gt;git tag &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; rc | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# install Ruby gems&lt;/span&gt;
gem &lt;span class="nb"&gt;install &lt;/span&gt;bundler
bundle config &lt;span class="nb"&gt;set &lt;/span&gt;deployment &lt;span class="s1"&gt;'true'&lt;/span&gt;
bundle config &lt;span class="nb"&gt;set &lt;/span&gt;without &lt;span class="s1"&gt;'development test'&lt;/span&gt;
bundle &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# install JS packages&lt;/span&gt;
yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--frozen-lockfile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Configure environment variables
&lt;/h2&gt;

&lt;p&gt;Copy the example configuration and adapt it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.production.sample .env.production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;.env.production&lt;/code&gt; and set values for your instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOCAL_DOMAIN=example.social

DB_HOST=/var/run/postgresql
DB_USER=mastodon
DB_NAME=mastodon_production
DB_PASS=change-me

REDIS_URL=redis://localhost:6379/1

# Optional: object storage
S3_ENABLED=true
S3_BUCKET=example-bucket
S3_ENDPOINT=https://us-east-1.example-object-storage.com
S3_HOSTNAME=files.example.social
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Database and assets
&lt;/h2&gt;

&lt;p&gt;Set up the database and precompile assets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rails db:setup
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rails assets:precompile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If asset compilation fails due to lack of memory, add swap:&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;fallocate &lt;span class="nt"&gt;-l&lt;/span&gt; 2G /swapfile
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;600 /swapfile
&lt;span class="nb"&gt;sudo &lt;/span&gt;mkswap /swapfile
&lt;span class="nb"&gt;sudo &lt;/span&gt;swapon /swapfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. Systemd services
&lt;/h2&gt;

&lt;p&gt;Create service files for the three Mastodon processes (&lt;code&gt;mastodon-web&lt;/code&gt;, &lt;code&gt;mastodon-sidekiq&lt;/code&gt;, &lt;code&gt;mastodon-streaming&lt;/code&gt;) as documented in the official guide.  After placing the files under &lt;code&gt;/etc/systemd/system/&lt;/code&gt;, reload and start them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; mastodon-web mastodon-sidekiq mastodon-streaming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can manually restart them at any time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logs are available via &lt;code&gt;journalctl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; mastodon-web &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Nginx and TLS
&lt;/h2&gt;

&lt;p&gt;Create an Nginx config in &lt;code&gt;/etc/nginx/sites-available/mastodon&lt;/code&gt; and link it to &lt;code&gt;sites-enabled&lt;/code&gt;.&lt;br&gt;
The config should proxy requests for &lt;code&gt;example.social&lt;/code&gt; to the Mastodon services and optionally expose an alias such as &lt;code&gt;files.example.social&lt;/code&gt; for object storage.&lt;/p&gt;

&lt;p&gt;Enable HTTPS with Let's Encrypt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; example.social &lt;span class="nt"&gt;-d&lt;/span&gt; files.example.social
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Certificates renew automatically via a cron job, but you can trigger it manually with &lt;code&gt;certbot renew&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Backups
&lt;/h2&gt;

&lt;p&gt;Combine regular PostgreSQL dumps with &lt;a href="https://www.borgbackup.org/" rel="noopener noreferrer"&gt;BorgBackup&lt;/a&gt; to create encrypted, deduplicated archives.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Borg and initialise a repository on remote storage:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;borgbackup
   &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BORG_REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ssh://user@backup.example.com/~/mastodon-borg
   borg init &lt;span class="nt"&gt;--encryption&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;repokey &lt;span class="nv"&gt;$BORG_REPO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a backup script (&lt;code&gt;/root/backup-mastodon.sh&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
   &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail
   &lt;span class="nv"&gt;DATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y-%m-%d&lt;span class="si"&gt;)&lt;/span&gt;

   pg_dump &lt;span class="nt"&gt;--username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c mastodon_production &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/db.dump

   borg create &lt;span class="nt"&gt;--compression&lt;/span&gt; zstd,3 &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nv"&gt;$BORG_REPO&lt;/span&gt;::&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DATE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     /home/mastodon/live/.env.production &lt;span class="se"&gt;\&lt;/span&gt;
     /tmp/db.dump &lt;span class="se"&gt;\&lt;/span&gt;
     /home/mastodon/live/public/system

   borg prune &lt;span class="nt"&gt;--keep-daily&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7 &lt;span class="nt"&gt;--keep-weekly&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4 &lt;span class="nt"&gt;--keep-monthly&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12 &lt;span class="nv"&gt;$BORG_REPO&lt;/span&gt;
   &lt;span class="nb"&gt;rm&lt;/span&gt; /tmp/db.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Schedule it nightly via cron:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
   0 1 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /root/backup-mastodon.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script dumps the database, backs up configuration and media files, prunes old archives, and removes temporary dumps. Store a &lt;code&gt;.pgpass&lt;/code&gt; file in &lt;code&gt;/root&lt;/code&gt; to avoid interactive passwords.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Automated cleanup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ricard.dev/improving-mastodons-disk-usage/" rel="noopener noreferrer"&gt;Ricard Torres&lt;/a&gt; suggests running periodic &lt;code&gt;tootctl&lt;/code&gt; tasks to purge unused media and cache files. Create &lt;code&gt;/home/mastodon/cleanup.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production /home/mastodon/live/bin/tootctl accounts prune
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production /home/mastodon/live/bin/tootctl statuses remove &lt;span class="nt"&gt;--days&lt;/span&gt; 4
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production /home/mastodon/live/bin/tootctl media remove &lt;span class="nt"&gt;--days&lt;/span&gt; 4
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production /home/mastodon/live/bin/tootctl media remove &lt;span class="nt"&gt;--remove-headers&lt;/span&gt; &lt;span class="nt"&gt;--include-follows&lt;/span&gt; &lt;span class="nt"&gt;--days&lt;/span&gt; 0
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production /home/mastodon/live/bin/tootctl preview_cards remove &lt;span class="nt"&gt;--days&lt;/span&gt; 4
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production /home/mastodon/live/bin/tootctl media remove-orphans
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it weekly with cron:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
0 3 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; 0 /home/mastodon/cleanup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands reclaim disk space by pruning remote accounts, old statuses, cached media, and orphaned files.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Useful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.joinmastodon.org/admin/install/" rel="noopener noreferrer"&gt;Official Mastodon installation guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.joinmastodon.org/admin/optional/object-storage/" rel="noopener noreferrer"&gt;Using object storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.joinmastodon.org/admin/optional/object-storage-proxy/" rel="noopener noreferrer"&gt;Object storage proxying&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/McKael/mastodon-documentation/blob/master/Running-Mastodon/Administration-guide.md" rel="noopener noreferrer"&gt;Administration guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ricard.dev/improving-mastodons-disk-usage/" rel="noopener noreferrer"&gt;Improving Mastodon's disk usage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;With the basics in place, you can now invite users, theme your instance, or automate maintenance tasks. Happy federating!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>mastodon</category>
      <category>fediverse</category>
    </item>
    <item>
      <title>Nice #howto #article on how to clear #systemd journal #logs https://linuxhandbook.com/clear-systemd-journal-logs/</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Mon, 14 Jul 2025 19:51:45 +0000</pubDate>
      <link>https://dev.to/andi1984/nice-howto-article-on-how-to-clear-systemd-journal-logs-3195</link>
      <guid>https://dev.to/andi1984/nice-howto-article-on-how-to-clear-systemd-journal-logs-3195</guid>
      <description></description>
      <category>linux</category>
      <category>systemdesign</category>
      <category>devops</category>
      <category>howto</category>
    </item>
    <item>
      <title>Exploring HTMX Integration with Go Backend</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Wed, 17 Jan 2024 21:01:38 +0000</pubDate>
      <link>https://dev.to/andi1984/exploring-htmx-integration-with-go-backend-4gb2</link>
      <guid>https://dev.to/andi1984/exploring-htmx-integration-with-go-backend-4gb2</guid>
      <description>&lt;p&gt;Hello developers,&lt;/p&gt;

&lt;p&gt;Let's dive into the practicalities of combining HTMX with a Go backend for web development. This approach aims to provide a practical, balanced enhancement to web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;HTMX introduces simplicity and effectiveness to web development. Integrating it with a Go backend can offer a responsive user experience. We'll go through the setup, exploring how these technologies can be employed together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Demo on GitHub
&lt;/h2&gt;

&lt;p&gt;For those eager to experiment, there's a simple demo available on &lt;a href="https://github.com/andi1984/htmx-go"&gt;GitHub&lt;/a&gt;. The repository contains code snippets and configurations, offering a hands-on experience to understand the integration process.&lt;/p&gt;

&lt;h2&gt;
  
  
  YouTube Overview
&lt;/h2&gt;

&lt;p&gt;Additionally, there's a brief overview on &lt;a href="https://youtu.be/UwxLOFvwBI0"&gt;YouTube&lt;/a&gt;, providing insights into HTMX. While it's not a tutorial, it serves as an introductory glimpse into what HTMX brings to the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why HTMX with Go?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Streamlined AJAX Integration&lt;/strong&gt;: HTMX simplifies AJAX integration directly into HTML, reducing reliance on complex JavaScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leveraging Go's Concurrency Model&lt;/strong&gt;: Utilize Go's concurrency model to efficiently handle multiple connections, ensuring a responsive user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability and Readability&lt;/strong&gt;: Combining HTMX with Go results in clean, readable code, facilitating collaboration and scalability.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In summary, the combination of HTMX with a Go backend shows promise for web development. The GitHub repository provides a simple demo for practical exploration, and the YouTube overview offers a glimpse into HTMX's capabilities. Feel free to adapt and integrate these technologies as needed for your projects. Happy coding!&lt;/p&gt;

</description>
      <category>htmx</category>
      <category>webdev</category>
      <category>go</category>
    </item>
    <item>
      <title>Bridging Communities: An Overview of the WordPress ActivityPub Plugin</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Thu, 26 Oct 2023 13:00:00 +0000</pubDate>
      <link>https://dev.to/andi1984/bridging-communities-an-overview-of-the-wordpress-activitypub-plugin-o9o</link>
      <guid>https://dev.to/andi1984/bridging-communities-an-overview-of-the-wordpress-activitypub-plugin-o9o</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Bridging Communities: An Overview of the WordPress ActivityPub Plugin&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;In a world constantly growing more interconnected, online communities are flourishing on various platforms. As a byproduct of this digital evolution, there's a rising need for diverse platforms to interact seamlessly with each other. This is where protocols like &lt;strong&gt;ActivityPub&lt;/strong&gt; play a pivotal role by promoting cross-platform interactions. For &lt;strong&gt;WordPress&lt;/strong&gt;, a platform that powers a significant portion of the web, integrating with ActivityPub through plugins is a strategic advancement. This post delves into the &lt;a href="https://wordpress.org/plugins/activitypub/"&gt;&lt;strong&gt;WordPress ActivityPub plugin&lt;/strong&gt;&lt;/a&gt;, highlighting its features, installation process, and the benefits it brings to the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is ActivityPub?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ActivityPub&lt;/strong&gt; is a decentralized social networking protocol that enables various platforms to communicate with each other. Through ActivityPub, users on one platform can &lt;em&gt;follow, update, and interact&lt;/em&gt; with users on another platform seamlessly. This interoperability breaks down silos and cultivates a more inclusive digital ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;WordPress Meets ActivityPub&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;WordPress ActivityPub plugin&lt;/strong&gt; transforms your WordPress site into a federated social network member. Once installed and activated, your website can interact with other platforms that support the &lt;strong&gt;ActivityPub protocol&lt;/strong&gt;, like Mastodon, Pleroma, or PeerTube.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Features of the WordPress ActivityPub Plugin&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Cross-platform Communication&lt;/strong&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The primary advantage is the ability to communicate across different platforms, expanding your site's reach and engagement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Follow and Be Followed&lt;/strong&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Users can &lt;em&gt;follow&lt;/em&gt; your WordPress site and receive updates, and vice versa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Comment Synchronization&lt;/strong&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Comments can be synced between your WordPress site and federated networks, maintaining a cohesive discussion thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Customizable Activity Streams&lt;/strong&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tailor the information you share and receive by customizing your activity streams.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Installation Process&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Installing the &lt;strong&gt;WordPress ActivityPub plugin&lt;/strong&gt; is straightforward. Navigate to the 'Plugins' section in your WordPress dashboard, click on 'Add New', and search for 'ActivityPub'. Click 'Install' and then 'Activate'.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Bigger Picture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The integration of &lt;strong&gt;ActivityPub&lt;/strong&gt; in WordPress via this plugin is more than just a technical enhancement; it's a step towards a more open and interconnected digital community. By bridging the gap between WordPress and the Fediverse, website owners can now partake in a larger, diversified conversation, fostering a sense of global digital camaraderie.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;WordPress ActivityPub plugin&lt;/strong&gt; is a testament to the open-source spirit, embodying the ethos of community, collaboration, and freedom that the digital realm can aspire to.&lt;/p&gt;

&lt;p&gt;As digital landscapes continue to evolve, the incorporation of protocols like &lt;strong&gt;ActivityPub&lt;/strong&gt; will increasingly become the norm rather than the exception, paving the way for a more inclusive and interactive web.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>activitypub</category>
      <category>fediverse</category>
    </item>
    <item>
      <title>Automatic Minimum Size of Flex Items</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Wed, 11 Oct 2023 14:07:00 +0000</pubDate>
      <link>https://dev.to/andi1984/automatic-minimum-size-of-flex-items-20af</link>
      <guid>https://dev.to/andi1984/automatic-minimum-size-of-flex-items-20af</guid>
      <description>&lt;p&gt;Today I would like to talk about flexbox and the automatic minimum size of flex items, means how the flexbox algorithm is internally calculating the minium size of flex child elements aka. flex items.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let us start looking at some example code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
    eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
    voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
    clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
    amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
    nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed
    diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
    clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
    amet.
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;50px&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;What do you think? How much will the height be of the &lt;code&gt;div&lt;/code&gt; flex child? &lt;strong&gt;It will be the minimum size the content will need to be rendered.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example (Overflow container)
&lt;/h2&gt;

&lt;p&gt;Let us adjust the example by making the flex-child element a scroll container on its own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scroll&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;What will the height be now? &lt;strong&gt;It will be the flex-basis of 50px.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;Why is that you my ask and I asked that myself several times. Having a look into the official specs can be helpful here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To provide a more reasonable default minimum size for flex items, the used value of a main axis automatic minimum size on a flex item that is not a scroll container is a content-based minimum size; for scroll containers the automatic minimum size is zero, as usual.&lt;br&gt;
-- &lt;cite&gt;&lt;a href="https://www.w3.org/TR/css-flexbox-1/#min-size-auto"&gt;W3C spec&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thus this means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For non-scroll containers, flexbox automatically increases the main axis minimum size to fit the content's needs&lt;/li&gt;
&lt;li&gt;For scroll containers, flexbox sets the minimum size to zero&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Flexbox is a great standard for flexible layouts. But especially on column based layouts I always have to remember myself about the situation shown above, that I need to specify a &lt;code&gt;min-height&lt;/code&gt; to make sure that the element is not increasing its height to fit the content. It always sounds counter intuitive to me, thus it is always good to read again through the specification in such kind of situations.&lt;/p&gt;

&lt;p&gt;I hope this was also helpful to you.&lt;/p&gt;

&lt;p&gt;Greets,&lt;/p&gt;

&lt;p&gt;Andi&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Container Queries in CSS: The Cool New Kid on the Block</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Sun, 08 Oct 2023 19:30:00 +0000</pubDate>
      <link>https://dev.to/andi1984/container-queries-in-css-the-cool-new-kid-on-the-block-3kck</link>
      <guid>https://dev.to/andi1984/container-queries-in-css-the-cool-new-kid-on-the-block-3kck</guid>
      <description>&lt;p&gt;Hey there, web design fans! Have you ever pulled your hair out trying to make a design look great on every screen size? Well, guess what? The web design world is abuzz with something new and exciting, and it's about to make your life a whole lot easier. Say hello to container queries in CSS!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the Big Deal About Container Queries?
&lt;/h2&gt;

&lt;p&gt;Let's break it down. In the past, if you wanted to change how something looked based on the size of the browser window, you'd use media queries. They were like magic wands for making sites look good on any device. But they were more like a one-size-fits-all solution.&lt;/p&gt;

&lt;p&gt;Now, container queries have come onto the scene, and they're more like having a tailor-made suit. Instead of looking at the whole browser window, container queries look at the size of the container an element is in. That means you can have more control and flexibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Quick Peek at How They Work
&lt;/h2&gt;

&lt;p&gt;Here's a super simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;both&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="n"&gt;inline-size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lightblue&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;With this, the inside element gets a fancy light blue background if the container is at least 500px wide. Cool, right? It's all about that &lt;code&gt;contain&lt;/code&gt; property, making things all nice and tidy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should You Care?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Rocking the Component-Driven Design&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine building blocks that adapt themselves no matter where you put them on the page. That's what container queries can do. They make building reusable, flexible components a breeze.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;No More Spaghetti Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Say goodbye to messy CSS that’s harder to untangle than a plate of spaghetti. With container queries, everything's more organized, like a neatly packed lunch box.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Unleashing Your Inner Designer&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Feel like an artist? Now you can paint even more intricate layouts without having to rely on global viewport sizes. Unleash your creativity and let your designs shine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser Support: The Not-So-Cool Part
&lt;/h2&gt;

&lt;p&gt;Okay, so here's the kicker: container queries are still pretty new, and not all browsers have gotten on board with them. But trust me, once they see how cool this is, they'll catch up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping It Up
&lt;/h2&gt;

&lt;p&gt;Container queries are like the cool new kid on the block who everyone wants to hang out with. They're all about giving you more control, letting you write cleaner code, and just making everything more fun.&lt;/p&gt;

&lt;p&gt;Whether you're a seasoned pro or just getting started with responsive design, give container queries a whirl. They might just become your new best friend in web development.&lt;/p&gt;

&lt;p&gt;So what are you waiting for? Dive in and start playing with container queries. Who knows what amazing things you'll create? Happy coding! 🎉&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The ugly part of CSS-in-JS</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Thu, 28 Sep 2023 20:12:26 +0000</pubDate>
      <link>https://dev.to/andi1984/the-ugly-part-of-css-in-js-2iph</link>
      <guid>https://dev.to/andi1984/the-ugly-part-of-css-in-js-2iph</guid>
      <description>&lt;p&gt;One often-overlooked aspect of CSS-in-JS is its "dark side"—the "JS" part. What does this mean? Essentially, when you're writing your styles &lt;strong&gt;within&lt;/strong&gt; JavaScript, you expose yourself to the quirks and intricacies of JS itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Issue Illustrated
&lt;/h3&gt;

&lt;p&gt;Consider the following example:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/css-in-js-ugly-part-vcmtx5"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You might notice that the styles defined in &lt;code&gt;IBreakStyles&lt;/code&gt; aren't applied as expected. Digging into the element with your development tools reveals a complete absence of styles.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Root Cause
&lt;/h3&gt;

&lt;p&gt;The culprit is a stray closing curly bracket within the template literal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IBreakStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="s2"&gt;`
  padding: &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;$count&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}; /* &amp;lt;-- The offender */
  color: red;
  background-color: blue;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens is that the CSS-in-JS library (in this case, styled-components) interprets the template literal in a specific way. This leads to parsing the CSS via JavaScript, and the stray curly bracket disrupts the intended behavior—likely closing some parent block in the JS logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Silent Problem
&lt;/h3&gt;

&lt;p&gt;The real issue is the absence of any alert mechanism: no errors are thrown, and no red squiggly lines appear in your editor to warn you. If you're fortunate, your editor's CSS-in-JS tooling might catch this, but that's not a guarantee.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Thought to Ponder
&lt;/h3&gt;

&lt;p&gt;Given these complexities, it's worth questioning if a separation of concerns—CSS in CSS files and JS in JS files—might not be a more foolproof approach, much like the "good old times."&lt;/p&gt;

&lt;p&gt;Best regards,&lt;br&gt;&lt;br&gt;
Andi&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Evolution of Remote Work: Insights from Eight Years of Experience</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Sun, 27 Aug 2023 10:16:58 +0000</pubDate>
      <link>https://dev.to/andi1984/the-evolution-of-remote-work-insights-from-eight-years-of-experience-3183</link>
      <guid>https://dev.to/andi1984/the-evolution-of-remote-work-insights-from-eight-years-of-experience-3183</guid>
      <description>&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evolution of Remote Work&lt;/strong&gt;: While the Covid-19 pandemic popularized remote work, some professionals had already been working remotely for years. The article offers insights from nearly eight years of remote work experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Challenges and Best Practices&lt;/strong&gt;: Remote work presents challenges like blurring work-life boundaries and missing face-to-face interactions. Best practices include designating a separate workspace, understanding core working hours, using video calls for better communication, and emphasizing asynchronous communication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Not a Universal Solution&lt;/strong&gt;: While remote work offers flexibility and has proven viable during the pandemic, it's not suitable for everyone. A company's success is determined more by its culture than its work model, as highlighted in an external Forbes article.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;During the height of the Covid-19 pandemic, remote work became the norm. Numerous companies transitioned to offering remote work options, and &lt;a href="https://www.statista.com/statistics/1122987/change-in-remote-work-trends-after-covid-in-usa/"&gt;many continue to do so&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, some of us, including myself, had the privilege of working remotely long before the pandemic hit. In this article, I'll share my reflections on nearly eight years of remote work and the lesser-discussed aspects of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Importance of Work-Life Boundaries
&lt;/h2&gt;

&lt;p&gt;The pandemic forced many to adapt to working from unconventional spaces like kitchens and living rooms. While this shift posed physical challenges, it also blurred the lines between personal and professional life. The omnipresence of work can be overwhelming.&lt;/p&gt;

&lt;p&gt;If feasible, both financially and spatially, it's beneficial to designate a separate workspace within your home. In countries like Germany, having a dedicated workspace can also have tax and insurance implications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Core Working Hours
&lt;/h2&gt;

&lt;p&gt;While remote work offers flexibility in terms of where and when you work, there are often unspoken expectations about core working hours. Your employer likely has a window of time during which they expect you to be available.&lt;/p&gt;

&lt;p&gt;The beauty of remote work is the ability to weave in personal errands or appointments, but this flexibility varies based on your role and company culture. Over time, you'll become attuned to your colleagues' schedules and availabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Connections: Turn on Your Camera
&lt;/h2&gt;

&lt;p&gt;Remote work lacks the nuances of face-to-face interactions. In a physical office, subtle cues like facial expressions provide context. When working remotely, video calls can bridge this gap.&lt;/p&gt;

&lt;p&gt;It's beneficial for team members to have their cameras on during meetings. This fosters better communication and understanding. Additionally, in-person meetups and retreats can strengthen team bonds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of Asynchronous Communication
&lt;/h2&gt;

&lt;p&gt;In a remote setting, you can't just walk over to a colleague's desk for a quick chat. Asynchronous communication becomes crucial. Document everything—from decisions to meeting minutes—and ensure they're accessible to the team. Whether it's a wiki, a ticketing system, or a chat platform, consistency in documentation is key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remote Work Isn't One Size Fits All
&lt;/h2&gt;

&lt;p&gt;While the pandemic highlighted the viability of remote work, it's not suitable for everyone or every job. Some may struggle with the isolation, miss casual office interactions, or find it challenging to maintain discipline.&lt;/p&gt;

&lt;p&gt;Remote work is a testament to the adaptability of the modern workforce, but it's not the ideal setup for everyone. As highlighted in this &lt;a href="https://www.forbes.com/sites/johnrau/2023/08/22/does-remote-work-hurt-workplace-culture-thats-the-wrong-question/?sh=749b2c641ca3"&gt;Forbes article&lt;/a&gt;, a company's success isn't solely based on its work model but its culture.&lt;/p&gt;

</description>
      <category>remote</category>
      <category>workplace</category>
      <category>life</category>
    </item>
    <item>
      <title>Setting Up a Node CLI with ChatGPT</title>
      <dc:creator>Andreas Sander</dc:creator>
      <pubDate>Tue, 15 Aug 2023 17:52:42 +0000</pubDate>
      <link>https://dev.to/andi1984/setting-up-a-node-cli-with-chatgpt-4j9m</link>
      <guid>https://dev.to/andi1984/setting-up-a-node-cli-with-chatgpt-4j9m</guid>
      <description>&lt;p&gt;Hey devcommunity! 🚀&lt;/p&gt;

&lt;p&gt;I've been diving into setting up a Node CLI using a ChatGPT account account. Apart from the intricacies of the access token, I found the process to be pretty straightforward. If anyone's interested, I just built up this &lt;a href="https://github.com/andi1984/chatgpt-demo"&gt;very fast sample repo&lt;/a&gt; that might be helpful as a starter.&lt;/p&gt;

&lt;p&gt;On a related note, for those looking into automatic access token generation, I stumbled upon &lt;a href="https://github.com/michael-dm/openai-token"&gt;openai-token&lt;/a&gt;. It seems to work with a username/password combo. Has anyone tried this or have any thoughts on it?&lt;/p&gt;

&lt;p&gt;Would love to hear your experiences or any tips you might have building ChatGPT CLIs via TypeScript! 💡&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>discuss</category>
      <category>node</category>
    </item>
  </channel>
</rss>
