<?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: PRATYAY MUSTAFI</title>
    <description>The latest articles on DEV Community by PRATYAY MUSTAFI (@pratyay360).</description>
    <link>https://dev.to/pratyay360</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%2F4125176%2Fc7c8f512-4591-4f50-b48e-a5a43104fe46.jpg</url>
      <title>DEV Community: PRATYAY MUSTAFI</title>
      <link>https://dev.to/pratyay360</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pratyay360"/>
    <language>en</language>
    <item>
      <title>Lightcms: A CMS that allows you to rediscover the writer Within You ✍️</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Tue, 27 Oct 2026 11:38:57 +0000</pubDate>
      <link>https://dev.to/pratyay360/lightcms-a-cms-that-allows-you-to-rediscover-the-writer-within-you-226i</link>
      <guid>https://dev.to/pratyay360/lightcms-a-cms-that-allows-you-to-rediscover-the-writer-within-you-226i</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh4ous92oft8gmvw08p4t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh4ous92oft8gmvw08p4t.png" alt=" " width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LightCMS is an easy to use, interactive, Git based CMS built to make the process of writing as enjoyable as possible.&lt;/p&gt;

&lt;p&gt;Light cms by default is compatible with any static site generator (SSG) which supports front matter schema, LightCMS makes creating, managing, and publishing content enjoyable.&lt;/p&gt;

&lt;p&gt;Whether you’re sharing your experiences, documenting your journey, or putting your thoughts into words, LightCMS makes it easier to turn your ideas into something meaningful.&lt;/p&gt;

&lt;p&gt;Give LightCMS a try. You won’t regret the time you spend exploring it!&lt;/p&gt;

&lt;p&gt;Live: &lt;a href="https://www.lightcms.me/" rel="noopener noreferrer"&gt;https://www.lightcms.me/&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/light-cms/lightcms" rel="noopener noreferrer"&gt;https://github.com/light-cms/lightcms&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hugo</category>
      <category>lightcms</category>
      <category>svelte</category>
      <category>opensource</category>
    </item>
    <item>
      <title>newsy a free to use zero hastle newsletter platform for your static sites powered by github.</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Thu, 15 Oct 2026 12:11:40 +0000</pubDate>
      <link>https://dev.to/pratyay360/newsy-a-free-to-use-zero-hastle-newsletter-platform-for-your-static-sites-powered-by-github-5e0o</link>
      <guid>https://dev.to/pratyay360/newsy-a-free-to-use-zero-hastle-newsletter-platform-for-your-static-sites-powered-by-github-5e0o</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb" class="crayons-story__hidden-navigation-link"&gt;GitHub: Enable Newsletter Using newsy Widget.&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 href="/pratyay360" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4125176%2Fc7c8f512-4591-4f50-b48e-a5a43104fe46.jpg" alt="pratyay360 profile" class="crayons-avatar__image" width="215" height="215"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/pratyay360" class="crayons-story__secondary fw-medium m:hidden"&gt;
              PRATYAY MUSTAFI
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                PRATYAY MUSTAFI
                
                
              
              &lt;div id="story-author-preview-content-4856338" 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="/pratyay360" 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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4125176%2Fc7c8f512-4591-4f50-b48e-a5a43104fe46.jpg" class="crayons-avatar__image" alt="" width="215" height="215"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;PRATYAY MUSTAFI&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;/div&gt;
          &lt;a href="https://dev.to/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 15&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/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb" id="article-link-4856338"&gt;
          GitHub: Enable Newsletter Using newsy Widget.
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&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/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&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/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb#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;
            1 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>github</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Thu, 15 Oct 2026 12:08:32 +0000</pubDate>
      <link>https://dev.to/pratyay360/-1bha</link>
      <guid>https://dev.to/pratyay360/-1bha</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb" class="crayons-story__hidden-navigation-link"&gt;GitHub: Enable Newsletter Using newsy Widget.&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 href="/pratyay360" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4125176%2Fc7c8f512-4591-4f50-b48e-a5a43104fe46.jpg" alt="pratyay360 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/pratyay360" class="crayons-story__secondary fw-medium m:hidden"&gt;
              PRATYAY MUSTAFI
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                PRATYAY MUSTAFI
                
                
              
              &lt;div id="story-author-preview-content-4856338" 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="/pratyay360" 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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4125176%2Fc7c8f512-4591-4f50-b48e-a5a43104fe46.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;PRATYAY MUSTAFI&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;/div&gt;
          &lt;a href="https://dev.to/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 15&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/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb" id="article-link-4856338"&gt;
          GitHub: Enable Newsletter Using newsy Widget.
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&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/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&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/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb#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;
            1 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>github</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>GitHub: Enable Newsletter Using newsy Widget.</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Thu, 15 Oct 2026 12:07:50 +0000</pubDate>
      <link>https://dev.to/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb</link>
      <guid>https://dev.to/pratyay360/github-enable-newsletter-using-httpsnewsylightcmsme-widget-2plb</guid>
      <description>&lt;p&gt;&lt;strong&gt;Newsy turns your GitHub repo into a newsletter platform.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you run a Hugo, Astro, Next.js, or Jekyll blog, your posts are already&lt;br&gt;
Markdown files in Git. Your newsletter can live there too — no database,&lt;br&gt;
no SaaS fee.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/light-cms" rel="noopener noreferrer"&gt;
        light-cms
      &lt;/a&gt; / &lt;a href="https://github.com/light-cms/newsy" rel="noopener noreferrer"&gt;
        newsy
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      github backed newsletter platform  for your static site 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/9126d8310e9c4d05cb5cde6a37a1d9d09ec6715f3655ed217b5dcbfe146c2ab9/68747470733a2f2f736869656c64636e2e6465762f6865616465722f6772616469656e742e7376673f7469746c653d4e65777379267375627469746c653d412b4769744875622b6261636b65642b73696d706c652b6e6577736c65747465722b736572766963652b666f722b796f75722b7374617469632b73697465266d6f64653d6461726b"&gt;&lt;img alt="header" src="https://camo.githubusercontent.com/9126d8310e9c4d05cb5cde6a37a1d9d09ec6715f3655ed217b5dcbfe146c2ab9/68747470733a2f2f736869656c64636e2e6465762f6865616465722f6772616469656e742e7376673f7469746c653d4e65777379267375627469746c653d412b4769744875622b6261636b65642b73696d706c652b6e6577736c65747465722b736572766963652b666f722b796f75722b7374617469632b73697465266d6f64653d6461726b"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;   &lt;a href="https://camo.githubusercontent.com/019e081ab0d32510d3828b19e85449e284afd6fa9b752e84e8ebcae78ad56ec8/68747470733a2f2f736869656c64636e2e6465762f6769746875622f73746172732f507261747961793336302f6e657773792e7376673f76617269616e743d7365636f6e64617279267468656d653d656d6572616c64266d6f64653d6c6967687426666f6e743d6a6574627261696e732d6d6f6e6f" class="article-body-image-wrapper"&gt;&lt;img alt="GitHub Stars" src="https://camo.githubusercontent.com/019e081ab0d32510d3828b19e85449e284afd6fa9b752e84e8ebcae78ad56ec8/68747470733a2f2f736869656c64636e2e6465762f6769746875622f73746172732f507261747961793336302f6e657773792e7376673f76617269616e743d7365636f6e64617279267468656d653d656d6572616c64266d6f64653d6c6967687426666f6e743d6a6574627261696e732d6d6f6e6f"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt; &lt;a href="https://github.com/light-cms/newsy" rel="noopener noreferrer"&gt; &lt;img alt="GitHub repository" src="https://camo.githubusercontent.com/704dacf5544a842a32f3cadfac4952a12f801d8e1105c971a98cc9fe670427e2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4769744875622d6c696768742d636d732532466e657773792d3138313731373f6c6f676f3d676974687562"&gt; &lt;/a&gt; &lt;a href="https://github.com/light-cms/newsy/blob/main/LICENSE" rel="noopener noreferrer"&gt; &lt;img alt="License" src="https://camo.githubusercontent.com/6b65cb60cc7d1654510b1f9e6ffbfc6f352830d2e3740153c8d9ad3e98e8f58e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6c696768742d636d732f6e65777379"&gt; &lt;/a&gt; &lt;a href="https://github.com/light-cms/newsy/graphs/contributors" rel="noopener noreferrer"&gt; &lt;img alt="Contributors" src="https://camo.githubusercontent.com/8edb80aeccbfaa54e27a0a4cbc6e8ebdee3bddf13686801286596b7686d9571f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6c696768742d636d732f6e65777379"&gt; &lt;/a&gt; &lt;a href="https://github.com/light-cms/newsy/forks" rel="noopener noreferrer"&gt; &lt;img alt="Forks" src="https://camo.githubusercontent.com/5e73eec06fe7d414d752e249f5aa7d7b6fba77cf243d2faa2c7255c96ab6c64f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f6c696768742d636d732f6e65777379"&gt; &lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;newsy&lt;/strong&gt; is a newsletter platform for your static site, using GitHub as a backend , inspired by &lt;a href="https://utteranc.es" rel="nofollow noopener noreferrer"&gt;utterances&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Read more about it in the &lt;a href="https://docs.lightcms.me/guides/newsy/getstarted/" rel="nofollow noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;📝 &lt;strong&gt;Zero-friction publishing&lt;/strong&gt; — newly &lt;em&gt;added&lt;/em&gt; post files trigger an announcement, and so does flipping an existing post from draft to published; other edits and deletes are ignored&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;💬 &lt;strong&gt;Issue as newsletter&lt;/strong&gt; — upserts one open issue per repo comments thereafter, with lock and unlocking capability&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fully free and opensource&lt;/strong&gt; — no need to pay for any newsletter service, just use your existing GitHub repo.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/light-cms/newsy/demo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fraw.githubusercontent.com%2Flight-cms%2Fnewsy%2FHEAD%2Fdemo.gif" alt="newsy demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Video guides:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=sfjo6ZVgC9w" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/959dca5ce7ad0afa9e4b8aa577c128f3702fd2e3cd8a66529e8a9335041db7d7/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f73666a6f365a56674339772f6d617872657364656661756c742e6a7067" alt="New guide – sfjo6ZVgC9w"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Quick start&lt;/h2&gt;
&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install the GitHub App&lt;/strong&gt; on the repo(s) you publish from:&lt;/p&gt;
&lt;p&gt;👉 &lt;a href="https://github.com/apps/newsletter-newsy/installations/select_target" rel="noopener noreferrer"&gt;https://github.com/apps/newsletter-newsy/installations/select_target&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Push a new post:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git add posts/hello-world.md
git commit -m &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;hello world&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;
git push&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;newsy will create (or comment on) an open issue titled &lt;code&gt;announcement&lt;/code&gt; with label &lt;code&gt;newsletter&lt;/code&gt; containing the commit summary, file list, and…&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/light-cms/newsy" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the GitHub App on your blog repo.&lt;/li&gt;
&lt;li&gt;Publish a new post,&lt;/li&gt;
&lt;li&gt;Newsy automatically opens an Announcement with your post content.
Readers subscribe to that issue and get notified whenever you publish.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Drafts (&lt;code&gt;draft: true&lt;/code&gt; in front matter) are detected and skipped&lt;br&gt;
automatically. Free and open source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add a Subscribe button in 10 seconds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generate one at &lt;a href="//newsy.lightcms.me"&gt;newsy.lightcms.me&lt;/a&gt; and paste it into your static site.&lt;/p&gt;

&lt;p&gt;Built in Go, inspired by &lt;a href="https://github.com/utterance/utterances" rel="noopener noreferrer"&gt;utterances&lt;/a&gt;. and &lt;a href="https://doveletter.dev/" rel="noopener noreferrer"&gt;dove letter&lt;/a&gt;&lt;br&gt;
Self hostable on Vercel or any server less platform.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Why Your Tauri based appImage not working on Linux (And How to Fix It)</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Sat, 10 Oct 2026 15:31:00 +0000</pubDate>
      <link>https://dev.to/pratyay360/why-your-tauri-based-appimage-not-working-on-linux-and-how-to-fix-it-h68</link>
      <guid>https://dev.to/pratyay360/why-your-tauri-based-appimage-not-working-on-linux-and-how-to-fix-it-h68</guid>
      <description>&lt;h2&gt;Tauri Apps Built as Appimages are not working on modern linux distributions, like fedora, arch&lt;/h2&gt;
&lt;p&gt;Appimages are one of the nicest ways to distribute an app but not being able to run a format meant to be used on multiple os, is a bad thing. Appimage as a format is crucial for users who want to test a app and use it without the need of installing. Appimages are cool as they comes with all the required dependencies and can be operated on systems such as Windows with WSL2 and FreeBSD with the Linuxulator. Appimages are self contained in nature and requires no root access.&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%2Fi.ibb.co%2FSzdDWNG%2FScreenshot-20261010-211137-png.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%2Fi.ibb.co%2FSzdDWNG%2FScreenshot-20261010-211137-png.png" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class="constant function"&gt;Gtk-Message:&lt;/span&gt; &lt;span class="constant"&gt;21:07:08.168:&lt;/span&gt; &lt;span class="constant"&gt;Failed&lt;/span&gt; &lt;span class="constant"&gt;to&lt;/span&gt; &lt;span class="constant"&gt;load&lt;/span&gt; &lt;span class="constant"&gt;module&lt;/span&gt; &lt;span class="string constant"&gt;"appmenu-gtk-module"&lt;/span&gt;&lt;span class="constant"&gt;:&lt;/span&gt; &lt;span class="string constant"&gt;'gtk_module_display_init'&lt;/span&gt;&lt;span class="constant"&gt;:&lt;/span&gt; &lt;span class="constant"&gt;/usr/lib64/gtk-3.0/modules/libcolorreload-gtk-module.so:&lt;/span&gt; &lt;span class="constant"&gt;undefined&lt;/span&gt; &lt;span class="constant"&gt;symbol:&lt;/span&gt; &lt;span class="constant"&gt;gtk_module_display_init&lt;/span&gt;&lt;br&gt;
&lt;span class="constant function"&gt;Could&lt;/span&gt; &lt;span class="constant"&gt;not&lt;/span&gt; &lt;span class="constant"&gt;create&lt;/span&gt; &lt;span class="constant"&gt;default&lt;/span&gt; &lt;span class="constant"&gt;EGL&lt;/span&gt; &lt;span class="constant"&gt;display:&lt;/span&gt; &lt;span class="constant"&gt;EGL_BAD_PARAMETER.&lt;/span&gt; &lt;span class="constant"&gt;Aborting...&lt;/span&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;&lt;span class="constant function"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;apiark:185476&lt;/span&gt;): &lt;span&gt;WARNING&lt;/span&gt; &lt;span&gt;&lt;/span&gt;&lt;/strong&gt;: &lt;span class="constant"&gt;21:07:33.334:&lt;/span&gt; &lt;span class="constant"&gt;atk-bridge:&lt;/span&gt; &lt;span class="constant"&gt;get_device_events_reply:&lt;/span&gt; &lt;span class="constant"&gt;unknown&lt;/span&gt; &lt;span class="constant"&gt;signature&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;p&gt;This is a sample app image for a Tauri based rest-api client &lt;a href="https://apiark.dev/" rel="noopener noreferrer"&gt;apiark&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, I was building &lt;a href="https://pratyay360.github.io/drawx/" rel="noopener noreferrer"&gt;Drawx&lt;/a&gt;, the offline version of &lt;a href="https://github.com/Pratyay360/drawy" rel="noopener noreferrer"&gt;drawy&lt;/a&gt;, which provides data sovereignty because nothing ever leaves your machine. However, the Drawx app was not working on my machine because of some odd issues. I wanted to run the AppImage in a portable manner, but using environment variables did not help. Setting &lt;code&gt;WEBKIT_DISABLE_DMABUF_RENDERER=1&lt;/code&gt; or &lt;code&gt;WEBKIT_DISABLE_COMPOSITING_MODE=1&lt;/code&gt; either caused a crash on launch or displayed a blank screen. The issue is that the CI environment adds libraries such as &lt;code&gt;libwayland-client.so&lt;/code&gt; inside the AppImage. This creates conflicts between the AppImage’s dependencies and the system’s libraries. The solution is to remove the duplicated dependencies and let the AppImage use the system’s libraries instead of those inside the AppImage.&lt;/p&gt;
&lt;h2&gt;How to Fix This ?&lt;/h2&gt;
&lt;p&gt;Remove all dependencies related to wayland from the AppImage. Since XWayland can handle X11 applications, there is no need to bundle these libraries internally. The creator of the AppImage also noted this in &lt;a href="https://x.com/realPratyay/status/2109024857203617944" rel="noopener noreferrer"&gt;his comment&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%2Fi.ibb.co%2FRkkyrt18%2FScreenshot-20261011-232802-png.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%2Fi.ibb.co%2FRkkyrt18%2FScreenshot-20261011-232802-png.png" width="592" height="133"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have written a shell script to handle this for you. Please create a file at &lt;code&gt;src-tauri/scripts/patch-appimage-wayland.sh&lt;/code&gt; and paste the script into it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class="comment"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="constant function"&gt;set&lt;/span&gt; &lt;span class="constant"&gt;-euo&lt;/span&gt; &lt;span class="constant"&gt;pipefail&lt;/span&gt;

&lt;span class="property"&gt;SCRIPT_DIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;cd&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant"&gt;${&lt;/span&gt;&lt;span class="string embedded constant property"&gt;BASH_SOURCE&lt;/span&gt;&lt;span class="string embedded constant"&gt;[0]}&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;)" &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="constant function"&gt;pwd&lt;/span&gt;)"
&lt;span class="property"&gt;REPO_ROOT&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;cd&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class="string embedded constant"&gt;/../.."&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant function"&gt;pwd&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
&lt;span class="property"&gt;SRC_TAURI_DIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="string"&gt;/src-tauri"&lt;/span&gt;
&lt;span class="property"&gt;TAURI_CACHE_DIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;XDG_CACHE_HOME&lt;/span&gt;&lt;span class="string embedded"&gt;:-&lt;/span&gt;&lt;span class="string embedded operator"&gt;$&lt;/span&gt;&lt;span class="string embedded property"&gt;HOME&lt;/span&gt;&lt;span class="string embedded"&gt;/.cache}&lt;/span&gt;&lt;span class="string"&gt;/tauri"&lt;/span&gt;

&lt;span class="comment"&gt;# Clean up temp files on exit&lt;/span&gt;
&lt;span class="property"&gt;TEMP_BIN&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;mktemp&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-d&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
&lt;span class="property"&gt;TEMP_EXTRACT&lt;/span&gt;=&lt;span class="string"&gt;""&lt;/span&gt;
&lt;span class="function"&gt;cleanup&lt;/span&gt;() {
  &lt;span class="constant function"&gt;rm&lt;/span&gt; &lt;span class="constant"&gt;-rf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; [ -d &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;rm&lt;/span&gt; &lt;span class="constant"&gt;-rf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
}
&lt;span class="constant function"&gt;trap&lt;/span&gt; &lt;span class="constant"&gt;cleanup&lt;/span&gt; &lt;span class="constant"&gt;EXIT&lt;/span&gt;

&lt;span class="comment"&gt;# 1. Resolve linuxdeploy and appimage tools&lt;/span&gt;
&lt;span class="property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;=&lt;span class="string"&gt;""&lt;/span&gt;
&lt;span class="keyword"&gt;if&lt;/span&gt; [ -d &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TAURI_CACHE_DIR&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
  &lt;span class="property"&gt;cached_linuxdeploy&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;find&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;TAURI_CACHE_DIR&lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-maxdepth&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;1&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-name&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"linuxdeploy-*.AppImage"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-print&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-quit&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded number"&gt;2&lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="embedded"&gt;/dev/null || &lt;/span&gt;&lt;span class="embedded constant function"&gt;true&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_linuxdeploy&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_linuxdeploy&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;ln&lt;/span&gt; &lt;span class="constant"&gt;-sf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;cached_linuxdeploy&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant"&gt;/linuxdeploy"&lt;/span&gt;
    &lt;span class="property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string"&gt;/linuxdeploy"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;

  &lt;span class="property"&gt;cached_plugin&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;find&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;TAURI_CACHE_DIR&lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-maxdepth&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;1&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-name&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"linuxdeploy-plugin-appimage.AppImage"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-print&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-quit&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded number"&gt;2&lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="embedded"&gt;/dev/null || &lt;/span&gt;&lt;span class="embedded constant function"&gt;true&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_plugin&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_plugin&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;ln&lt;/span&gt; &lt;span class="constant"&gt;-sf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;cached_plugin&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant"&gt;/linuxdeploy-plugin-appimage"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
&lt;span class="keyword"&gt;fi&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; [ -z &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="constant function"&gt;command&lt;/span&gt; &lt;span class="constant"&gt;-v&lt;/span&gt; &lt;span class="constant"&gt;linuxdeploy&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class="number"&gt;2&lt;/span&gt;&amp;gt;&amp;amp;1; &lt;span class="keyword"&gt;then&lt;/span&gt;
  &lt;span class="property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;command&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;-v&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;linuxdeploy&lt;/span&gt;&lt;span class="string embedded"&gt;)&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
&lt;span class="keyword"&gt;fi&lt;/span&gt;

&lt;span class="keyword"&gt;export&lt;/span&gt; &lt;span class="property"&gt;PATH&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string"&gt;:&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;PATH&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
&lt;span class="keyword"&gt;export&lt;/span&gt; &lt;span class="property"&gt;APPIMAGE_EXTRACT_AND_RUN&lt;/span&gt;=1

&lt;span class="comment"&gt;# 2. Patch an AppDir in-place&lt;/span&gt;
&lt;span class="function"&gt;patch_appdir&lt;/span&gt;() {
  local &lt;span class="property"&gt;appdir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;1&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
  &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Patching AppDir: &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;

  &lt;span class="comment"&gt;# 1. Write self-contained Wayland compatibility hook&lt;/span&gt;
  &lt;span class="constant function"&gt;mkdir&lt;/span&gt; &lt;span class="constant"&gt;-p&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/apprun-hooks"&lt;/span&gt;
  &lt;span class="constant function"&gt;cat&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="string"&gt;'EOF'&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/apprun-hooks/wayland-compat.sh"&lt;/span&gt;
&lt;span class="string"&gt;export DESKTOPINTEGRATION=1

if [ -z "${LD_PRELOAD:-}" ]; then
  for lib in \
    /usr/lib/libwayland-client.so \
    /usr/lib64/libwayland-client.so \
    /usr/lib/x86_64-linux-gnu/libwayland-client.so \
    /usr/lib/aarch64-linux-gnu/libwayland-client.so \
    /usr/lib/arm-linux-gnueabihf/libwayland-client.so; do
    if [ -f "$lib" ]; then
      export LD_PRELOAD="$lib"
      break
    fi
  done
fi
&lt;/span&gt;EOF
  &lt;span class="constant function"&gt;chmod&lt;/span&gt; &lt;span class="constant"&gt;+x&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/apprun-hooks/wayland-compat.sh"&lt;/span&gt;

  &lt;span class="comment"&gt;# 2. Patch AppRun so it sources the new hook before executing AppRun.wrapped&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun.wrapped"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; ! &lt;span class="constant function"&gt;grep&lt;/span&gt; &lt;span class="constant"&gt;-q&lt;/span&gt; &lt;span class="string constant"&gt;"wayland-compat.sh"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt;; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="constant function"&gt;cat&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="string"&gt;'EOF'&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun"&lt;/span&gt;
&lt;span class="string"&gt;#!/usr/bin/env bash
HERE="$(dirname "$(readlink -f "${0}")")"
if [ -f "$HERE/apprun-hooks/wayland-compat.sh" ]; then
  . "$HERE/apprun-hooks/wayland-compat.sh"
fi
exec "$HERE/AppRun.wrapped" "$@"
&lt;/span&gt;EOF
      &lt;span class="constant function"&gt;chmod&lt;/span&gt; &lt;span class="constant"&gt;+x&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt;
    &lt;span class="keyword"&gt;fi&lt;/span&gt;
  &lt;span class="keyword"&gt;elif&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;mv&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun.wrapped"&lt;/span&gt;
    &lt;span class="constant function"&gt;cat&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="string"&gt;'EOF'&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun"&lt;/span&gt;
&lt;span class="string"&gt;#!/usr/bin/env bash
HERE="$(dirname "$(readlink -f "${0}")")"
if [ -f "$HERE/apprun-hooks/wayland-compat.sh" ]; then
  . "$HERE/apprun-hooks/wayland-compat.sh"
fi
exec "$HERE/AppRun.wrapped" "$@"
&lt;/span&gt;EOF
    &lt;span class="constant function"&gt;chmod&lt;/span&gt; &lt;span class="constant"&gt;+x&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
}

&lt;span class="comment"&gt;# 3. Repack AppDir into AppImage&lt;/span&gt;
&lt;span class="function"&gt;repack_appdir&lt;/span&gt;() {
  local &lt;span class="property"&gt;appdir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;1&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
  local &lt;span class="property"&gt;expected_appimage&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;2&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
  local &lt;span class="property"&gt;bundle_dir&lt;/span&gt;
  &lt;span class="property"&gt;bundle_dir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
  local &lt;span class="property"&gt;appimage_base&lt;/span&gt;
  &lt;span class="property"&gt;appimage_base&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;basename&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"

  &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Repacking AppImage into &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;..."&lt;/span&gt;
  (
    &lt;span class="constant function"&gt;cd&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;bundle_dir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="keyword"&gt;export&lt;/span&gt; &lt;span class="property"&gt;LDAI_OUTPUT&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appimage_base&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;

    &lt;span class="comment"&gt;# Remove existing AppImage before repacking&lt;/span&gt;
    [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="constant function"&gt;rm&lt;/span&gt; &lt;span class="constant"&gt;-f&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;

    &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="string constant function"&gt;"&lt;/span&gt;&lt;span class="string constant operator function"&gt;$&lt;/span&gt;&lt;span class="string constant property function"&gt;LINUXDEPLOY_BIN&lt;/span&gt;&lt;span class="string constant function"&gt;"&lt;/span&gt; &lt;span class="constant"&gt;--appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="constant"&gt;--output&lt;/span&gt; &lt;span class="constant"&gt;appimage&lt;/span&gt;
    &lt;span class="keyword"&gt;elif&lt;/span&gt; &lt;span class="constant function"&gt;command&lt;/span&gt; &lt;span class="constant"&gt;-v&lt;/span&gt; &lt;span class="constant"&gt;appimagetool&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class="number"&gt;2&lt;/span&gt;&amp;gt;&amp;amp;1; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="constant function"&gt;appimagetool&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="keyword"&gt;elif&lt;/span&gt; [ -x &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string"&gt;/linuxdeploy-plugin-appimage"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="string constant function"&gt;"&lt;/span&gt;&lt;span class="string constant operator function"&gt;$&lt;/span&gt;&lt;span class="string constant property function"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant function"&gt;/linuxdeploy-plugin-appimage"&lt;/span&gt; &lt;span class="constant"&gt;--appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Error: Could not find linuxdeploy or appimagetool to repack &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &amp;gt;&amp;amp;2
      &lt;span class="constant function"&gt;exit&lt;/span&gt; &lt;span class="constant"&gt;1&lt;/span&gt;
    &lt;span class="keyword"&gt;fi&lt;/span&gt;
  )

  &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Successfully repacked AppImage at &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
}

&lt;span class="comment"&gt;# 4. Process targets&lt;/span&gt;
&lt;span class="keyword"&gt;if&lt;/span&gt; [ &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;1&lt;/span&gt;&lt;span class="string embedded"&gt;:-}&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; != &lt;span class="string"&gt;""&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
  &lt;span class="property"&gt;TARGET_PATH&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;readlink&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;-f&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;1&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -d &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;patch_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="property"&gt;bundle_dir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;appdir_name&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;basename&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;expected_appimage&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;bundle_dir&lt;/span&gt;&lt;span class="string embedded"&gt;}&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;appdir_name&lt;/span&gt;&lt;span class="string embedded"&gt;%.AppDir}&lt;/span&gt;&lt;span class="string"&gt;.AppImage"&lt;/span&gt;
    &lt;span class="constant function"&gt;repack_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;elif&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="property"&gt;TEMP_EXTRACT&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;mktemp&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-d&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
    &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Extracting AppImage: &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    (&lt;span class="constant function"&gt;cd&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="string constant function"&gt;"&lt;/span&gt;&lt;span class="string constant operator function"&gt;$&lt;/span&gt;&lt;span class="string constant property function"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant function"&gt;"&lt;/span&gt; &lt;span class="constant"&gt;--appimage-extract&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt;/dev/null)
    &lt;span class="property"&gt;EXTRACTED_APPDIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string"&gt;/squashfs-root"&lt;/span&gt;
    &lt;span class="constant function"&gt;patch_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;EXTRACTED_APPDIR&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="constant function"&gt;repack_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;EXTRACTED_APPDIR&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Error: Target path not found: &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &amp;gt;&amp;amp;2
    &lt;span class="constant function"&gt;exit&lt;/span&gt; &lt;span class="constant"&gt;1&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;
  &lt;span class="property"&gt;APPDIRS&lt;/span&gt;=()
  &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="constant property"&gt;IFS&lt;/span&gt;&lt;span class="constant"&gt;=&lt;/span&gt; &lt;span class="constant function"&gt;read&lt;/span&gt; &lt;span class="constant"&gt;-r&lt;/span&gt; &lt;span class="constant"&gt;-d&lt;/span&gt; &lt;span class="string constant"&gt;''&lt;/span&gt; &lt;span class="constant"&gt;dir&lt;/span&gt;; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="property"&gt;APPDIRS&lt;/span&gt;+=(&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;dir&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;)
  &lt;span class="keyword"&gt;done&lt;/span&gt; &lt;span class="operator"&gt;&amp;lt;&lt;/span&gt; &lt;span class="embedded"&gt;&amp;lt;(&lt;/span&gt;&lt;span class="embedded constant function"&gt;find&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;SRC_TAURI_DIR&lt;/span&gt;&lt;span class="embedded string constant"&gt;/target"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="embedded string constant"&gt;/target"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-type&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;d&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-name&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"*.AppDir"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-print0&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded number"&gt;2&lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="embedded"&gt;/dev/null || &lt;/span&gt;&lt;span class="embedded constant function"&gt;true&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;

  &lt;span class="keyword"&gt;if&lt;/span&gt; [ &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${#&lt;/span&gt;&lt;span class="string embedded property"&gt;APPDIRS&lt;/span&gt;&lt;span class="string embedded"&gt;[@]}&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; -eq 0 ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"No *.AppDir found to patch. (Did you run tauri build?)"&lt;/span&gt;
    &lt;span class="constant function"&gt;exit&lt;/span&gt; &lt;span class="constant"&gt;0&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;

  &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="property"&gt;appdir&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;APPDIRS&lt;/span&gt;&lt;span class="string embedded"&gt;[@]}&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="constant function"&gt;patch_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="property"&gt;bundle_dir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;appdir&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;appdir_name&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;basename&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;appdir&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;expected_appimage&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;bundle_dir&lt;/span&gt;&lt;span class="string embedded"&gt;}&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;appdir_name&lt;/span&gt;&lt;span class="string embedded"&gt;%.AppDir}&lt;/span&gt;&lt;span class="string"&gt;.AppImage"&lt;/span&gt;
    &lt;span class="constant function"&gt;repack_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;done&lt;/span&gt;
&lt;span class="keyword"&gt;fi&lt;/span&gt;

&lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Wayland AppImage patching complete."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;And Change a Little Thing in the Existing Workflow&lt;/h2&gt;
&lt;h2&gt;Replace All &lt;code&gt;tauri build&lt;/code&gt; Commands With &lt;code&gt;tauri build &amp;amp;&amp;amp; source src-tauri/scripts/patch-appimage-wayland.sh&lt;/code&gt;
&lt;/h2&gt;
&lt;p&gt;if you are using vite then replace the &lt;code&gt;tauri build&lt;/code&gt; command with &lt;code&gt;tauri build &amp;amp;&amp;amp; source src-tauri/scripts/patch-appimage-wayland.sh&lt;/code&gt; in the scripts section of &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
 &lt;span class="string_special_key string"&gt;"name"&lt;/span&gt;: &lt;span class="string"&gt;"drawx"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"version"&lt;/span&gt;: &lt;span class="string"&gt;"0.8.5"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"type"&lt;/span&gt;: &lt;span class="string"&gt;"module"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"imports"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"#components/*"&lt;/span&gt;: &lt;span class="string"&gt;"./src/components/*.tsx"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"#lib/*"&lt;/span&gt;: &lt;span class="string"&gt;"./src/lib/*.ts"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"#hooks/*"&lt;/span&gt;: &lt;span class="string"&gt;"./src/hooks/*.ts"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"scripts"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"dev"&lt;/span&gt;: &lt;span class="string"&gt;"vite"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"build"&lt;/span&gt;: &lt;span class="string"&gt;"tsc &amp;amp;&amp;amp; vite build"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"typecheck"&lt;/span&gt;: &lt;span class="string"&gt;"tsc --noEmit"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"preview"&lt;/span&gt;: &lt;span class="string"&gt;"vite preview"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tauri"&lt;/span&gt;: &lt;span class="string"&gt;"tauri"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tauri:build"&lt;/span&gt;: &lt;span class="string"&gt;"tauri build &amp;amp;&amp;amp; source src-tauri/scripts/patch-appimage-wayland.sh"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"dependencies"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"@astryxdesign/cli"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/core"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-matcha"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-neutral"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-stone"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-y2k"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@excalidraw/excalidraw"&lt;/span&gt;: &lt;span class="string"&gt;"^0.18.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@fontsource-variable/inter"&lt;/span&gt;: &lt;span class="string"&gt;"^5.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@fontsource-variable/jetbrains-mono"&lt;/span&gt;: &lt;span class="string"&gt;"^5.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@hugeicons/core-free-icons"&lt;/span&gt;: &lt;span class="string"&gt;"^4.3.5"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@hugeicons/react"&lt;/span&gt;: &lt;span class="string"&gt;"^1.1.10"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@iconify/react"&lt;/span&gt;: &lt;span class="string"&gt;"^6.0.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@phosphor-icons/react"&lt;/span&gt;: &lt;span class="string"&gt;"^2.1.10"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@stylexjs/stylex"&lt;/span&gt;: &lt;span class="string"&gt;"^0.19.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/api"&lt;/span&gt;: &lt;span class="string"&gt;"^2.12.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-clipboard-manager"&lt;/span&gt;: &lt;span class="string"&gt;"^2.4.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-dialog"&lt;/span&gt;: &lt;span class="string"&gt;"^2.8.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-fs"&lt;/span&gt;: &lt;span class="string"&gt;"^2.6.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-log"&lt;/span&gt;: &lt;span class="string"&gt;"^2.10.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-opener"&lt;/span&gt;: &lt;span class="string"&gt;"^2.7.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-process"&lt;/span&gt;: &lt;span class="string"&gt;"^2.4.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-updater"&lt;/span&gt;: &lt;span class="string"&gt;"^2.13.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"class-variance-authority"&lt;/span&gt;: &lt;span class="string"&gt;"^0.7.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"clsx"&lt;/span&gt;: &lt;span class="string"&gt;"^2.1.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"lucide-react"&lt;/span&gt;: &lt;span class="string"&gt;"^1.53.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"radix-ui"&lt;/span&gt;: &lt;span class="string"&gt;"^1.7.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"react"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"react-dom"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"react-router-dom"&lt;/span&gt;: &lt;span class="string"&gt;"^7.18.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tailwind-merge"&lt;/span&gt;: &lt;span class="string"&gt;"^3.7.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tw-animate-css"&lt;/span&gt;: &lt;span class="string"&gt;"^1.4.0"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"devDependencies"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"@biomejs/biome"&lt;/span&gt;: &lt;span class="string"&gt;"^2.5.15"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@oxlint/plugins"&lt;/span&gt;: &lt;span class="string"&gt;"1.81.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tailwindcss/vite"&lt;/span&gt;: &lt;span class="string"&gt;"^4.3.3"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/cli"&lt;/span&gt;: &lt;span class="string"&gt;"^2.12.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@types/node"&lt;/span&gt;: &lt;span class="string"&gt;"^26.6.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@types/react"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@types/react-dom"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@vitejs/plugin-react"&lt;/span&gt;: &lt;span class="string"&gt;"^6.1.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"astryx"&lt;/span&gt;: &lt;span class="string"&gt;"^0.0.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"oxfmt"&lt;/span&gt;: &lt;span class="string"&gt;"^0.72.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"oxlint"&lt;/span&gt;: &lt;span class="string"&gt;"^1.87.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"typescript"&lt;/span&gt;: &lt;span class="string"&gt;"~7.0.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"vite"&lt;/span&gt;: &lt;span class="string"&gt;"^8.3.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"zustand"&lt;/span&gt;: &lt;span class="string"&gt;"^5.0.15"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"devEngines"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"packageManager"&lt;/span&gt;: {
   &lt;span class="string_special_key string"&gt;"name"&lt;/span&gt;: &lt;span class="string"&gt;"pnpm"&lt;/span&gt;,
   &lt;span class="string_special_key string"&gt;"version"&lt;/span&gt;: &lt;span class="string"&gt;"^12.10.1"&lt;/span&gt;,
   &lt;span class="string_special_key string"&gt;"onFail"&lt;/span&gt;: &lt;span class="string"&gt;"warn"&lt;/span&gt;
  }
 },
 &lt;span class="string_special_key string"&gt;"packageManager"&lt;/span&gt;: &lt;span class="string"&gt;"pnpm@12.10.1+sha512.ba40a37eb1a370d60fea8c4cf1d364c13bcccef518e98ad2bcee954f539d38da37458e58261a3fa55e06523450ea0ffff9f497b135be41f2c15c1642bacace6c"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"trustedDependencies"&lt;/span&gt;: [
  &lt;span class="string"&gt;"@astryxdesign/cli"&lt;/span&gt;,
  &lt;span class="string"&gt;"@astryxdesign/core"&lt;/span&gt;
 ],
 &lt;span class="string_special_key string"&gt;"allowScripts"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"@astryxdesign/cli"&lt;/span&gt;: &lt;span class="constant_builtin"&gt;true&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/core"&lt;/span&gt;: &lt;span class="constant_builtin"&gt;true&lt;/span&gt;
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I referred to this &lt;a href="https://girishjoshi.io/post/tauri-2.0-appimage-egl-issue-on-wayland/" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; for the initial solution to the issue.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>software</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Making Tauri Apps Packaged as AppImages Usable Again</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Sat, 10 Oct 2026 15:31:00 +0000</pubDate>
      <link>https://dev.to/pratyay360/making-tauri-apps-packaged-as-appimages-usable-again-1d4d</link>
      <guid>https://dev.to/pratyay360/making-tauri-apps-packaged-as-appimages-usable-again-1d4d</guid>
      <description>&lt;h2&gt;Tauri Apps Built as Appimages are not working on modern linux distributions, like fedora, arch&lt;/h2&gt;
&lt;p&gt;Appimages are one of the nicest ways to distribute an app but not being able to run a format meant to be used on multiple os, is a bad thing. Appimage as a format is crucial for users who want to test a app and use it without the need of installing. Appimages are cool as they comes with all the required dependencies and can be operated on systems such as Windows with WSL2 and FreeBSD with the Linuxulator. Appimages are self contained in nature and requires no root access.&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%2Fi.ibb.co%2FSzdDWNG%2FScreenshot-20261010-211137-png.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%2Fi.ibb.co%2FSzdDWNG%2FScreenshot-20261010-211137-png.png" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class="constant function"&gt;Gtk-Message:&lt;/span&gt; &lt;span class="constant"&gt;21:07:08.168:&lt;/span&gt; &lt;span class="constant"&gt;Failed&lt;/span&gt; &lt;span class="constant"&gt;to&lt;/span&gt; &lt;span class="constant"&gt;load&lt;/span&gt; &lt;span class="constant"&gt;module&lt;/span&gt; &lt;span class="string constant"&gt;"appmenu-gtk-module"&lt;/span&gt;&lt;span class="constant"&gt;:&lt;/span&gt; &lt;span class="string constant"&gt;'gtk_module_display_init'&lt;/span&gt;&lt;span class="constant"&gt;:&lt;/span&gt; &lt;span class="constant"&gt;/usr/lib64/gtk-3.0/modules/libcolorreload-gtk-module.so:&lt;/span&gt; &lt;span class="constant"&gt;undefined&lt;/span&gt; &lt;span class="constant"&gt;symbol:&lt;/span&gt; &lt;span class="constant"&gt;gtk_module_display_init&lt;/span&gt;&lt;br&gt;
&lt;span class="constant function"&gt;Could&lt;/span&gt; &lt;span class="constant"&gt;not&lt;/span&gt; &lt;span class="constant"&gt;create&lt;/span&gt; &lt;span class="constant"&gt;default&lt;/span&gt; &lt;span class="constant"&gt;EGL&lt;/span&gt; &lt;span class="constant"&gt;display:&lt;/span&gt; &lt;span class="constant"&gt;EGL_BAD_PARAMETER.&lt;/span&gt; &lt;span class="constant"&gt;Aborting...&lt;/span&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;&lt;span class="constant function"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;apiark:185476&lt;/span&gt;): &lt;span&gt;WARNING&lt;/span&gt; &lt;span&gt;&lt;/span&gt;&lt;/strong&gt;: &lt;span class="constant"&gt;21:07:33.334:&lt;/span&gt; &lt;span class="constant"&gt;atk-bridge:&lt;/span&gt; &lt;span class="constant"&gt;get_device_events_reply:&lt;/span&gt; &lt;span class="constant"&gt;unknown&lt;/span&gt; &lt;span class="constant"&gt;signature&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;p&gt;This is a sample app image for a Tauri based rest-api client &lt;a href="https://apiark.dev/" rel="noopener noreferrer"&gt;apiark&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, I was building &lt;a href="https://pratyay360.github.io/drawx/" rel="noopener noreferrer"&gt;Drawx&lt;/a&gt;, the offline version of &lt;a href="https://github.com/Pratyay360/drawy" rel="noopener noreferrer"&gt;drawy&lt;/a&gt;, which provides data sovereignty because nothing ever leaves your machine. However, the Drawx app was not working on my machine because of some odd issues. I wanted to run the AppImage in a portable manner, but using environment variables did not help. Setting &lt;code&gt;WEBKIT_DISABLE_DMABUF_RENDERER=1&lt;/code&gt; or &lt;code&gt;WEBKIT_DISABLE_COMPOSITING_MODE=1&lt;/code&gt; either caused a crash on launch or displayed a blank screen. The issue is that the CI environment adds libraries such as &lt;code&gt;libwayland-client.so&lt;/code&gt; inside the AppImage. This creates conflicts between the AppImage’s dependencies and the system’s libraries. The solution is to remove the duplicated dependencies and let the AppImage use the system’s libraries instead of those inside the AppImage.&lt;/p&gt;
&lt;h2&gt;How to Fix This ?&lt;/h2&gt;
&lt;p&gt;fixing missing libraries&lt;/p&gt;
&lt;p&gt;Have composed a shell script to fix the issue. Create a file &lt;code&gt;src-tauri/scripts/patch-appimage-wayland.sh&lt;/code&gt; and paste the script inside&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class="comment"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="constant function"&gt;set&lt;/span&gt; &lt;span class="constant"&gt;-euo&lt;/span&gt; &lt;span class="constant"&gt;pipefail&lt;/span&gt;

&lt;span class="property"&gt;SCRIPT_DIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;cd&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant"&gt;${&lt;/span&gt;&lt;span class="string embedded constant property"&gt;BASH_SOURCE&lt;/span&gt;&lt;span class="string embedded constant"&gt;[0]}&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;)" &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="constant function"&gt;pwd&lt;/span&gt;)"
&lt;span class="property"&gt;REPO_ROOT&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;cd&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class="string embedded constant"&gt;/../.."&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant function"&gt;pwd&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
&lt;span class="property"&gt;SRC_TAURI_DIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="string"&gt;/src-tauri"&lt;/span&gt;
&lt;span class="property"&gt;TAURI_CACHE_DIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;XDG_CACHE_HOME&lt;/span&gt;&lt;span class="string embedded"&gt;:-&lt;/span&gt;&lt;span class="string embedded operator"&gt;$&lt;/span&gt;&lt;span class="string embedded property"&gt;HOME&lt;/span&gt;&lt;span class="string embedded"&gt;/.cache}&lt;/span&gt;&lt;span class="string"&gt;/tauri"&lt;/span&gt;

&lt;span class="comment"&gt;# Clean up temp files on exit&lt;/span&gt;
&lt;span class="property"&gt;TEMP_BIN&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;mktemp&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-d&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
&lt;span class="property"&gt;TEMP_EXTRACT&lt;/span&gt;=&lt;span class="string"&gt;""&lt;/span&gt;
&lt;span class="function"&gt;cleanup&lt;/span&gt;() {
  &lt;span class="constant function"&gt;rm&lt;/span&gt; &lt;span class="constant"&gt;-rf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; [ -d &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;rm&lt;/span&gt; &lt;span class="constant"&gt;-rf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
}
&lt;span class="constant function"&gt;trap&lt;/span&gt; &lt;span class="constant"&gt;cleanup&lt;/span&gt; &lt;span class="constant"&gt;EXIT&lt;/span&gt;

&lt;span class="comment"&gt;# 1. Resolve linuxdeploy and appimage tools&lt;/span&gt;
&lt;span class="property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;=&lt;span class="string"&gt;""&lt;/span&gt;
&lt;span class="keyword"&gt;if&lt;/span&gt; [ -d &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TAURI_CACHE_DIR&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
  &lt;span class="property"&gt;cached_linuxdeploy&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;find&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;TAURI_CACHE_DIR&lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-maxdepth&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;1&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-name&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"linuxdeploy-*.AppImage"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-print&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-quit&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded number"&gt;2&lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="embedded"&gt;/dev/null || &lt;/span&gt;&lt;span class="embedded constant function"&gt;true&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_linuxdeploy&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_linuxdeploy&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;ln&lt;/span&gt; &lt;span class="constant"&gt;-sf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;cached_linuxdeploy&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant"&gt;/linuxdeploy"&lt;/span&gt;
    &lt;span class="property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string"&gt;/linuxdeploy"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;

  &lt;span class="property"&gt;cached_plugin&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;find&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;TAURI_CACHE_DIR&lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-maxdepth&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;1&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-name&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"linuxdeploy-plugin-appimage.AppImage"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-print&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-quit&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded number"&gt;2&lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="embedded"&gt;/dev/null || &lt;/span&gt;&lt;span class="embedded constant function"&gt;true&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_plugin&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;cached_plugin&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;ln&lt;/span&gt; &lt;span class="constant"&gt;-sf&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;cached_plugin&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant"&gt;/linuxdeploy-plugin-appimage"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
&lt;span class="keyword"&gt;fi&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; [ -z &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="constant function"&gt;command&lt;/span&gt; &lt;span class="constant"&gt;-v&lt;/span&gt; &lt;span class="constant"&gt;linuxdeploy&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class="number"&gt;2&lt;/span&gt;&amp;gt;&amp;amp;1; &lt;span class="keyword"&gt;then&lt;/span&gt;
  &lt;span class="property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;command&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;-v&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;linuxdeploy&lt;/span&gt;&lt;span class="string embedded"&gt;)&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
&lt;span class="keyword"&gt;fi&lt;/span&gt;

&lt;span class="keyword"&gt;export&lt;/span&gt; &lt;span class="property"&gt;PATH&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string"&gt;:&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;PATH&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
&lt;span class="keyword"&gt;export&lt;/span&gt; &lt;span class="property"&gt;APPIMAGE_EXTRACT_AND_RUN&lt;/span&gt;=1

&lt;span class="comment"&gt;# 2. Patch an AppDir in-place&lt;/span&gt;
&lt;span class="function"&gt;patch_appdir&lt;/span&gt;() {
  local &lt;span class="property"&gt;appdir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;1&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
  &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Patching AppDir: &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;

  &lt;span class="comment"&gt;# 1. Write self-contained Wayland compatibility hook&lt;/span&gt;
  &lt;span class="constant function"&gt;mkdir&lt;/span&gt; &lt;span class="constant"&gt;-p&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/apprun-hooks"&lt;/span&gt;
  &lt;span class="constant function"&gt;cat&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="string"&gt;'EOF'&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/apprun-hooks/wayland-compat.sh"&lt;/span&gt;
&lt;span class="string"&gt;export DESKTOPINTEGRATION=1

if [ -z "${LD_PRELOAD:-}" ]; then
  for lib in \
    /usr/lib/libwayland-client.so \
    /usr/lib64/libwayland-client.so \
    /usr/lib/x86_64-linux-gnu/libwayland-client.so \
    /usr/lib/aarch64-linux-gnu/libwayland-client.so \
    /usr/lib/arm-linux-gnueabihf/libwayland-client.so; do
    if [ -f "$lib" ]; then
      export LD_PRELOAD="$lib"
      break
    fi
  done
fi
&lt;/span&gt;EOF
  &lt;span class="constant function"&gt;chmod&lt;/span&gt; &lt;span class="constant"&gt;+x&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/apprun-hooks/wayland-compat.sh"&lt;/span&gt;

  &lt;span class="comment"&gt;# 2. Patch AppRun so it sources the new hook before executing AppRun.wrapped&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun.wrapped"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; ! &lt;span class="constant function"&gt;grep&lt;/span&gt; &lt;span class="constant"&gt;-q&lt;/span&gt; &lt;span class="string constant"&gt;"wayland-compat.sh"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt;; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="constant function"&gt;cat&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="string"&gt;'EOF'&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun"&lt;/span&gt;
&lt;span class="string"&gt;#!/usr/bin/env bash
HERE="$(dirname "$(readlink -f "${0}")")"
if [ -f "$HERE/apprun-hooks/wayland-compat.sh" ]; then
  . "$HERE/apprun-hooks/wayland-compat.sh"
fi
exec "$HERE/AppRun.wrapped" "$@"
&lt;/span&gt;EOF
      &lt;span class="constant function"&gt;chmod&lt;/span&gt; &lt;span class="constant"&gt;+x&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt;
    &lt;span class="keyword"&gt;fi&lt;/span&gt;
  &lt;span class="keyword"&gt;elif&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;mv&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun.wrapped"&lt;/span&gt;
    &lt;span class="constant function"&gt;cat&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="string"&gt;'EOF'&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appdir&lt;/span&gt;&lt;span class="string"&gt;/AppRun"&lt;/span&gt;
&lt;span class="string"&gt;#!/usr/bin/env bash
HERE="$(dirname "$(readlink -f "${0}")")"
if [ -f "$HERE/apprun-hooks/wayland-compat.sh" ]; then
  . "$HERE/apprun-hooks/wayland-compat.sh"
fi
exec "$HERE/AppRun.wrapped" "$@"
&lt;/span&gt;EOF
    &lt;span class="constant function"&gt;chmod&lt;/span&gt; &lt;span class="constant"&gt;+x&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;/AppRun"&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
}

&lt;span class="comment"&gt;# 3. Repack AppDir into AppImage&lt;/span&gt;
&lt;span class="function"&gt;repack_appdir&lt;/span&gt;() {
  local &lt;span class="property"&gt;appdir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;1&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
  local &lt;span class="property"&gt;expected_appimage&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;2&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;
  local &lt;span class="property"&gt;bundle_dir&lt;/span&gt;
  &lt;span class="property"&gt;bundle_dir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
  local &lt;span class="property"&gt;appimage_base&lt;/span&gt;
  &lt;span class="property"&gt;appimage_base&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;basename&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"

  &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Repacking AppImage into &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;..."&lt;/span&gt;
  (
    &lt;span class="constant function"&gt;cd&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;bundle_dir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="keyword"&gt;export&lt;/span&gt; &lt;span class="property"&gt;LDAI_OUTPUT&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;appimage_base&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;

    &lt;span class="comment"&gt;# Remove existing AppImage before repacking&lt;/span&gt;
    [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ] &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="constant function"&gt;rm&lt;/span&gt; &lt;span class="constant"&gt;-f&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;

    &lt;span class="keyword"&gt;if&lt;/span&gt; [ -n &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;LINUXDEPLOY_BIN&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="string constant function"&gt;"&lt;/span&gt;&lt;span class="string constant operator function"&gt;$&lt;/span&gt;&lt;span class="string constant property function"&gt;LINUXDEPLOY_BIN&lt;/span&gt;&lt;span class="string constant function"&gt;"&lt;/span&gt; &lt;span class="constant"&gt;--appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="constant"&gt;--output&lt;/span&gt; &lt;span class="constant"&gt;appimage&lt;/span&gt;
    &lt;span class="keyword"&gt;elif&lt;/span&gt; &lt;span class="constant function"&gt;command&lt;/span&gt; &lt;span class="constant"&gt;-v&lt;/span&gt; &lt;span class="constant"&gt;appimagetool&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class="number"&gt;2&lt;/span&gt;&amp;gt;&amp;amp;1; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="constant function"&gt;appimagetool&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="keyword"&gt;elif&lt;/span&gt; [ -x &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string"&gt;/linuxdeploy-plugin-appimage"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="string constant function"&gt;"&lt;/span&gt;&lt;span class="string constant operator function"&gt;$&lt;/span&gt;&lt;span class="string constant property function"&gt;TEMP_BIN&lt;/span&gt;&lt;span class="string constant function"&gt;/linuxdeploy-plugin-appimage"&lt;/span&gt; &lt;span class="constant"&gt;--appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Error: Could not find linuxdeploy or appimagetool to repack &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &amp;gt;&amp;amp;2
      &lt;span class="constant function"&gt;exit&lt;/span&gt; &lt;span class="constant"&gt;1&lt;/span&gt;
    &lt;span class="keyword"&gt;fi&lt;/span&gt;
  )

  &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Successfully repacked AppImage at &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
}

&lt;span class="comment"&gt;# 4. Process targets&lt;/span&gt;
&lt;span class="keyword"&gt;if&lt;/span&gt; [ &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;1&lt;/span&gt;&lt;span class="string embedded"&gt;:-}&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; != &lt;span class="string"&gt;""&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
  &lt;span class="property"&gt;TARGET_PATH&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;readlink&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;-f&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;1&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
  &lt;span class="keyword"&gt;if&lt;/span&gt; [ -d &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;patch_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="property"&gt;bundle_dir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;appdir_name&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;basename&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;expected_appimage&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;bundle_dir&lt;/span&gt;&lt;span class="string embedded"&gt;}&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;appdir_name&lt;/span&gt;&lt;span class="string embedded"&gt;%.AppDir}&lt;/span&gt;&lt;span class="string"&gt;.AppImage"&lt;/span&gt;
    &lt;span class="constant function"&gt;repack_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;elif&lt;/span&gt; [ -f &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="property"&gt;TEMP_EXTRACT&lt;/span&gt;=&lt;span class="embedded"&gt;$(&lt;/span&gt;&lt;span class="embedded constant function"&gt;mktemp&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-d&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;
    &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Extracting AppImage: &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    (&lt;span class="constant function"&gt;cd&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="string constant function"&gt;"&lt;/span&gt;&lt;span class="string constant operator function"&gt;$&lt;/span&gt;&lt;span class="string constant property function"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant function"&gt;"&lt;/span&gt; &lt;span class="constant"&gt;--appimage-extract&lt;/span&gt; &lt;span class="operator"&gt;&amp;gt;&lt;/span&gt;/dev/null)
    &lt;span class="property"&gt;EXTRACTED_APPDIR&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;TEMP_EXTRACT&lt;/span&gt;&lt;span class="string"&gt;/squashfs-root"&lt;/span&gt;
    &lt;span class="constant function"&gt;patch_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;EXTRACTED_APPDIR&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="constant function"&gt;repack_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;EXTRACTED_APPDIR&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Error: Target path not found: &lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &amp;gt;&amp;amp;2
    &lt;span class="constant function"&gt;exit&lt;/span&gt; &lt;span class="constant"&gt;1&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;
  &lt;span class="property"&gt;APPDIRS&lt;/span&gt;=()
  &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="constant property"&gt;IFS&lt;/span&gt;&lt;span class="constant"&gt;=&lt;/span&gt; &lt;span class="constant function"&gt;read&lt;/span&gt; &lt;span class="constant"&gt;-r&lt;/span&gt; &lt;span class="constant"&gt;-d&lt;/span&gt; &lt;span class="string constant"&gt;''&lt;/span&gt; &lt;span class="constant"&gt;dir&lt;/span&gt;; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="property"&gt;APPDIRS&lt;/span&gt;+=(&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string operator"&gt;$&lt;/span&gt;&lt;span class="string property"&gt;dir&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;)
  &lt;span class="keyword"&gt;done&lt;/span&gt; &lt;span class="operator"&gt;&amp;lt;&lt;/span&gt; &lt;span class="embedded"&gt;&amp;lt;(&lt;/span&gt;&lt;span class="embedded constant function"&gt;find&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;SRC_TAURI_DIR&lt;/span&gt;&lt;span class="embedded string constant"&gt;/target"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"&lt;/span&gt;&lt;span class="embedded string constant operator"&gt;$&lt;/span&gt;&lt;span class="embedded string constant property"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="embedded string constant"&gt;/target"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-type&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;d&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-name&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded string constant"&gt;"*.AppDir"&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded constant"&gt;-print0&lt;/span&gt;&lt;span class="embedded"&gt; &lt;/span&gt;&lt;span class="embedded number"&gt;2&lt;/span&gt;&lt;span class="embedded operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="embedded"&gt;/dev/null || &lt;/span&gt;&lt;span class="embedded constant function"&gt;true&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;

  &lt;span class="keyword"&gt;if&lt;/span&gt; [ &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${#&lt;/span&gt;&lt;span class="string embedded property"&gt;APPDIRS&lt;/span&gt;&lt;span class="string embedded"&gt;[@]}&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt; -eq 0 ]; &lt;span class="keyword"&gt;then&lt;/span&gt;
    &lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"No *.AppDir found to patch. (Did you run tauri build?)"&lt;/span&gt;
    &lt;span class="constant function"&gt;exit&lt;/span&gt; &lt;span class="constant"&gt;0&lt;/span&gt;
  &lt;span class="keyword"&gt;fi&lt;/span&gt;

  &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="property"&gt;appdir&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;APPDIRS&lt;/span&gt;&lt;span class="string embedded"&gt;[@]}&lt;/span&gt;&lt;span class="string"&gt;"&lt;/span&gt;; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="constant function"&gt;patch_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
    &lt;span class="property"&gt;bundle_dir&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;dirname&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;appdir&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;appdir_name&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;$(&lt;/span&gt;&lt;span class="string embedded constant function"&gt;basename&lt;/span&gt;&lt;span class="string embedded"&gt; &lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="string embedded constant operator"&gt;$&lt;/span&gt;&lt;span class="string embedded constant property"&gt;appdir&lt;/span&gt;&lt;span class="string embedded constant"&gt;"&lt;/span&gt;&lt;span class="embedded"&gt;)&lt;/span&gt;"
    &lt;span class="property"&gt;expected_appimage&lt;/span&gt;=&lt;span class="string"&gt;"&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;bundle_dir&lt;/span&gt;&lt;span class="string embedded"&gt;}&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="string embedded"&gt;${&lt;/span&gt;&lt;span class="string embedded property"&gt;appdir_name&lt;/span&gt;&lt;span class="string embedded"&gt;%.AppDir}&lt;/span&gt;&lt;span class="string"&gt;.AppImage"&lt;/span&gt;
    &lt;span class="constant function"&gt;repack_appdir&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;appdir&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt; &lt;span class="string constant"&gt;"&lt;/span&gt;&lt;span class="string constant operator"&gt;$&lt;/span&gt;&lt;span class="string constant property"&gt;expected_appimage&lt;/span&gt;&lt;span class="string constant"&gt;"&lt;/span&gt;
  &lt;span class="keyword"&gt;done&lt;/span&gt;
&lt;span class="keyword"&gt;fi&lt;/span&gt;

&lt;span class="constant function"&gt;echo&lt;/span&gt; &lt;span class="string constant"&gt;"Wayland AppImage patching complete."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;And Change a Little Thing in the Existing Workflow&lt;/h2&gt;
&lt;h2&gt;Replace All &lt;code&gt;tauri build&lt;/code&gt; Commands With &lt;code&gt;tauri build &amp;amp;&amp;amp; source src-tauri/scripts/patch-appimage-wayland.sh&lt;/code&gt;
&lt;/h2&gt;
&lt;p&gt;if you are using vite then replace the &lt;code&gt;tauri build&lt;/code&gt; command with &lt;code&gt;tauri build &amp;amp;&amp;amp; source src-tauri/scripts/patch-appimage-wayland.sh&lt;/code&gt; in the scripts section of &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
 &lt;span class="string_special_key string"&gt;"name"&lt;/span&gt;: &lt;span class="string"&gt;"drawx"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"version"&lt;/span&gt;: &lt;span class="string"&gt;"0.8.5"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"type"&lt;/span&gt;: &lt;span class="string"&gt;"module"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"imports"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"#components/*"&lt;/span&gt;: &lt;span class="string"&gt;"./src/components/*.tsx"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"#lib/*"&lt;/span&gt;: &lt;span class="string"&gt;"./src/lib/*.ts"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"#hooks/*"&lt;/span&gt;: &lt;span class="string"&gt;"./src/hooks/*.ts"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"scripts"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"dev"&lt;/span&gt;: &lt;span class="string"&gt;"vite"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"build"&lt;/span&gt;: &lt;span class="string"&gt;"tsc &amp;amp;&amp;amp; vite build"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"typecheck"&lt;/span&gt;: &lt;span class="string"&gt;"tsc --noEmit"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"preview"&lt;/span&gt;: &lt;span class="string"&gt;"vite preview"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tauri"&lt;/span&gt;: &lt;span class="string"&gt;"tauri"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tauri:build"&lt;/span&gt;: &lt;span class="string"&gt;"tauri build &amp;amp;&amp;amp; source src-tauri/scripts/patch-appimage-wayland.sh"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"dependencies"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"@astryxdesign/cli"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/core"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-matcha"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-neutral"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-stone"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/theme-y2k"&lt;/span&gt;: &lt;span class="string"&gt;"^0.5.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@excalidraw/excalidraw"&lt;/span&gt;: &lt;span class="string"&gt;"^0.18.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@fontsource-variable/inter"&lt;/span&gt;: &lt;span class="string"&gt;"^5.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@fontsource-variable/jetbrains-mono"&lt;/span&gt;: &lt;span class="string"&gt;"^5.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@hugeicons/core-free-icons"&lt;/span&gt;: &lt;span class="string"&gt;"^4.3.5"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@hugeicons/react"&lt;/span&gt;: &lt;span class="string"&gt;"^1.1.10"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@iconify/react"&lt;/span&gt;: &lt;span class="string"&gt;"^6.0.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@phosphor-icons/react"&lt;/span&gt;: &lt;span class="string"&gt;"^2.1.10"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@stylexjs/stylex"&lt;/span&gt;: &lt;span class="string"&gt;"^0.19.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/api"&lt;/span&gt;: &lt;span class="string"&gt;"^2.12.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-clipboard-manager"&lt;/span&gt;: &lt;span class="string"&gt;"^2.4.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-dialog"&lt;/span&gt;: &lt;span class="string"&gt;"^2.8.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-fs"&lt;/span&gt;: &lt;span class="string"&gt;"^2.6.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-log"&lt;/span&gt;: &lt;span class="string"&gt;"^2.10.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-opener"&lt;/span&gt;: &lt;span class="string"&gt;"^2.7.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-process"&lt;/span&gt;: &lt;span class="string"&gt;"^2.4.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/plugin-updater"&lt;/span&gt;: &lt;span class="string"&gt;"^2.13.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"class-variance-authority"&lt;/span&gt;: &lt;span class="string"&gt;"^0.7.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"clsx"&lt;/span&gt;: &lt;span class="string"&gt;"^2.1.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"lucide-react"&lt;/span&gt;: &lt;span class="string"&gt;"^1.53.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"radix-ui"&lt;/span&gt;: &lt;span class="string"&gt;"^1.7.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"react"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"react-dom"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"react-router-dom"&lt;/span&gt;: &lt;span class="string"&gt;"^7.18.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tailwind-merge"&lt;/span&gt;: &lt;span class="string"&gt;"^3.7.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"tw-animate-css"&lt;/span&gt;: &lt;span class="string"&gt;"^1.4.0"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"devDependencies"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"@biomejs/biome"&lt;/span&gt;: &lt;span class="string"&gt;"^2.5.15"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@oxlint/plugins"&lt;/span&gt;: &lt;span class="string"&gt;"1.81.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tailwindcss/vite"&lt;/span&gt;: &lt;span class="string"&gt;"^4.3.3"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@tauri-apps/cli"&lt;/span&gt;: &lt;span class="string"&gt;"^2.12.1"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@types/node"&lt;/span&gt;: &lt;span class="string"&gt;"^26.6.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@types/react"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@types/react-dom"&lt;/span&gt;: &lt;span class="string"&gt;"^19.3.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@vitejs/plugin-react"&lt;/span&gt;: &lt;span class="string"&gt;"^6.1.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"astryx"&lt;/span&gt;: &lt;span class="string"&gt;"^0.0.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"oxfmt"&lt;/span&gt;: &lt;span class="string"&gt;"^0.72.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"oxlint"&lt;/span&gt;: &lt;span class="string"&gt;"^1.87.0"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"typescript"&lt;/span&gt;: &lt;span class="string"&gt;"~7.0.2"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"vite"&lt;/span&gt;: &lt;span class="string"&gt;"^8.3.4"&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"zustand"&lt;/span&gt;: &lt;span class="string"&gt;"^5.0.15"&lt;/span&gt;
 },
 &lt;span class="string_special_key string"&gt;"devEngines"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"packageManager"&lt;/span&gt;: {
   &lt;span class="string_special_key string"&gt;"name"&lt;/span&gt;: &lt;span class="string"&gt;"pnpm"&lt;/span&gt;,
   &lt;span class="string_special_key string"&gt;"version"&lt;/span&gt;: &lt;span class="string"&gt;"^12.10.1"&lt;/span&gt;,
   &lt;span class="string_special_key string"&gt;"onFail"&lt;/span&gt;: &lt;span class="string"&gt;"warn"&lt;/span&gt;
  }
 },
 &lt;span class="string_special_key string"&gt;"packageManager"&lt;/span&gt;: &lt;span class="string"&gt;"pnpm@12.10.1+sha512.ba40a37eb1a370d60fea8c4cf1d364c13bcccef518e98ad2bcee954f539d38da37458e58261a3fa55e06523450ea0ffff9f497b135be41f2c15c1642bacace6c"&lt;/span&gt;,
 &lt;span class="string_special_key string"&gt;"trustedDependencies"&lt;/span&gt;: [
  &lt;span class="string"&gt;"@astryxdesign/cli"&lt;/span&gt;,
  &lt;span class="string"&gt;"@astryxdesign/core"&lt;/span&gt;
 ],
 &lt;span class="string_special_key string"&gt;"allowScripts"&lt;/span&gt;: {
  &lt;span class="string_special_key string"&gt;"@astryxdesign/cli"&lt;/span&gt;: &lt;span class="constant_builtin"&gt;true&lt;/span&gt;,
  &lt;span class="string_special_key string"&gt;"@astryxdesign/core"&lt;/span&gt;: &lt;span class="constant_builtin"&gt;true&lt;/span&gt;
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Referred &lt;a href="https://girishjoshi.io/post/tauri-2.0-appimage-egl-issue-on-wayland/" rel="noopener noreferrer"&gt;blog&lt;/a&gt; for initial solution of the issue.&lt;/p&gt;

</description>
      <category>tauri</category>
      <category>appimage</category>
    </item>
    <item>
      <title>Mastering Toolbx Containers: A Guide to Frictionless Linux Development</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Fri, 09 Oct 2026 18:35:00 +0000</pubDate>
      <link>https://dev.to/pratyay360/mastering-toolbx-containers-a-guide-to-frictionless-linux-development-4f1b</link>
      <guid>https://dev.to/pratyay360/mastering-toolbx-containers-a-guide-to-frictionless-linux-development-4f1b</guid>
      <description>&lt;p&gt;I recently ran into a problem while trying to work with Homebrew on my Atomic Fedora system. I was developing a custom formula and running &lt;code&gt;brew audit&lt;/code&gt; to debug it, but it failed because GCC &amp;amp; ruby was not available on the host, and i was doing &lt;code&gt;brew bundle install&lt;/code&gt; to make this work but had no luck.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff4jvydij1klecru6048.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff4jvydij1klecru6048.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The issue wasn’t with Homebrew itself, it was that my host environment was missing the specific dependencies needed for that workflow. I could have installed more packages globally on the host, but that would have made the system more cluttered and harder to manage.&lt;/p&gt;

&lt;p&gt;Similarly recently I was trying to develop an app in flutter for internal use but have faced issues running that .. and things got solved when I am using a sand boxed environment. Also for agents, toolbox can be a bliss . they can run any command and there is a very low chance of breaking stuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Toolbox?
&lt;/h2&gt;

&lt;p&gt;Toolbox containers are useful because they integrate well with your host system without forcing you to abandon isolation. They share your home directory and can access host resources such as the SSH agent, while still giving you a clean, disposable Linux environment for development.&lt;/p&gt;

&lt;p&gt;That makes them especially useful when you need a project-specific toolchain but don’t want to pollute your main system. They also make it easy to define a development workflow as code instead of manually installing packages every time.&lt;/p&gt;

&lt;p&gt;I realized that if I could create my own customized Toolbox image, I could keep the tools and dependencies I use regularly in one reusable environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining Your Own Development Environment
&lt;/h2&gt;

&lt;p&gt;If you work with package maintenance, formula development, or distro-specific tooling, learning to write a Dockerfile or Containerfile is incredibly valuable. It lets you build a consistent environment that is reproducible and version able.&lt;/p&gt;

&lt;p&gt;Here is an example of an AlmaLinux based Toolbox image for Homebrew development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; quay.io/toolbx-images/almalinux-toolbox:latest&lt;/span&gt;

&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; com.github.containers.toolbox="true" \&lt;/span&gt;
    name="alma-brew" \
    version="latest" \
    usage="This image is meant to be used with the toolbox or distrobox command" \
    summary="AlmaLinux Toolbox with GCC and Homebrew for developing brew recipes" \
    maintainer="Pratyay Mustafi &amp;lt;pratyaymustafi@outlook.com&amp;gt;"

# Copy setup scripts and package lists
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; scripts/ /scripts/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; packages/ /packages/&lt;/span&gt;

&lt;span class="c"&gt;# Run the setup scripts, then remove the build-time files&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /scripts/&lt;span class="k"&gt;*&lt;/span&gt;.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; /scripts/&lt;span class="k"&gt;*&lt;/span&gt;.sh
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /scripts /packages

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

&lt;/div&gt;



&lt;p&gt;This approach makes it easy to build a container that includes exactly what you need, without modifying the host system.&lt;/p&gt;

&lt;p&gt;I also wanted an Arch-based environment with Chaotic-AUR and &lt;code&gt;paru&lt;/code&gt;, so I created a second image for that workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; quay.io/toolbx/arch-toolbox:latest&lt;/span&gt;

&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; com.github.containers.toolbox="true" \&lt;/span&gt;
    name="arch-chaotic-toolbox" \
    version="latest" \
    usage="This image is meant to be used with the toolbox or distrobox command" \
    summary="Arch Linux Toolbox with Chaotic-AUR and paru" \
    maintainer="Pratyay Mustafi &amp;lt;pratyaymustafi@outlook.com&amp;gt;"

# Copy setup scripts and package lists
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; scripts/ /scripts/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; packages/ /packages/&lt;/span&gt;

&lt;span class="c"&gt;# Run the Chaotic-AUR setup script, then remove the build-time files&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /scripts/&lt;span class="k"&gt;*&lt;/span&gt;.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; /scripts/chaotic.sh
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /scripts /packages

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Simple Layout of the file structure.
&lt;/h2&gt;

&lt;p&gt;A project like this can stay clean and easy to maintain if it follows a simple layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── .github
│ └── workflows
│ ├── build.yml
│ └── clean-runs.yml
├── .gitignore
├── ContainerFiles
│ ├── brew
│ └── chaotic
├── LICENSE
├── README.md
├── packages
│ ├── brew.packages
│ └── chaotic.packages
└── scripts
    ├── brew.sh
    └── chaotic.sh

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

&lt;/div&gt;



&lt;p&gt;This structure keeps each concern separated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;scripts/&lt;/code&gt; contains the setup logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;packages/&lt;/code&gt; contains package lists&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ContainerFiles/&lt;/code&gt; stores the image definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;README.md&lt;/code&gt; explains how to build and use the environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That keeps the workflow organized and easier to extend later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Package List
&lt;/h2&gt;

&lt;p&gt;For the Arch-based image, the package list can be as simple as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;devel
git
paru

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

&lt;/div&gt;



&lt;p&gt;This is nice because package changes are declarative. If I need to add a tool, I can update the package list and rebuild the image whenever I need a new dependency or a different tool chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up &lt;a href="https://aur.chaotic.cx/" rel="noopener noreferrer"&gt;Chaotic AUR based toolbox&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;For Arch-based work, I also wanted a clean way to configure &lt;a href="https://aur.chaotic.cx/" rel="noopener noreferrer"&gt;Chaotic AUR&lt;/a&gt; and install the packages I use most often. The setup script below does just that:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"==&amp;gt; Configuring Chaotic AUR repository..."&lt;/span&gt;
pacman-key &lt;span class="nt"&gt;--init&lt;/span&gt;
pacman-key &lt;span class="nt"&gt;--recv-key&lt;/span&gt; 3056513887B78AEB &lt;span class="nt"&gt;--keyserver&lt;/span&gt; keyserver.ubuntu.com
pacman-key &lt;span class="nt"&gt;--lsign-key&lt;/span&gt; 3056513887B78AEB
pacman &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="nt"&gt;--noconfirm&lt;/span&gt; &lt;span class="s1"&gt;'https://geo-mirror.chaotic.cx/chaotic-aur/x86_64/chaotic-keyring.pkg.tar.zst'&lt;/span&gt;
pacman &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="nt"&gt;--noconfirm&lt;/span&gt; &lt;span class="s1"&gt;'https://geo-mirror.chaotic.cx/chaotic-aur/x86_64/chaotic-mirrorlist.pkg.tar.zst'&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s|^Server = https://cdn-mirror.chaotic.cx|# Server = https://cdn-mirror.chaotic.cx|'&lt;/span&gt; /etc/pacman.d/chaotic-mirrorlist
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\n[chaotic-aur]\nInclude = /etc/pacman.d/chaotic-mirrorlist\n'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/pacman.conf

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"==&amp;gt; Installing packages from chaotic.packages..."&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s1"&gt;'^#'&lt;/span&gt; /packages/chaotic.packages &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/chaotic.pkglist
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[!&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /tmp/chaotic.pkglist]&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"chaotic.packages is missing or empty"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi
&lt;/span&gt;xargs pacman &lt;span class="nt"&gt;-Syu&lt;/span&gt; &lt;span class="nt"&gt;--needed&lt;/span&gt; &lt;span class="nt"&gt;--noconfirm&lt;/span&gt; &amp;lt; /tmp/chaotic.pkglist
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/chaotic.pkglist
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/pacman/pkg/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"==&amp;gt; Configuring toolbx permissions..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"%wheel ALL=(ALL) NOPASSWD: ALL"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/sudoers.d/toolbox
&lt;span class="nb"&gt;chmod &lt;/span&gt;0440 /etc/sudoers.d/toolbox

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

&lt;/div&gt;



&lt;p&gt;This keeps the setup steps reproducible and easy to manage. If the Arch repository or package list changes, the update is straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Workflow Works So Well
&lt;/h2&gt;

&lt;p&gt;This pattern has several practical advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reproducible builds : the environment is defined in code&lt;/li&gt;
&lt;li&gt;Portability: the same image can be built elsewhere&lt;/li&gt;
&lt;li&gt;Isolation: dependencies stay inside the container instead of the host&lt;/li&gt;
&lt;li&gt;Speed: no repeated manual package setup&lt;/li&gt;
&lt;li&gt;Simplicity: the environment is easier to debug and maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a great fit for package maintenance, Linux tooling, custom formula work, and any development workflow that depends on a specific tool chain.&lt;/p&gt;

&lt;p&gt;Toolbox/Distrobox gives you a flexible middle ground: you get the isolation of a container without losing the convenience of working closely with your host environment.&lt;/p&gt;

&lt;p&gt;For me, building a specialized toolbox image solved an immediate problem and gave me a more maintainable sand boxed way to work going forward. I can now create exactly the environment I need, whether that’s for Home brew development, Arch based tooling, or any other project-specific workflow.&lt;/p&gt;

&lt;p&gt;If you work with Linux tooling, package building, or want reproducible dev setups, this is a workflow with toolbox container based development is worth adopting. &lt;a href="https://github.com/Pratyay360/chaotic-toolbx" rel="noopener noreferrer"&gt;Source code on GitHub.&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;toolbox container type&lt;/td&gt;
&lt;td&gt;image link&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;brew-toolbox&lt;/td&gt;
&lt;td&gt;&lt;a href="https://quay.io/repository/pratyay360/brew-toolbox" rel="noopener noreferrer"&gt;quay.io/pratyay360/brew-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;docker.io/pratyay360/brew-toolbox:latest&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Pratyay360/chaotic-toolbx" rel="noopener noreferrer"&gt;ghcr.io/pratyay360/brew-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chaotic-toolbox&lt;/td&gt;
&lt;td&gt;&lt;a href="https://quay.io/repository/pratyay360/chaotic-toolbox" rel="noopener noreferrer"&gt;quay.io/pratyay360/chaotic-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://docker.io/pratyay360/chaotic-toolbox:latest" rel="noopener noreferrer"&gt;docker.io/pratyay360/chaotic-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Pratyay360/chaotic-toolbx" rel="noopener noreferrer"&gt;ghcr.io/pratyay360/chaotic-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;android-toolbox&lt;/td&gt;
&lt;td&gt;&lt;a href="http://quay.io/pratyay360/android-toolbox" rel="noopener noreferrer"&gt;quay.io/pratyay360/android-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>containers</category>
      <category>linux</category>
      <category>tools</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create Your Own Specialized Toolbox Containers for Development</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Fri, 09 Oct 2026 18:35:00 +0000</pubDate>
      <link>https://dev.to/pratyay360/create-your-own-specialized-toolbox-containers-for-development-4gki</link>
      <guid>https://dev.to/pratyay360/create-your-own-specialized-toolbox-containers-for-development-4gki</guid>
      <description>&lt;p&gt;I recently ran into a problem while trying to work on Homebrew on my Atomic Fedora system. I was developing a custom formula and running &lt;code&gt;brew audit&lt;/code&gt;, but it failed because GCC &amp;amp; ruby was not available on the host, and i was doing &lt;code&gt;brew bundle install&lt;/code&gt; to work reliably but had no luck.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff4jvydij1klecru6048.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff4jvydij1klecru6048.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The issue wasn’t with Homebrew itself, it was that my host environment was missing the specific dependencies needed for that workflow. I could have installed more packages globally on the host, but that would have made the system more cluttered and harder to manage.&lt;/p&gt;

&lt;p&gt;Similarly recently I was trying to develop an app in flutter for internal use but have faced issues running that .. and things got solved when I am using a sand boxed environment. Also for agents, toolbox can be a bliss . they can run any command and there is a very low chance of breaking stuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Toolbox?
&lt;/h2&gt;

&lt;p&gt;Toolbox containers are useful because they integrate well with your host system without forcing you to abandon isolation. They share your home directory and can access host resources such as the SSH agent, while still giving you a clean, disposable Linux environment for development.&lt;/p&gt;

&lt;p&gt;That makes them especially useful when you need a project-specific toolchain but don’t want to pollute your main system. They also make it easy to define a development workflow as code instead of manually installing packages every time.&lt;/p&gt;

&lt;p&gt;I realized that if I could create my own customized Toolbox image, I could keep the tools and dependencies I use regularly in one reusable environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining Your Own Development Environment
&lt;/h2&gt;

&lt;p&gt;If you work with package maintenance, formula development, or distro-specific tooling, learning to write a Dockerfile or Containerfile is incredibly valuable. It lets you build a consistent environment that is reproducible and version able.&lt;/p&gt;

&lt;p&gt;Here is an example of an AlmaLinux based Toolbox image for Homebrew development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; quay.io/toolbx-images/almalinux-toolbox:latest&lt;/span&gt;

&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; com.github.containers.toolbox="true" \&lt;/span&gt;
    name="alma-brew" \
    version="latest" \
    usage="This image is meant to be used with the toolbox or distrobox command" \
    summary="AlmaLinux Toolbox with GCC and Homebrew for developing brew recipes" \
    maintainer="Pratyay Mustafi &amp;lt;pratyaymustafi@outlook.com&amp;gt;"

# Copy setup scripts and package lists
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; scripts/ /scripts/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; packages/ /packages/&lt;/span&gt;

&lt;span class="c"&gt;# Run the setup scripts, then remove the build-time files&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /scripts/&lt;span class="k"&gt;*&lt;/span&gt;.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; /scripts/&lt;span class="k"&gt;*&lt;/span&gt;.sh
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /scripts /packages

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

&lt;/div&gt;



&lt;p&gt;This approach makes it easy to build a container that includes exactly what you need, without modifying the host system.&lt;/p&gt;

&lt;p&gt;I also wanted an Arch-based environment with Chaotic-AUR and &lt;code&gt;paru&lt;/code&gt;, so I created a second image for that workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; quay.io/toolbx/arch-toolbox:latest&lt;/span&gt;

&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; com.github.containers.toolbox="true" \&lt;/span&gt;
    name="arch-chaotic-toolbox" \
    version="latest" \
    usage="This image is meant to be used with the toolbox or distrobox command" \
    summary="Arch Linux Toolbox with Chaotic-AUR and paru" \
    maintainer="Pratyay Mustafi &amp;lt;pratyaymustafi@outlook.com&amp;gt;"

# Copy setup scripts and package lists
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; scripts/ /scripts/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; packages/ /packages/&lt;/span&gt;

&lt;span class="c"&gt;# Run the Chaotic-AUR setup script, then remove the build-time files&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /scripts/&lt;span class="k"&gt;*&lt;/span&gt;.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; /scripts/chaotic.sh
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /scripts /packages

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Simple Layout of the file structure.
&lt;/h2&gt;

&lt;p&gt;A project like this can stay clean and easy to maintain if it follows a simple layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── .github
│ └── workflows
│ ├── build.yml
│ └── clean-runs.yml
├── .gitignore
├── ContainerFiles
│ ├── brew
│ └── chaotic
├── LICENSE
├── README.md
├── packages
│ ├── brew.packages
│ └── chaotic.packages
└── scripts
    ├── brew.sh
    └── chaotic.sh

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

&lt;/div&gt;



&lt;p&gt;This structure keeps each concern separated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;scripts/&lt;/code&gt; contains the setup logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;packages/&lt;/code&gt; contains package lists&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ContainerFiles/&lt;/code&gt; stores the image definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;README.md&lt;/code&gt; explains how to build and use the environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That keeps the workflow organized and easier to extend later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Package List
&lt;/h2&gt;

&lt;p&gt;For the Arch-based image, the package list can be as simple as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;devel
git
paru

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

&lt;/div&gt;



&lt;p&gt;This is nice because package changes are declarative. If I need to add a tool, I can update the package list and rebuild the image whenever I need a new dependency or a different tool chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up &lt;a href="https://aur.chaotic.cx/" rel="noopener noreferrer"&gt;Chaotic AUR based toolbox&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;For Arch-based work, I also wanted a clean way to configure &lt;a href="https://aur.chaotic.cx/" rel="noopener noreferrer"&gt;Chaotic AUR&lt;/a&gt; and install the packages I use most often. The setup script below does just that:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"==&amp;gt; Configuring Chaotic AUR repository..."&lt;/span&gt;
pacman-key &lt;span class="nt"&gt;--init&lt;/span&gt;
pacman-key &lt;span class="nt"&gt;--recv-key&lt;/span&gt; 3056513887B78AEB &lt;span class="nt"&gt;--keyserver&lt;/span&gt; keyserver.ubuntu.com
pacman-key &lt;span class="nt"&gt;--lsign-key&lt;/span&gt; 3056513887B78AEB
pacman &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="nt"&gt;--noconfirm&lt;/span&gt; &lt;span class="s1"&gt;'https://geo-mirror.chaotic.cx/chaotic-aur/x86_64/chaotic-keyring.pkg.tar.zst'&lt;/span&gt;
pacman &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="nt"&gt;--noconfirm&lt;/span&gt; &lt;span class="s1"&gt;'https://geo-mirror.chaotic.cx/chaotic-aur/x86_64/chaotic-mirrorlist.pkg.tar.zst'&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s|^Server = https://cdn-mirror.chaotic.cx|# Server = https://cdn-mirror.chaotic.cx|'&lt;/span&gt; /etc/pacman.d/chaotic-mirrorlist
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\n[chaotic-aur]\nInclude = /etc/pacman.d/chaotic-mirrorlist\n'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/pacman.conf

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"==&amp;gt; Installing packages from chaotic.packages..."&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s1"&gt;'^#'&lt;/span&gt; /packages/chaotic.packages &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/chaotic.pkglist
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[!&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /tmp/chaotic.pkglist]&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"chaotic.packages is missing or empty"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi
&lt;/span&gt;xargs pacman &lt;span class="nt"&gt;-Syu&lt;/span&gt; &lt;span class="nt"&gt;--needed&lt;/span&gt; &lt;span class="nt"&gt;--noconfirm&lt;/span&gt; &amp;lt; /tmp/chaotic.pkglist
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/chaotic.pkglist
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/pacman/pkg/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"==&amp;gt; Configuring toolbx permissions..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"%wheel ALL=(ALL) NOPASSWD: ALL"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/sudoers.d/toolbox
&lt;span class="nb"&gt;chmod &lt;/span&gt;0440 /etc/sudoers.d/toolbox

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

&lt;/div&gt;



&lt;p&gt;This keeps the setup steps reproducible and easy to manage. If the Arch repository or package list changes, the update is straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Workflow Works So Well
&lt;/h2&gt;

&lt;p&gt;This pattern has several practical advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reproducible builds : the environment is defined in code&lt;/li&gt;
&lt;li&gt;Portability: the same image can be built elsewhere&lt;/li&gt;
&lt;li&gt;Isolation: dependencies stay inside the container instead of the host&lt;/li&gt;
&lt;li&gt;Speed: no repeated manual package setup&lt;/li&gt;
&lt;li&gt;Simplicity: the environment is easier to debug and maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a great fit for package maintenance, Linux tooling, custom formula work, and any development workflow that depends on a specific tool chain.&lt;/p&gt;

&lt;p&gt;Toolbox/Distrobox gives you a flexible middle ground: you get the isolation of a container without losing the convenience of working closely with your host environment.&lt;/p&gt;

&lt;p&gt;For me, building a specialized toolbox image solved an immediate problem and gave me a more maintainable sand boxed way to work going forward. I can now create exactly the environment I need, whether that’s for Home brew development, Arch based tooling, or any other project-specific workflow.&lt;/p&gt;

&lt;p&gt;If you work with Linux tooling, package building, or want reproducible dev setups, this is a workflow with toolbox container based development is worth adopting. &lt;a href="https://github.com/Pratyay360/chaotic-toolbx" rel="noopener noreferrer"&gt;Source code on GitHub.&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;toolbox container type&lt;/td&gt;
&lt;td&gt;image link&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;brew-toolbox&lt;/td&gt;
&lt;td&gt;&lt;a href="https://quay.io/repository/pratyay360/brew-toolbox" rel="noopener noreferrer"&gt;quay.io/pratyay360/brew-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;docker.io/pratyay360/brew-toolbox:latest&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Pratyay360/chaotic-toolbx" rel="noopener noreferrer"&gt;ghcr.io/pratyay360/brew-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chaotic-toolbox&lt;/td&gt;
&lt;td&gt;&lt;a href="https://quay.io/repository/pratyay360/chaotic-toolbox" rel="noopener noreferrer"&gt;quay.io/pratyay360/chaotic-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://docker.io/pratyay360/chaotic-toolbox:latest" rel="noopener noreferrer"&gt;docker.io/pratyay360/chaotic-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Pratyay360/chaotic-toolbx" rel="noopener noreferrer"&gt;ghcr.io/pratyay360/chaotic-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;android-toolbox&lt;/td&gt;
&lt;td&gt;&lt;a href="http://quay.io/pratyay360/android-toolbox" rel="noopener noreferrer"&gt;quay.io/pratyay360/android-toolbox:latest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>toolbox</category>
      <category>devops</category>
      <category>cncf</category>
      <category>fedora</category>
    </item>
    <item>
      <title>Releasing tools on different channels with goreleaser</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Mon, 05 Oct 2026 11:23:00 +0000</pubDate>
      <link>https://dev.to/pratyay360/releasing-tools-on-different-channels-with-goreleaser-3pdk</link>
      <guid>https://dev.to/pratyay360/releasing-tools-on-different-channels-with-goreleaser-3pdk</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5d2mfs9qzgmugdvmq0db.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5d2mfs9qzgmugdvmq0db.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a CLI tool is easy, compared to distributing it
&lt;/h2&gt;

&lt;p&gt;Goreleaser makes publishing almost a cake walk, but it comes with a steep learning curve. Still, distribution is just as important as the product itself. Shipping your tool as standalone binaries isn’t enough. reaching users through established channels matters It increses your tool’s reputation and gives a free visibility. Like for macOS, there’s Homebrew, now a days many Linux distributions are promoting it, brew is backed by a large community. Similarly, Winget and Scoop are important distribution channels. Being available through these channels brings significantly more visibility and ease of use.&lt;/p&gt;

&lt;p&gt;By the way, GoReleaser is a publishing automation tool, and it’s not exclusive to Go, one can build and distribute apps written in many languages like Go, Zig, Rust, Typescript and more.&lt;/p&gt;

&lt;p&gt;Let’s first learn about different types of package managers before publishing there.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;homebrew.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Brew is generally maintained by the community and formulas are mostly written in Ruby &lt;code&gt;:)&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  So do you have to learn ruby to publish on homebrew?
&lt;/h3&gt;

&lt;p&gt;The answer is no, you don’t. goreleaser covers everything for you.&lt;/p&gt;

&lt;p&gt;You can create an empty GitHub repo named &lt;code&gt;homebrew-tap&lt;/code&gt; or any other name with a &lt;code&gt;homebrew-&lt;/code&gt; prefix. &lt;em&gt;the prefix is recommended&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo create user1/homebrew-tap &lt;span class="nt"&gt;--public&lt;/span&gt;

brew new-tap user1/tap

brew &lt;span class="nb"&gt;install &lt;/span&gt;gh git

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  What is tap?
&lt;/h4&gt;

&lt;p&gt;A tap is a repository with some recipes that brew needs to follow to install a tool. recipe is, in the sense, a formula to install a tool the repo user1/homebrew-tap will be reffered as user1/tap while using.&lt;/p&gt;

&lt;p&gt;On the other side you can make a repo like user1/homebrew-cli –&amp;gt; user1/cli (tap).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;scoop?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Scoop is a command line installer for Windows. Think of it as the Windows equivalent of Homebrew, but with its own flavor. To distribute your tool via Scoop, you’ll need to create a “bucket.” A bucket is basically Scoop’s version of a tap, a repo with the name &lt;code&gt;scoop-bucket&lt;/code&gt; is suggested.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo create user1/scoop-bucket &lt;span class="nt"&gt;--public&lt;/span&gt;
scoop bucket add bucket-name &amp;lt;https://github.com/user1/bucket-name&amp;gt; &lt;span class="c"&gt;## adding a bucket to scoop&lt;/span&gt;
scoop &lt;span class="nb"&gt;install &lt;/span&gt;bucket-name/your-tool &lt;span class="c"&gt;## installing your tool from the bucket&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Creating a Scoop bucket is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Winget&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, Winget is Microsoft’s official package manager for Windows built into the operating system.&lt;/p&gt;

&lt;p&gt;The process here is a bit different. Instead of creating a new repo you have to fork the &lt;a href="https://github.com/microsoft/winget-pkgs" rel="noopener noreferrer"&gt;main repo&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;&lt;del&gt;and then create a new branch for your tool&lt;/del&gt; you don’t have to do this thing manually goreleaser handles that for you.&lt;/p&gt;

&lt;h5&gt;
  
  
  Winget do’s and don’ts
&lt;/h5&gt;

&lt;p&gt;There are a few things to keep in mind:&lt;/p&gt;

&lt;p&gt;one tool = one branch,&lt;/p&gt;

&lt;p&gt;you can’t submit multiple tools in one branch as the pr is for tracking the changes of a single tool, goreleaser automates this process too.&lt;/p&gt;

&lt;p&gt;Generally, Linux users are techy so they are more likely to install &lt;code&gt;.deb&lt;/code&gt; and &lt;code&gt;.rpm&lt;/code&gt; packages, as well as tools like &lt;code&gt;eget&lt;/code&gt;, And the thing with go as a language is that it includes all the necessary C libraries in the binaries so it can be runned by just putting in $PATH on any machine.&lt;/p&gt;

&lt;h4&gt;
  
  
  the process generally is like you have to create/modify a file in other repo. But github-actions only gives your workflow access to that repo only
&lt;/h4&gt;

&lt;p&gt;create a PAT (personal access token) with scopes read, write, releasing, files, repos, actions, action-metadata etc, and add it to your repo secrets. then you can use that token in your workflow to access other repo.&lt;/p&gt;

&lt;p&gt;Remember you can’t create any variable with &lt;code&gt;GITHUB_&lt;/code&gt; prefix in the secrets, so you have to use a different name for your secret like &lt;code&gt;PAT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;to create a release, you have to create a numeric tag only as winget refuses to accept alphanumeric tags.&lt;/p&gt;

&lt;p&gt;like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.1.1
0.1.2-1

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

&lt;/div&gt;



&lt;p&gt;tags can be created using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag 1.1.1
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin 1.1.1

&lt;span class="c"&gt;## if you use jj then &lt;/span&gt;

jj new &lt;span class="c"&gt;# stage changes&lt;/span&gt;

jj desc &lt;span class="c"&gt;# describe changes&lt;/span&gt;

jj bookmark advance main &lt;span class="c"&gt;# advance bookmark main to the new staged state.&lt;/span&gt;

jj tag &lt;span class="nb"&gt;set &lt;/span&gt;1.1.1

jj git push &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="c"&gt;#or &lt;/span&gt;

jj git push &lt;span class="nt"&gt;--tag&lt;/span&gt; 1.1.1

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

&lt;/div&gt;



&lt;p&gt;If you have followed my &lt;a href="https://pratyay.qzz.io/blog/1788377082/" rel="noopener noreferrer"&gt;previous post on doing ci with mise&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;then read that post first as I am going to use the same approach here. Also I am assuming you are already using mise on your machine. goreleaser is available on mise, so you can install it using &lt;code&gt;mise use goreleaser@latest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To getting started, you have to generate a goreleaser config file using &lt;code&gt;goreleaser init&lt;/code&gt; command. It will create a &lt;code&gt;.goreleaser.yml&lt;/code&gt; file in your repo. You can modify it according to your needs. For detailed info please refer to the &lt;a href="https://goreleaser.com/customization/" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build and release&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*'&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
  &lt;span class="na"&gt;pages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
  &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ci&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/jdx/mise:2026.8.16&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@main&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Trust git directory in container&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git config --global --add safe.directory '*'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies &amp;amp; building&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;mise deps&lt;/span&gt;
            &lt;span class="s"&gt;mise fetch&lt;/span&gt;
            &lt;span class="s"&gt;mise run release&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.PAT }}&lt;/span&gt;
          &lt;span class="na"&gt;MISE_EXPERIMENTAL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  mise.toml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tools]&lt;/span&gt;
&lt;span class="py"&gt;go&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"latest"&lt;/span&gt;
&lt;span class="py"&gt;goreleaser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"latest"&lt;/span&gt;

&lt;span class="nn"&gt;[deps]&lt;/span&gt;
&lt;span class="py"&gt;go&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nn"&gt;[tasks]&lt;/span&gt;
&lt;span class="py"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fetch Go module dependencies"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;run&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"go mod download"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;testcase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Run Go testcase"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;run&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"go run ./test/test.go"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;build&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Build Go binary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;run&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"mise deps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"mise run fetch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"goreleaser build --snapshot --clean"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test binary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;run&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"mise deps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"mise run testcase"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"mise run build"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;testcases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Run Go test cases"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;run&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"go test ./..."&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Build and release using Goreleaser"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;run&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"goreleaser release --clean"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So I had composed the &lt;code&gt;.goreleaser.yml&lt;/code&gt; file for &lt;a href="https://github.com/Pratyay360/ensor" rel="noopener noreferrer"&gt;ensor&lt;/a&gt; it should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# yaml-language-server: $schema=https://goreleaser.com/static/schema.json&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

&lt;span class="na"&gt;project_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;

&lt;span class="na"&gt;before&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;go mod tidy&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;go generate ./...&lt;/span&gt;

&lt;span class="na"&gt;builds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;
    &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;binary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;

    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CGO_ENABLED=0&lt;/span&gt;

    &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;linux&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;windows&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;darwin&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;freebsd&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;openbsd&lt;/span&gt;

    &lt;span class="na"&gt;goarch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;amd64&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;arm64&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;386"&lt;/span&gt;

    &lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;darwin&lt;/span&gt;
        &lt;span class="na"&gt;goarch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;386"&lt;/span&gt;

    &lt;span class="na"&gt;flags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-trimpath&lt;/span&gt;

    &lt;span class="na"&gt;ldflags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-s -w -X github.com/Pratyay360/ensor/cmd.version={{.Version}}&lt;/span&gt;

&lt;span class="na"&gt;archives&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="na"&gt;ids&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;

    &lt;span class="na"&gt;formats&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tar.gz&lt;/span&gt;

    &lt;span class="na"&gt;name_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;{{ .ProjectName }}_&lt;/span&gt;
      &lt;span class="s"&gt;{{- title .Os }}_&lt;/span&gt;
      &lt;span class="s"&gt;{{- if eq .Arch "amd64" }}x86_64&lt;/span&gt;
      &lt;span class="s"&gt;{{- else if eq .Arch "386" }}i386&lt;/span&gt;
      &lt;span class="s"&gt;{{- else }}{{ .Arch }}{{ end }}&lt;/span&gt;
      &lt;span class="s"&gt;{{- if .Arm }}v{{ .Arm }}{{ end }}&lt;/span&gt;

    &lt;span class="na"&gt;format_overrides&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;windows&lt;/span&gt;
        &lt;span class="na"&gt;formats&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;zip&lt;/span&gt;

&lt;span class="na"&gt;checksum&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;checksums.txt&lt;/span&gt;

&lt;span class="na"&gt;changelog&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asc&lt;/span&gt;
  &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github&lt;/span&gt;

  &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^docs:"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^test:"&lt;/span&gt;

  &lt;span class="na"&gt;groups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Features&lt;/span&gt;
      &lt;span class="na"&gt;regexp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^feat"&lt;/span&gt;
      &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Bug fixes&lt;/span&gt;
      &lt;span class="na"&gt;regexp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^fix"&lt;/span&gt;
      &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Others&lt;/span&gt;
      &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;999&lt;/span&gt;

&lt;span class="na"&gt;nfpms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;packages&lt;/span&gt;
    &lt;span class="na"&gt;package_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Censor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;codebase"&lt;/span&gt;
    &lt;span class="na"&gt;homepage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/Pratyay360/ensor"&lt;/span&gt;
    &lt;span class="na"&gt;maintainer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pratyay360&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;pratyaymustafi@outlook.com&amp;gt;"&lt;/span&gt;
    &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache-2.0&lt;/span&gt;

    &lt;span class="na"&gt;formats&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rpm&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apk&lt;/span&gt;

&lt;span class="na"&gt;homebrew_casks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;
    &lt;span class="na"&gt;homepage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/Pratyay360/ensor"&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Censor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;codebase"&lt;/span&gt;
    &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache-2.0&lt;/span&gt;

    &lt;span class="na"&gt;binaries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;

    &lt;span class="na"&gt;generate_completions_from_executable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;executable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;completion&lt;/span&gt;
      &lt;span class="na"&gt;base_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;
      &lt;span class="na"&gt;shell_parameter_format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cobra&lt;/span&gt;
      &lt;span class="na"&gt;shells&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;zsh&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;fish&lt;/span&gt;

    &lt;span class="na"&gt;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Casks&lt;/span&gt;
    &lt;span class="na"&gt;commit_msg_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Brew&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;cask&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.ProjectName&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.Tag&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

    &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pratyay360&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;homebrew-tap&lt;/span&gt;
      &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;span class="na"&gt;scoops&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;
    &lt;span class="na"&gt;homepage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/Pratyay360/ensor"&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Censor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;codebase"&lt;/span&gt;
    &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache-2.0&lt;/span&gt;
    &lt;span class="na"&gt;commit_msg_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scoop&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.ProjectName&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.Tag&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

    &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pratyay360&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scoop-bucket&lt;/span&gt;
      &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;winget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;winget&lt;/span&gt;
    &lt;span class="na"&gt;publisher&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pratyay360&lt;/span&gt;
    &lt;span class="na"&gt;publisher_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/Pratyay360"&lt;/span&gt;
    &lt;span class="na"&gt;publisher_support_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/Pratyay360/ensor/issues"&lt;/span&gt;
    &lt;span class="na"&gt;package_identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pratyay360.ensor&lt;/span&gt;
    &lt;span class="na"&gt;short_description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Censor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;codebase"&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;unified&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CLI&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;censoring&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;codebase"&lt;/span&gt;
    &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache-2.0&lt;/span&gt;
    &lt;span class="na"&gt;homepage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/Pratyay360/ensor"&lt;/span&gt;
    &lt;span class="na"&gt;commit_msg_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.PackageIdentifier&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.Tag&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

    &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pratyay360&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;winget-pkgs&lt;/span&gt;
      &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt; &lt;span class="c1"&gt;# branch name should be your tool name. for easy navigation later on.&lt;/span&gt;

&lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;github&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pratyay360&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensor&lt;/span&gt;

&lt;span class="na"&gt;snapshot&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;version_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;incpatch&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.Version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}-next"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;for other tech stack you can use make or &lt;a href="https://just.systems/" rel="noopener noreferrer"&gt;just&lt;/a&gt; or &lt;a href="https://mise.jdx.dev/" rel="noopener noreferrer"&gt;mise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fttueybda5noqy683sfkp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fttueybda5noqy683sfkp.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am yet to explore aur as they have stopped registration and haven’t seen any literature on conda forge so have to try this later on (maybe content for a new post), Also creating a custom coppr repo or ppa to distribute tool is tbd.&lt;/p&gt;

</description>
      <category>goreleaser</category>
      <category>brew</category>
      <category>winget</category>
      <category>scoop</category>
    </item>
    <item>
      <title>LightCMS: Writing, Without the Fuss</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Mon, 28 Sep 2026 14:17:49 +0000</pubDate>
      <link>https://dev.to/pratyay360/lightcms-writing-without-the-fuss-2c3h</link>
      <guid>https://dev.to/pratyay360/lightcms-writing-without-the-fuss-2c3h</guid>
      <description>&lt;h3&gt;
  
  
  LightCMS: A CMS That Encourages You to Write Again
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxs1w2ma99li4m1454h1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxs1w2ma99li4m1454h1b.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/finCY7BnobM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You picked a static site generator because you wanted something fast, clean, and lightweight. But somewhere between Hugo, Git, CI/CD pipelines, and VS Code extensions, “writing a blog post” turned into a technical project and the motivation to actually share what you know got lost in the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LightCMS fixes that.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s a self hostable, open-source headless git backed CMS built specifically for static sites wrapped in a gorgeous editor. The goal of lightcms is to encourage you as a writer.&lt;/p&gt;

&lt;h4&gt;
  
  
  How It Works
&lt;/h4&gt;

&lt;p&gt;Your content still lives in GitHub. Your CI/CD still builds and deploys it automatically. Nothing about your existing static-site setup changes under the hood — LightCMS just removes the need to touch Git, Markdown syntax, or front matter schema to use it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why It’s Different
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encouraging as a hobby.&lt;/strong&gt; LightCMS is built with a single goal to make writing enjoyable again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for writing:&lt;/strong&gt; LightCMS tries to provide an experience that the entire process feels as pleasant and friction less as possible&lt;/li&gt;
&lt;li&gt;Copilot: Lightcms comes with a copilot inbuilt and there is also a dictation plugin to make your experience of sharing knowledge smooth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lighter on the planet.&lt;/strong&gt; Static sites are already one of the most eco friendly ways to publish content and light cms aids managing content for static site generators.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  See It Live
&lt;/h4&gt;

&lt;p&gt;LightCMS is live on &lt;strong&gt;lightcms.me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and the github repo is &lt;a href="https://github.com/Pratyay360/lightcms" rel="noopener noreferrer"&gt;https://github.com/Pratyay360/lightcms&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everyone has something worth writing and sharing about a lesson learned, a project shipped, a bug that took three days to fix. LightCMS exists so that the tooling never gets in the way of sharing that experience.&lt;/p&gt;

</description>
      <category>staticsitegenerator</category>
      <category>sveltekit</category>
      <category>cms</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Generate UPI QR Codes Dynamically on Any Device with upiqrcode</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:39:18 +0000</pubDate>
      <link>https://dev.to/pratyay360/generate-upi-qr-codes-dynamically-on-any-device-with-upiqrcode-49bg</link>
      <guid>https://dev.to/pratyay360/generate-upi-qr-codes-dynamically-on-any-device-with-upiqrcode-49bg</guid>
      <description>&lt;p&gt;&lt;em&gt;Generate secure, NPCI compatible UPI payment QR codes directly in the browser using Rust and WebAssembly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ferizbzw4d6mpqsgn11rt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ferizbzw4d6mpqsgn11rt.png" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing upiqrcode
&lt;/h3&gt;

&lt;p&gt;What if you could generate a UPI payment QR code instantly, on any device, without sending payment details to a server?&lt;/p&gt;

&lt;p&gt;Meet &lt;a href="https://npmx.dev/package/upiqrcode" rel="noopener noreferrer"&gt;&lt;strong&gt;upiqrcode&lt;/strong&gt;&lt;/a&gt; — an open-source WebAssembly (WASM) library that generates UPI payment intent links and renders them as vector SVG QR codes, entirely on the client side.&lt;/p&gt;

&lt;p&gt;Whether you’re building a payment page, a small business checkout, a donation flow, or a personal payment tool, upiqrcode makes it easy to generate dynamic UPI QR codes directly in the browser.&lt;/p&gt;

&lt;p&gt;No backend round trips. No unnecessary data collection. Just fast, local QR code generation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is Dynamic UPI?
&lt;/h3&gt;

&lt;p&gt;UPI (Unified Payments Interface) has made digital payments incredibly accessible across India. From small street vendors to large online businesses, UPI QR codes have become a convenient way to receive payments.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;dynamic UPI QR code&lt;/strong&gt; contains a payment intent that can include details such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UPI ID:&lt;/strong&gt; The recipient’s Virtual Payment Address (VPA).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payee name:&lt;/strong&gt; The name displayed in the payment app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amount:&lt;/strong&gt; An optional, predefined payment amount.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction note:&lt;/strong&gt; A short description of the payment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction reference:&lt;/strong&gt; An optional identifier for the transaction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When someone scans the QR code using a compatible UPI app — such as PhonePe, Google Pay, Paytm, or BHIM — the app can read the payment details and prefill the payment screen.&lt;/p&gt;

&lt;p&gt;The user reviews the information and confirms the payment in their UPI app.&lt;/p&gt;

&lt;p&gt;With upiqrcode, these payment details can be turned into a QR code dynamically, without requiring a server to generate the image.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Does upiqrcode Work?
&lt;/h3&gt;

&lt;p&gt;The core idea behind upiqrcode is simple: move QR generation to the device instead of relying on a remote service.&lt;/p&gt;

&lt;p&gt;The library is written in Rust and compiled to WebAssembly. The resulting WASM module runs inside the browser, allowing the application to construct a UPI payment URI and generate a vector SVG QR code locally.&lt;/p&gt;

&lt;p&gt;Here’s the typical workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Enter the payment details&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provide the recipient’s UPI ID and payee name.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;UPI ID: success@upi&lt;/li&gt;
&lt;li&gt;Payee name: Example Store&lt;/li&gt;
&lt;li&gt;Amount: 150.00&lt;/li&gt;
&lt;li&gt;Transaction note: Order payment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Generate the payment intent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The library constructs a UPI payment URI using the supplied details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Render the QR code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The WASM module generates a QR code that can be rendered as an SVG. Since SVG is a vector format, the QR code can scale to different screen sizes without becoming blurry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Scan or open the payment app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The generated QR code can be scanned by a compatible UPI app. An application may also offer an &lt;strong&gt;Open in App&lt;/strong&gt; action to launch a compatible payment handler where supported.&lt;/p&gt;

&lt;p&gt;The payment itself is completed through the user’s chosen UPI app — generating the QR code does not initiate or authorize a payment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Rust and WebAssembly?
&lt;/h3&gt;

&lt;p&gt;Using Rust and WebAssembly makes it possible to run the QR generation logic efficiently in the browser.&lt;/p&gt;

&lt;p&gt;Here are some of the key benefits.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Client-Side Performance
&lt;/h3&gt;

&lt;p&gt;QR generation happens locally, eliminating the need to send a request to a backend just to create a QR code.&lt;/p&gt;

&lt;p&gt;This makes the workflow lightweight and responsive.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Privacy by Design
&lt;/h3&gt;

&lt;p&gt;Payment details can remain on the user’s device during QR generation.&lt;/p&gt;

&lt;p&gt;Because the library does not need a server to construct the QR code, there is no need to transmit the recipient details or payment amount to a remote QR-generation service.&lt;/p&gt;

&lt;p&gt;Actual privacy also depends on how the surrounding application is built, including its analytics, logging, and network requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Cross-Platform Compatibility
&lt;/h3&gt;

&lt;p&gt;WebAssembly enables the compiled library to run in supported browser environments across desktop and mobile devices.&lt;/p&gt;

&lt;p&gt;That means developers can integrate the same core generation logic into different web applications without implementing the entire QR-generation process separately for every platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Crisp, Scalable SVG Output
&lt;/h3&gt;

&lt;p&gt;SVG QR codes are useful for web interfaces, printable receipts, invoices, and payment pages.&lt;/p&gt;

&lt;p&gt;They can be resized while maintaining their vector quality, making them suitable for both small mobile screens and larger displays.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the UPI QR Code Format
&lt;/h3&gt;

&lt;p&gt;At its core, a UPI QR code encodes a payment intent URI.&lt;/p&gt;

&lt;p&gt;A simplified example looks like this:&lt;/p&gt;

&lt;p&gt;upi://pay?pa=success%40upi&amp;amp;pn=Example%20Store&amp;amp;am=150.00&amp;amp;cu=INR&amp;amp;tn=Order%20payment&lt;/p&gt;

&lt;p&gt;The URI contains the information that a compatible UPI application uses to populate the payment screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supported Payment Parameters
&lt;/h3&gt;

&lt;p&gt;ParameterDescriptionRequired?paPayee's UPI ID (VPA)YespnPayee nameYesamPayment amountOptionalcuCurrency, typically INROptionaltnTransaction noteOptionaltrTransaction reference IDOptional&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This is a simplified representation. Implementations should follow the applicable UPI intent specification and validate parameters according to their intended use.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  QR Data Fields
&lt;/h3&gt;

&lt;p&gt;The application can work with structured data before constructing the payment URI.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;payeeVPA — the recipient's UPI ID.&lt;/li&gt;
&lt;li&gt;payeeName — the recipient's display name.&lt;/li&gt;
&lt;li&gt;amount — the requested payment amount, if specified.&lt;/li&gt;
&lt;li&gt;currency — the currency code, typically INR.&lt;/li&gt;
&lt;li&gt;transactionNote — an optional description of the payment.&lt;/li&gt;
&lt;li&gt;transactionId — an optional unique transaction reference, where supported by the implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact data structure depends on the library’s API, but the goal is the same: accept payment details, construct a valid intent URI, and encode that URI into a QR code.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Happens When Someone Scans the QR Code?
&lt;/h3&gt;

&lt;p&gt;The process is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The QR scanner reads the encoded upi://pay URI.&lt;/li&gt;
&lt;li&gt;The compatible UPI application parses the payment parameters.&lt;/li&gt;
&lt;li&gt;The payment screen displays the available recipient and transaction details.&lt;/li&gt;
&lt;li&gt;The user reviews the details and authorizes the payment through the app.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Where Can You Use Dynamic UPI QR Codes?
&lt;/h3&gt;

&lt;p&gt;Dynamic QR generation is useful in several scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E-commerce checkout:&lt;/strong&gt; Generate a QR code with the order amount already filled in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small businesses:&lt;/strong&gt; Display payment QR codes for individual purchases without manually creating a new image each time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Donations and fundraising:&lt;/strong&gt; Include a predefined amount or a descriptive transaction note.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invoices and receipts:&lt;/strong&gt; Embed payment QR codes directly into generated documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personal payment tools:&lt;/strong&gt; Share a QR code with a recipient and optional payment details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web applications:&lt;/strong&gt; Integrate QR generation into browser-based applications without operating a dedicated QR generation API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For payment verification, the responsible party must have an escrow account in place to receive and process webhooks from banks.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy and Security Considerations
&lt;/h3&gt;

&lt;p&gt;Keeping QR generation on the client side is a useful privacy advantage, but it is important to understand what it does — and does not — protect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment details used to generate the QR code can stay in browser memory.&lt;/li&gt;
&lt;li&gt;A back end is not required solely for constructing the QR image.&lt;/li&gt;
&lt;li&gt;The library does not itself authorize a payment or move money.&lt;/li&gt;
&lt;li&gt;The receiving UPI app remains responsible for presenting the payment details and obtaining user confirmation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Bigger Picture
&lt;/h3&gt;

&lt;p&gt;upiqrcode demonstrates how WebAssembly can make browser-based utilities more capable without adding unnecessary infrastructure.&lt;/p&gt;

&lt;p&gt;By combining Rust’s performance, WebAssembly’s portability, and SVG’s flexibility, it provides a practical approach to generating UPI payment QR codes directly on a user’s device.&lt;/p&gt;

&lt;p&gt;For developers building payment interfaces, this means one less server-side operation to maintain — and a simpler way to keep QR generation local.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Dynamic UPI QR codes are a small feature that can make payment experiences much smoother.&lt;/p&gt;

&lt;p&gt;With upiqrcode, developers can generate UPI payment intent links and vector QR codes directly in the browser, customize payment details, and integrate the results into a variety of applications.&lt;/p&gt;

&lt;p&gt;The most interesting part is not just generating a QR code. It’s doing so with a lightweight, privacy-conscious architecture powered by Rust and WebAssembly.&lt;/p&gt;

&lt;p&gt;If you’re building tools around UPI payments, &lt;a href="https://npmx.dev/package/upiqrcode" rel="noopener noreferrer"&gt;upiqrcode&lt;/a&gt; is worth exploring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://npmx.dev/package/upiqrcode" rel="noopener noreferrer"&gt;&lt;strong&gt;Explore the project, try it in your application, and build something useful with it.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dynamic-upi-qr.netlify.app/" rel="noopener noreferrer"&gt;There is a website demonstrating upiqrcode&lt;/a&gt; you can check this out.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://www.pratyay.online" rel="noopener noreferrer"&gt;&lt;em&gt;pratyay.online&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>node</category>
      <category>upi</category>
      <category>npmpackage</category>
      <category>webassembly</category>
    </item>
    <item>
      <title>Newsletters Should Live Next to Your Code — Not in any Database</title>
      <dc:creator>PRATYAY MUSTAFI</dc:creator>
      <pubDate>Mon, 28 Sep 2026 05:59:40 +0000</pubDate>
      <link>https://dev.to/pratyay360/newsletters-should-live-next-to-your-code-not-in-any-database-5hk0</link>
      <guid>https://dev.to/pratyay360/newsletters-should-live-next-to-your-code-not-in-any-database-5hk0</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjvtuhs1jp9kinahxuve4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjvtuhs1jp9kinahxuve4.png" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;newsy&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hello, Internet! 👋&lt;/p&gt;

&lt;p&gt;I’m excited to introduce &lt;a href="https://newsy.lightcms.me" rel="noopener noreferrer"&gt;newsy&lt;/a&gt;&lt;br&gt;
  — a newsletter service for your static site, powered by GitHub Issues.&lt;/p&gt;

&lt;p&gt;If you’re reading this, you probably know the projects that inspired it: &lt;strong&gt;Utterances&lt;/strong&gt; , &lt;strong&gt;Giscus&lt;/strong&gt; , and &lt;strong&gt;Gitalk&lt;/strong&gt;. These projects completely reimagined commenting on static sites by using GitHub Issues as a backend. No database, no CMS, no vendor lock-in — just your repo and a little embed script.&lt;/p&gt;

&lt;p&gt;Newsy takes that same idea and applies it to newsletters.&lt;/p&gt;

&lt;p&gt;Think about it. Instead of signing up for a traditional email marketing service, maintaining a separate mailing list, or paying monthly for a newsletter platform you barely use, your newsletter can simply &lt;em&gt;live alongside your code&lt;/em&gt; in a GitHub repository.&lt;/p&gt;

&lt;p&gt;That’s the core idea behind Newsy: &lt;strong&gt;democratizing newsletter services&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We wanted to strip away the overhead of traditional platforms — the dashboards, the pricing tiers, the data you don’t own — while keeping everything close to the tools you already use and love.&lt;/p&gt;

&lt;p&gt;Your blog is static. Your comments are GitHub Issues. Why shouldn’t your newsletter be too?&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/sfjo6ZVgC9w" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>email</category>
      <category>networking</category>
      <category>github</category>
      <category>newsletter</category>
    </item>
  </channel>
</rss>
