<?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: Ed Rutherford</title>
    <description>The latest articles on DEV Community by Ed Rutherford (@dedsyn4ps3).</description>
    <link>https://dev.to/dedsyn4ps3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F982241%2F28109f0d-49cb-45b3-82dc-10dc59ae6686.jpeg</url>
      <title>DEV Community: Ed Rutherford</title>
      <link>https://dev.to/dedsyn4ps3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dedsyn4ps3"/>
    <language>en</language>
    <item>
      <title>Native Naïveté: Why Native Applications Still Have a Future</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Sun, 01 Sep 2024 20:57:17 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/native-naivete-why-native-applications-still-have-a-future-poe</link>
      <guid>https://dev.to/dedsyn4ps3/native-naivete-why-native-applications-still-have-a-future-poe</guid>
      <description>&lt;h2&gt;
  
  
  A New Wave
&lt;/h2&gt;

&lt;p&gt;Over the past year, there's been a consistent growth in the number of videos, walk-throughs, and supportive articles regarding the use of cross-platform frameworks to build applications with. Heck, even I've written a couple articles touting the ease-of-use of cross-platform frameworks...namely React Native and it's popular Expo framework for mobile app development, and the Rust-powered Tauri framework for building desktop applications.&lt;/p&gt;

&lt;p&gt;These frameworks have become powerhouses in the app-dev sphere, and are go-to's for rapid project development for both teams and individual developers alike! One could reasonably argue that the success of these cross-platform frameworks leaves other native platform languages out in the cold with no real purpose...but I'm not so convinced!&lt;/p&gt;

&lt;h2&gt;
  
  
  The (Not So Simple) Answer
&lt;/h2&gt;

&lt;p&gt;I've begun to notice a growing trend as of late, and I'm sure many of you have as well:&lt;/p&gt;

&lt;p&gt;Everywhere you turn, there's another new article or Youtube video touting that Native app development is dead, and that everyone should just come to grips with that, and start building their applications with some cool cross-platform framework such as Flutter...&lt;/p&gt;

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

&lt;p&gt;At first glance, seeing so many people promoting these frameworks might make you think it's a no-brainer to make the switch! Personally, even I found myself drawn to checking out expo as a means of shifting my mobile development to a more cross-platform scheme...and it worked out great! &lt;/p&gt;

&lt;p&gt;But here's a newsflash: cross-platform frameworks haven't all of a sudden become the end-all-be-all solution to app development!&lt;/p&gt;

&lt;p&gt;I know, I know, I can hear many of you screaming it out already: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why would you say something like that?! Don't you know how awesome Flutter is?? It allows you to have the same codebase for all the different platforms! There's literally no reason to waste time learning multiple native languages when you've got Flutter!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The same thing could be said for Expo, which I DO still use for some of my mobile app development. The important thing that many developers need to realize, is that while a number of these (truly impressive) frameworks have a legitimate use in building many different applications, they are not (and should not) be the only way to do so! &lt;/p&gt;

&lt;p&gt;Frameworks such as Expo and Flutter offer an excellent alternative for creating applications for iOS and Android without having to spend time building separate codebases. Heck, they can even use the same code for building desktop versions of the app! The thing is, there's always a catch...&lt;/p&gt;

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

&lt;p&gt;First things first, let's revisit why one might prefer to choose a cross-platform framework like Expo to prototype and develop their mobile app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Uses JavaScript and React:&lt;/strong&gt; If you have experience with JavaScript and React, React Native is a perfect fit, allowing you to leverage the same skills to build both impressive UI's and backend functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rich Ecosystem:&lt;/strong&gt; The extensive library of third-party plugins and components accelerates development, and provides just about everything you would need to build a fully-functional production app (though it may take some configuring).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, there are certainly a number of intriguing reasons to lean towards using something like Expo to build and release an Android application...but as I said previously, nothing is without a downside. I've had the unfortunate first-hand experience recently to deal with this myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bloated Binaries:&lt;/strong&gt; While having the ability to write both UI and backend code in JavaScript is a wonderful thing for experienced web developers, it brings with it the need for a translation layer that adds to the overall app binary size, and has the potential to impact overall performance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependency Hell:&lt;/strong&gt; Node Modules have the ability to be a jumbled mess as-is sometimes, but all that aside, the constant dependency changes can regularly cause issues building your application from one version to the next...especially if core dependencies require a NodeJS version upgrade that by itself can break other modules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native Module Nightmares:&lt;/strong&gt; If you're looking to incorporate some kind of native Android functionality, in my case widgets, you're required to "eject" or generate native code to write these features. This requires additional work adding compatibility layers for it to work. It's a great feeling once it's all together, but once the NodeJS version gets bumped, instability may soon follow and require re-writes &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;With all this in mind, I've reached the following conclusion (and I think many of you would as well):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to have a completely managed project using Expo, and have no plans for additional fancy bells and whistles, you have an absolutely fantastic set of tools at your fingertips using React Native and the Expo framework! By all means, check it out and see what magic you can write.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want something more, however, like the raw power and speed of a purely native application...keep reading!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Revisiting Native Development
&lt;/h2&gt;

&lt;p&gt;For years, the one and only language that typically came to mind when thinking of Android app development was Java. It's a powerful and performant language, but requires a heck of a lot of boilerplate code to put everything together! Not only that: While Java powered the backend of these applications, XML markup files handled the user interface (UI).&lt;/p&gt;

&lt;p&gt;I'm not sure what all of your opinions are of writing UI's using XML, but I'll tell you right now...it's definitely &lt;strong&gt;not&lt;/strong&gt; my preferred option!&lt;/p&gt;

&lt;p&gt;No worries, though! As is the case with iOS apps as well, Android development has shifted in recent years to utilize a &lt;strong&gt;declarative&lt;/strong&gt; approach to building user interfaces, as well as handling app logic. The Android approach to this involves the use of a popular type-safe language developed by JetBrains called Kotlin, in conjunction with a newly revamped UI framework called Jetpack Compose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A couple key features include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Declarative UI:&lt;/strong&gt; Allows developers to describe the UI in a straightforward manner, reducing code confusion and overlap thanks to more reusable components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interoperability:&lt;/strong&gt; Jetpack Compose can coexist with traditional Android Views, allowing for gradual migration in existing Java-based apps.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So not only do you get an application that runs at full native speeds, you're equipped with a flexible UI framework that doesn't require you to write any compatibility layers to work smoothly. Like I said earlier, though, nothing is without downsides. If you're not familiar with writing code in Kotlin, there can be a learning curve especially if coming from web development using JavaScript (perhaps not as much with TypeScript).&lt;/p&gt;

&lt;h2&gt;
  
  
  Drawing Conclusions
&lt;/h2&gt;

&lt;p&gt;While there are clearly a number of popular and impressive cross-platform frameworks out there supporting mobile development, it should go without saying that by no means is native development dead...quite the contrary! The native landscape has continued to evolve and grow to become an extremely enticing option for those looking to get the most out of their applications, and in the smallest of packages. Android has Jetpack Compose and iOS has SwitUI, both of which offer an exceptional experience for both developers and application users...which is really what it all boils down to.&lt;/p&gt;

&lt;p&gt;The sheer number of options can be dizzying at times, but I implore you, take the time to review what you're looking for in your app and make your framework choice accordingly.&lt;/p&gt;

&lt;p&gt;Cross-platform options have come a long ways the past few years, which is truly a welcome reprieve for those looking for other ways to get involved in mobile development. And while that may be true, they're not the only option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some may not care to admit it, but native app development isn't going anywhere...anytime soon!&lt;/strong&gt;&lt;/p&gt;

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




&lt;div class="ltag__user ltag__user__id__982241"&gt;
    &lt;a href="/dedsyn4ps3" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F982241%2F28109f0d-49cb-45b3-82dc-10dc59ae6686.jpeg" alt="dedsyn4ps3 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;Ed Rutherford&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;IT Support Engineer, Cybersecurity Journeyman, Multi-Language Programmer. Avid learner of all things, and enjoy sharing with those willing to listen!&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>android</category>
      <category>mobile</category>
      <category>programming</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Level-up Your Git Projects with Gitflow</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Thu, 06 Jun 2024 02:10:34 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/how-i-leveled-up-my-github-projects-with-gitflow-25k</link>
      <guid>https://dev.to/dedsyn4ps3/how-i-leveled-up-my-github-projects-with-gitflow-25k</guid>
      <description>&lt;h2&gt;
  
  
  Take your project’s design and evolution to the next level by integrating Gitflow into your development process!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3xedpnq9vbnjzu1vdmt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3xedpnq9vbnjzu1vdmt.png" alt="Info" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  In the Beginning
&lt;/h3&gt;

&lt;p&gt;I’m fairly certain that many of you reading this are plenty familiar with the fantastic ecosystem that is Git, as well as some of the gigantic version control platforms such as Github and GitLab. That being said, there could still be some newbie programmers reading this article, and may need a quick primer on what Git is…so here’s your brief explanation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Git is a version control system that allows you to manage and keep track of your source code history. It’s like a time machine for your code, enabling you to save snapshots of your changes and collaborate with others. GitHub, on the other hand, is a cloud-based hosting service specifically designed for managing Git repositories. It provides a platform where developers can store, create, manage, and collaborate on code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As I’m sure many of you can relate, getting new projects up and running can be a challenge…and I’m just talking about drafting out and writing the code! Like a lot of us come to find out, managing a codebase can be quite a bit more involved than one might think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, you initialize your new repo and link it to a remote branch (if doing it locally)&lt;/li&gt;
&lt;li&gt;Then, you start writing some code…easy right?&lt;/li&gt;
&lt;li&gt;Next thing you know, your project is growing, new ideas emerge to add to the project…and of course, the occasional bug or hot-fix that may be necessary!&lt;/li&gt;
&lt;li&gt;Finally, you keep making changes bit by bit, then commit and push the changes to your remote, with the occasional tag here and there…then repeat…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If the codebase isn’t all that large or complex, following such a straightforward development approach is more than likely going to be okay.&lt;/strong&gt; But what happens if you’re creative juices are flowing and your once-small project now becomes more of a thriving repo with the potential for other collaborators to get involved, or perhaps you begin planning on packaging and distributing the code as it becomes more developed?&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter Workflows
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lucky for us, there are several solutions for dealing with projects that grow in scope and complexity!&lt;/strong&gt; We'll be focusing primarily on one of these solutions, which has become a key piece in my own improved development life-cycle (as well as countless other developers). Before we dive into it, let's have a quick introduction into what all we're talking about here...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9iojlalku3ubbtrrsvi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9iojlalku3ubbtrrsvi.png" alt="Flow" width="560" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some of you may or may not be familiar with the term workflow when it comes to project development strategy. I'm sure it rings a bell for many of you, whether you know exactly what it is or not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A workflow is an end-to-end process that...move[s] data (tasks) through a series of steps from initiation to completion. Once it’s set up, a workflow helps you organize information in a way that is not only understandable, but also repeatable.1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;When it comes to Git project development, there are three popular workflows that are typically implemented by developers and teams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Centralized&lt;/li&gt;
&lt;li&gt;Feature Branch&lt;/li&gt;
&lt;li&gt;Gitflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these has their own pros and cons, and for many are reliable ways to effectively build and maintain projects. &lt;strong&gt;Many of you will more than likely identify with using at least one of these workflows in your day to day coding experiences, even if you never knew it!&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Centralized Workflow:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Uses a central repository (often named &lt;strong&gt;main&lt;/strong&gt;) as the single point of entry for all changes.&lt;/li&gt;
&lt;li&gt;Developers commit directly to the &lt;strong&gt;main&lt;/strong&gt; branch.&lt;/li&gt;
&lt;li&gt;Advantages: Simple and easy to understand.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature Branch Workflow:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Developers create separate branches for individual features or bug fixes.&lt;/li&gt;
&lt;li&gt;Each feature branch is isolated and independent.&lt;/li&gt;
&lt;li&gt;After development, feature branches are merged back into the &lt;strong&gt;&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt; branch.&lt;/li&gt;
&lt;li&gt;Advantages: Branch isolation as well as parallel development ability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gitflow Workflow:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Extends the feature branch workflow.&lt;/li&gt;
&lt;li&gt;Introduces additional branches: &lt;strong&gt;&lt;code&gt;develop&lt;/code&gt;&lt;/strong&gt; (for ongoing development) and &lt;strong&gt;&lt;code&gt;release&lt;/code&gt;&lt;/strong&gt; (for release candidates).&lt;/li&gt;
&lt;li&gt;Feature branches are created from &lt;strong&gt;&lt;code&gt;develop&lt;/code&gt;&lt;/strong&gt; (or &lt;strong&gt;&lt;code&gt;dev&lt;/code&gt;&lt;/strong&gt;), and &lt;strong&gt;&lt;code&gt;hotfix&lt;/code&gt;&lt;/strong&gt; branches are based on &lt;strong&gt;main&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Advantages: Clear structure, well-defined roles for branches, and support for both features and releases.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementing Gitflow
&lt;/h3&gt;

&lt;p&gt;How many of you immediately identified with a particular workflow after reading the previous section? I have a feeling many of you relate to using the first style of workflow, which is totally fine! What I hope to do here is expand your understanding of other common flows, in the event that your projects grow or you simply want a more organized structure for all your code.&lt;/p&gt;

&lt;p&gt;Like many developers, I too was consistently using a Centralized Workflow for quite a long time. Once my projects started becoming significantly more complex, it became clear that a new flow had to be implemented...and the flow that worked best (and &lt;strong&gt;continues&lt;/strong&gt; to work great) for these projects was &lt;strong&gt;Gitflow&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Getting started is pretty straightforward and painless for most, especially if you have &lt;em&gt;full control&lt;/em&gt; of your git repo (which from this point on, I will assume you have). There are only a handful of required actions that need taken when setting the flow up, &lt;strong&gt;many of which can be done automatically depending on the code management platform you're using.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2blq8gb2uwttmgblnni4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2blq8gb2uwttmgblnni4.png" alt="Enable Flow" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the above image, desktop Git applications such as &lt;strong&gt;&lt;code&gt;GitKraken&lt;/code&gt;&lt;/strong&gt; offer built-in Gitflow integration, making it extremely easy to implement Gitflow in your projects!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My personal preference is to use GitKraken for all my desktop-based code management, though you're free to utilize whichever platform works well for you...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8nc531n9ysej8bfgwgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8nc531n9ysej8bfgwgh.png" alt="Important" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If for some reason your desktop Git client doesn’t have the option to enable Gitflow, or perhaps you prefer sticking with the terminal…have no fear! There's a dedicated &lt;strong&gt;&lt;code&gt;git-flow&lt;/code&gt;&lt;/strong&gt; extension available to install using your system's package manager! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Once installed, you can just as easily enable the flow in an existing repository or when creating a new one...&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For Debian/Ubuntu Distros&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; git-flow

&lt;span class="c"&gt;# For Archlinux&lt;/span&gt;
yay &lt;span class="nt"&gt;-S&lt;/span&gt; gitflow-avh

&lt;span class="c"&gt;# Using Homebrew&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;git-flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Putting it Together
&lt;/h3&gt;

&lt;p&gt;Once we have either enabled Gitflow functionality in our desktop Git client, or installed it locally using our system’s package manager, it’s time to actually put it to use!&lt;/p&gt;

&lt;p&gt;Using a desktop client such as GitKraken works out to be the simplest option, since all we need to do is enable it in our repository’s settings tab, and define what we want the various branches to be named. Once that’s done, we’re off to the races!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When following the manual approach to things, we first need to initialize the flow in our repo and define what our various branches should be called using the &lt;code&gt;git-flow&lt;/code&gt; CLI:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable Gitflow in our project&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git flow init
No branches exist yet. Base branches must be created now.
Branch name &lt;span class="k"&gt;for &lt;/span&gt;production releases: &lt;span class="o"&gt;[&lt;/span&gt;master] main
Branch name &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s2"&gt;"next release"&lt;/span&gt; development: &lt;span class="o"&gt;[&lt;/span&gt;develop] dev

How to name your supporting branch prefixes?
Feature branches? &lt;span class="o"&gt;[&lt;/span&gt;feature/] feat
Release branches? &lt;span class="o"&gt;[&lt;/span&gt;release/] 
Hotfix branches? &lt;span class="o"&gt;[&lt;/span&gt;hotfix/] fix
Support branches? &lt;span class="o"&gt;[&lt;/span&gt;support/] 
Version tag prefix? &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now that our new flow is enabled, we can go about developing our code as we normally would…for the most part! Remember, the whole purpose of implementing a Gitflow-styled development process is to better compartmentalize the various stages of the entire process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The core, stable codebase will always follow the &lt;strong&gt;&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt; branch (or whatever you named it)&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;&lt;code&gt;dev&lt;/code&gt;&lt;/strong&gt; branch to make and push changes as you test and grow your project&lt;/li&gt;
&lt;li&gt;When something doesn’t work right after a &lt;strong&gt;&lt;code&gt;dev&lt;/code&gt;&lt;/strong&gt; commit, use the &lt;strong&gt;&lt;code&gt;hotfix&lt;/code&gt;&lt;/strong&gt; type branch to make corrections and merge into &lt;strong&gt;&lt;code&gt;dev&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;After accomplishing a milestone (i.e. finished a new component or code section), merge the current &lt;strong&gt;&lt;code&gt;dev&lt;/code&gt;&lt;/strong&gt; branch into &lt;strong&gt;&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Any Thoughts?
&lt;/h3&gt;

&lt;p&gt;Some of you may be wondering to yourselves: &lt;em&gt;&lt;strong&gt;“What’s the point of doing all this?”&lt;/strong&gt;&lt;/em&gt;. I’m glad you asked! While it may seem like a bit of extra work to enable and implement different branches in a project, doing so will help keep your code commits organized and overall project more structured than a typical single-branch style repo.&lt;/p&gt;

&lt;p&gt;By maintaining such structure in your projects, &lt;em&gt;&lt;strong&gt;you’ll without a doubt become a better developer that’s much better equipped to work on larger projects down the road&lt;/strong&gt;&lt;/em&gt;…be they your own or even an internal corporate project!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current and potential employers alike typically appreciate seeing such well-structured code and commit histories that models like Gitflow produce…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cqlv36k0z931k67vnft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cqlv36k0z931k67vnft.png" alt="Commit Graph" width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Get to it!
&lt;/h3&gt;

&lt;p&gt;Now that you have a better understanding of what Gitflow is, and how it can help you become a better developer, get out there and try it out! The important thing to remember is that while not &lt;strong&gt;all&lt;/strong&gt; projects need implement such a flow…many of them can and should.&lt;/p&gt;

&lt;p&gt;Pick a project that you’ve been working on (or even start a new one), and follow the steps that apply to you to enable Gitflow. Once you do, see what kind of changes you experience while following this workflow! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you find yourself better organizing your commits and code merges as your project grows in complexity? Perhaps you don’t think it makes much of a difference for the project you’re currently working on? It can happen sometimes!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ce36lrlj6mk4n34ta47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ce36lrlj6mk4n34ta47.png" alt="Thanks!" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; Martins, Julia. “Hitting Work Blocks? Try Workflows. [2024].” Asana, Asana, 17 Jan. 2024, asana.com/resources/workflow-examples.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__982241"&gt;
    &lt;a href="/dedsyn4ps3" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F982241%2F28109f0d-49cb-45b3-82dc-10dc59ae6686.jpeg" alt="dedsyn4ps3 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;Ed Rutherford&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;IT Support Engineer, Cybersecurity Journeyman, Multi-Language Programmer. Avid learner of all things, and enjoy sharing with those willing to listen!&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>programming</category>
      <category>productivity</category>
      <category>git</category>
      <category>tooling</category>
    </item>
    <item>
      <title>From NixOS with Love</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Sat, 23 Mar 2024 19:43:06 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/from-nixos-with-love-5e0p</link>
      <guid>https://dev.to/dedsyn4ps3/from-nixos-with-love-5e0p</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnhi6rhqhk8j7bq7bsg9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnhi6rhqhk8j7bq7bsg9.png" alt="Originally published on Medium"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those of you who’ve read my previous article on immutability, you’d know that I’ve been somewhat starting to spread the word about (increasingly popular) &lt;strong&gt;immutable operating systems&lt;/strong&gt;. While the concept and existence of these systems is nothing new, there have been several candidates with their own unique spin on the concept that has been truly remarkable!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Many of the more popular and recognizable immutable operating systems include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fedora Silverblue&lt;/li&gt;
&lt;li&gt;macOS (surprised??)&lt;/li&gt;
&lt;li&gt;Vanilla OS&lt;/li&gt;
&lt;li&gt;NixOS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is the latter of these that I’ve found myself enamored with over the past year, and it’s been one heck of a ride! I figured it was high-time that I shared this truly awesome experience, and help other &lt;code&gt;*nix&lt;/code&gt; enthusiasts understand the profound impacts such an OS could have on them as well!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;p&gt;If you haven’t read my previous article on immutable systems, here’s a quick rundown of what we’re talking about here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Immutable operating systems are built with the principle of immutability in mind. This basically means that the operating system is designed to be unchangeable and unmodifiable during runtime. Any updates or modifications to the system result in the creation of a new instance or snapshot…thus making it extremely easy to rollback to a previous configuration should a change produce undesirable effects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;This means that:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instead of overwriting previous applications and files with their newest selves, an entirely new system state is created and stored separate from the previous one&lt;/li&gt;
&lt;li&gt;This new state is then available at system boot, alongside any previous states from prior upgrades

&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtxc6ct7lzfyijquqozu.png" alt="Originally published on Medium"&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Questions?
&lt;/h2&gt;

&lt;p&gt;Many of you probably have many of the same thoughts, questions, and reservations that I did when considering testing out a system like NixOS. The very first thing that I thought of was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If each system upgrade produces a new copy of the system to boot from, won’t that use up a crap ton of storage space??&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The short answer to this is yes, it has the potential to use up large blocks of storage space on your hard drive…but like I said...&lt;strong&gt;that’s only the short answer!&lt;/strong&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;
A more accurate answer to this is that there’s the &lt;strong&gt;potential&lt;/strong&gt; for high storage requirements, but &lt;strong&gt;only&lt;/strong&gt; if you plan to keep multiple snapshot versions on your system! Generally speaking, when you upgrade your system, you will have a new image to boot into after restart, as well as the previous stable version. It’s totally fine to have one or two previous system images on hand to boot from in case a change you make ends up being no-so-good. NixOS makes rollbacks so trivial, it's usually good practice to have a generation or two on hand to rollback to just in case.&lt;/p&gt;

&lt;p&gt;If you’re a bit clingy and think it’s necessary to hold onto 10+ previous images, though, &lt;strong&gt;you’re going to feel the weight of all that space being used up pretty quickly…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9n466iokfjtbkwm4bsn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9n466iokfjtbkwm4bsn.png" alt="GRUB menu with previous configurations"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that question answered, there’s no other possible downsides for any of you to worry about other than your own willingness to learn about something new and awesome…&lt;/p&gt;
&lt;h2&gt;
  
  
  Something Awesome Awaits
&lt;/h2&gt;

&lt;p&gt;As a hardcore Arch Linux user, I was quite used to frequent rolling updates and library patches. I was also in the habit of regularly handling symlinks and ensuring executables were in my &lt;code&gt;$PATH&lt;/code&gt;...which typically meant being located in the universal &lt;code&gt;/usr/bin&lt;/code&gt; directory. To my surprise, among other things, was to learn that no such directory existed in NixOS...at least not in the traditional sense!&lt;/p&gt;

&lt;p&gt;Everything as you know it when it comes to system paths and application directories will be completely flipped on its head with NixOS...and I'm talking some serious &lt;em&gt;Inception&lt;/em&gt; type stuff here folks!&lt;/p&gt;

&lt;p&gt;In a typical Arch system, you run an upgrade command to update all of your applications:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-Syu&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;During this process, any new versions of an application or library are downloaded and installed, replacing the old version. This applies to supporting modules and DLL’s too. Out with the old, in with the new! But what happens if your upgrade gets interrupted? Network disconnect, power surge, catastrophic shutdown cause of some weird possessed PC?? If you’re lucky, you are able to re-run the command and pick back up where you left off. Worst case, you get corrupted files, or have to fix pacman by unlocking it (among other possible scenarios)…this is no bueno!&lt;/p&gt;

&lt;p&gt;With NixOS, updates are &lt;code&gt;atomic&lt;/code&gt;, meaning that all update operations only get applied once the entire process has finished. If something gets interrupted or crashes during the update, no worries! No system files have been created/modified in any way whatsoever. This adds to the overall stability of the system!&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Personally, I always enjoyed having bleeding edge versions of many of the applications I’d regularly use.&lt;/strong&gt; As it turns out, NixOS has an &lt;code&gt;unstable channel&lt;/code&gt; (a sources repo of sorts) that you can follow for all your system upgrades. This means you can have the stability of an immutable system, while also enjoying the newest versions of your favorite applications and tools!&lt;/p&gt;
&lt;h2&gt;
  
  
  The Cherry On Top
&lt;/h2&gt;

&lt;p&gt;So far, we’ve seen that NixOS has several qualities that should peak all of your interest, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Atomic, safe, system upgrades&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snapshot-type versioning for quick-and-easy rollbacks (built-in!)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stable and Unstable (bleeding-edge) application sources to choose from&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these aspects are fine and dandy, but the real cherry on top is how the system itself is built and configured…that’s right, I said &lt;em&gt;&lt;strong&gt;configured&lt;/strong&gt;&lt;/em&gt;! NixOS isn’t some typical Linux system that you manage from the command line or GUI. It's an intricate, complex system that is &lt;strong&gt;realized&lt;/strong&gt; and managed by a core configuration file (or flake depending on the setup)…&lt;strong&gt;the glorious &lt;code&gt;configuration.nix&lt;/code&gt;!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Did you notice the file extension of the config file? That's right, &lt;em&gt;the OS has it's own programming language which it is built on top of!&lt;/em&gt; If you were unaware of its existence before now, it's okay, but the name should say it all...&lt;/p&gt;
&lt;h2&gt;
  
  
  Package Manager | Language Framework
&lt;/h2&gt;

&lt;p&gt;Nix is an interesting language, very similar to Haskell, and is the backbone of the operating system. I'm not going to get into it in this article, but will go a bit more in-depth in an upcoming article…so stay tuned and be sure to subscribe! As usual, I highly encourage anyone interested in the OS to at least spend a little time looking through the official &lt;a href="https://nixos.org/learn.html" rel="noopener noreferrer"&gt;documentation and tutorials&lt;/a&gt; to get an idea of how it works.&lt;/p&gt;

&lt;p&gt;At first, the thought of building out a configuration file to control what applications were installed on my machine seemed downright ludicrous! Why not just run commands from the terminal to install why I need? News flash..you can! &lt;strong&gt;But&lt;/strong&gt; it's much more efficient and customizable to do so from the configuration file. Below is a small section that could be imported or written directly into the main config file. You'll notice it's pretty straightforward to understand, especially when declaring the &lt;code&gt;hostname&lt;/code&gt; for the system and enabling &lt;code&gt;ssh&lt;/code&gt; and &lt;code&gt;postgresql&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;fileSystems&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/dev/disk/by-label/nixos"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;networking&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;hostName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mandark"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;systemPackages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;firefox&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;openssh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;openssh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;forwardX11&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;postgresql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;postgresql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enableTCPIP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;xserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;xserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;desktopManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;kde4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;As it would soon turn out, using a configuration-based system is absolutely magnificent! Not only is it extremely powerful and flexible, it can be &lt;strong&gt;reproduced&lt;/strong&gt; across machines! That’s right, I can tailor my own perfect system, and use the same configuration on my other devices to reproduce the &lt;em&gt;exact same&lt;/em&gt; setup with absolutely minimal effort! Even more awesome, I can build the new system on a beefy desktop PC and &lt;em&gt;push&lt;/em&gt; it over the network to a laptop and install everything there…&lt;strong&gt;like I’m some kind of Nix Warlock!!!&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s these final features that convinced me to give NixOS a worthy shot of being a daily driver on one of my laptops. &lt;strong&gt;And before I knew it, I was running it daily on my main desktop and one of my Raspberry Pi’s as well!&lt;/strong&gt; Even now, I’m writing part of this article on it because it just works so darn well, regardless of how powerful your hardware is!&lt;/p&gt;
&lt;/blockquote&gt;


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

&lt;p&gt;There’s actually one other (freaking awesome) thing that can be done to make a NixOS system the best of the best that you can have on your device…&lt;strong&gt;but you’ll have to stay tuned for that article!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whether you’re an Arch Linux power-user like me, or an intrepid newbie looking for the perfect OS to call home, I hope you take a moment to seriously look into NixOS. &lt;strong&gt;It has the potential to be the paradigm shift that many of you have been looking for, and it’s community is only going to continue to grow!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope you enjoyed a glimpse at my own personal experience and love for NixOS! Give me a like and leave a comment with your thoughts! &lt;strong&gt;If you’re curious and want to learn more about various programming frameworks and systems like NixOS, feel free to follow me and subscribe for updates on newly released articles!&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Until next time, stay curious and seek knowledge!
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovrf759q24i5cnmrhu6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovrf759q24i5cnmrhu6c.png" alt="By the way..."&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__982241"&gt;
    &lt;a href="/dedsyn4ps3" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F982241%2F28109f0d-49cb-45b3-82dc-10dc59ae6686.jpeg" alt="dedsyn4ps3 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;Ed Rutherford&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;IT Support Engineer, Cybersecurity Journeyman, Multi-Language Programmer. Avid learner of all things, and enjoy sharing with those willing to listen!&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://github.com/dedsyn4ps3?source=post_page-----d1b26dd3dc9c--------------------------------" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F49820403%3Fv%3D4%3Fs%3D400" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://github.com/dedsyn4ps3?source=post_page-----d1b26dd3dc9c--------------------------------" rel="noopener noreferrer" class="c-link"&gt;
          dedSyn4ps3 (Ed Rutherford) · GitHub
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Founder and Lead Consultant for Null-Return IT Services and Consulting. Multi-language programmer and cybersecurity journeyman. - dedSyn4ps3
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.githubassets.com%2Ffavicons%2Ffavicon.svg"&gt;
        github.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>linux</category>
      <category>tooling</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Goodbye Electron. Hello Tauri!</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Mon, 12 Feb 2024 01:21:24 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/goodbye-electron-hello-tauri-26d5</link>
      <guid>https://dev.to/dedsyn4ps3/goodbye-electron-hello-tauri-26d5</guid>
      <description>&lt;h2&gt;
  
  
  Utilize the Rust-powered backend framework paired with a React frontend to offer an awesome browser-less experience
&lt;/h2&gt;



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



&lt;p&gt;Many a developer can tell you about their love-hate relationship with the JavaScript GUI framework that helped revolutionize the way many desktop applications are made. The fact is that many of the apps we all use today, whether it pertains to development, social media, communications…you name it, have been built using the Electron framework.&lt;/p&gt;

&lt;p&gt;If you’re ever curious, check out the curated list of apps that use Electron from their &lt;a href="https://www.electronjs.org/apps" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;The point is, Electron offered developers with web development experience the opportunity to create standalone desktop applications for multiple platforms…all without having to learn any new programming languages! It offered the ability to use the same JavaScript, CSS, and HTML that many of us use all the time, which of course is quite wonderful!&lt;/p&gt;

&lt;p&gt;To briefly summarize how Electron was able to offer this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Electron is a framework for building desktop applications using JavaScript, HTML, and CSS. By embedding Chromium and Node.js into its binary, Electron allows you to maintain one JavaScript codebase and create cross-platform apps that work on Windows, macOS, and Linux — no native development experience required.&lt;/p&gt;
&lt;/blockquote&gt;




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




&lt;p&gt;One of the biggest downsides to building desktop apps using Electron, as some of you have probably seen throughout Stack Overflow and other forums…is the resulting binary tends to be outrageously large! So much so, that even just a medium-sized code base could result in a final binary ~60MB.&lt;/p&gt;

&lt;p&gt;After experiencing this frustration firsthand, I started wondering if there was a magical solution to this problem…and as it turns out, &lt;strong&gt;Rust just so happened to offer one!&lt;/strong&gt;&lt;/p&gt;




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




&lt;blockquote&gt;
&lt;p&gt;Tauri is a toolkit that helps developers make applications for the major desktop platforms — using virtually any frontend framework in existence. The core is built with Rust, and the CLI leverages Node.js making Tauri a genuinely polyglot approach to creating and maintaining great apps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Diving In
&lt;/h3&gt;

&lt;p&gt;To my excitement, their command-line scaffolding tool creates all the Rust files you need to get up and running using familiar frontend frameworks. Not only that, but once I was ready to start adding my own functions to the backend for the UI to use, Tauri makes getting everything working together rather seamless!&lt;/p&gt;




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




&lt;p&gt;I decided to give Tauri a try to create a new desktop dashboard application for a community project I was planning on contributing to, and spoiler…&lt;strong&gt;it didn’t disappoint!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned previously, getting started was rather straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure your system has Rust installed&lt;/li&gt;
&lt;li&gt;If on Windows or Linux, make sure to install the relevant dependencies&lt;/li&gt;
&lt;li&gt;Run a simple command to set up your project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, it was a matter of getting the frontend source files all put together, while occasionally referencing the docs from Tauri when I needed some pointers on Inter-Process Communication between the UI and backend.&lt;/p&gt;





&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;The beauty of using Tauri to create my dashboard is I no longer had to bother with creating a separate &lt;code&gt;preload.js&lt;/code&gt; file just to be able to utilize inter-process communication properly.&lt;/p&gt;

&lt;p&gt;All that was required was the proper annotation in the &lt;code&gt;main.rs&lt;/code&gt; above the function that I wanted to call from the UI, and a simple additional import line in my React &lt;code&gt;jsx&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { invoke } from '@tauri-apps/api/tauri'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The power of a Tauri-built app, in the end, comes down to the fact that its backend utilizes Rust. This allows developers such as myself to build their final product into a native-running binary at a fraction of the size of many Electron-built applications.&lt;/p&gt;
&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;It’s become clear, at least to me, that Tauri certainly has the potential to continue growing to the point in which it topples Electron as the dominant “front-end” GUI framework. Even though there may be an intimidation factor due to being built on Rust, the small amount of time needed to understand its internals is well worth it!&lt;/p&gt;




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




&lt;p&gt;I encourage anyone looking to start their journey into front-end GUI development to check out the Tauri framework, and resist the urge to immediately look to Electron as the immediate solution…you’ll be pleasantly surprised I assure you!&lt;/p&gt;

&lt;p&gt;For completeness, you can find the entire code base for my community project on my Gitlab. Check it out if you’re looking for any ideas for your own projects!&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://gitlab.com/dedSyn4ps3/enviroplus-desktop" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgitlab.com%2Fuploads%2F-%2Fsystem%2Fproject%2Favatar%2F38788161%2Ftauri_logo_dark.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://gitlab.com/dedSyn4ps3/enviroplus-desktop" rel="noopener noreferrer" class="c-link"&gt;
          Ed Rutherford / Enviro Plus Desktop · GitLab
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          GitLab.com
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgitlab.com%2Fassets%2Ffavicon-72a2cad5025aa931d6ea56c3201d1f18e68a8cd39788c7c80d5b2b82aa5143ef.png"&gt;
        gitlab.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag__user ltag__user__id__982241"&gt;
    &lt;a href="/dedsyn4ps3" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F982241%2F28109f0d-49cb-45b3-82dc-10dc59ae6686.jpeg" alt="dedsyn4ps3 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;Ed Rutherford&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;IT Support Engineer, Cybersecurity Journeyman, Multi-Language Programmer. Avid learner of all things, and enjoy sharing with those willing to listen!&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;a href="https://github.com/dedsyn4ps3" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;💻 Check out my Github, too!&lt;/a&gt;


</description>
      <category>rust</category>
      <category>programming</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Immutability: A Growing Trend</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Sat, 03 Feb 2024 20:07:15 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/immutability-a-growing-trend-4j3m</link>
      <guid>https://dev.to/dedsyn4ps3/immutability-a-growing-trend-4j3m</guid>
      <description>&lt;h3&gt;
  
  
  What is it, how it works, and why you should seriously consider checking it out!
&lt;/h3&gt;




&lt;p&gt;If you happen to pay any kind of attention to ongoing trends in the Linux OS sphere, you've more than likely come across posts, articles, or maybe a few videos that make reference to these interesting operating systems that tout having this magical structure that makes them "&lt;strong&gt;immutable&lt;/strong&gt;".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Immutable operating systems are built with the principle of immutability in mind. This basically means that the operating system is designed to be &lt;strong&gt;unchangeable&lt;/strong&gt; and &lt;strong&gt;unmodifiable&lt;/strong&gt; during runtime. Any updates or modifications to the system result in the creation of a new &lt;strong&gt;instance&lt;/strong&gt; or &lt;strong&gt;snapshot&lt;/strong&gt;...thus making it extremely easy to rollback to a previous configuration should a change produce undesirable effects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, so maybe a literal kind of definition isn't exactly the most tasteful way of explaining what makes these OS's different from everything else...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perhaps a better way to look at the difference between a typical OS many of us use, and an immutable one is like this:&lt;/strong&gt;&lt;br&gt;
&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6rk32evtsig39sica3y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6rk32evtsig39sica3y.png" alt="Standard Linux Filesystem Hierarchy"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Standard OS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The vast majority of Linux operating systems, such as Arch or Ubuntu, follow a standard file system hierarchy (shown above).&lt;/li&gt;
&lt;li&gt;Users run their respective package manager commands to update their system, i.e. &lt;code&gt;apt upgrade&lt;/code&gt; or &lt;code&gt;pacman -Syu&lt;/code&gt;, to check whether or not there are newer software versions available.&lt;/li&gt;
&lt;li&gt;If a more recent version exists, the application binary (or shared libraries) is downloaded from the remote source and installed…consequently overwriting the previous installation files.&lt;/li&gt;
&lt;li&gt;Even though &lt;strong&gt;Windows&lt;/strong&gt; differs in its system structure, it too follows a similar process for system updates.&lt;/li&gt;
&lt;li&gt;Such processes of &lt;em&gt;update and replace&lt;/em&gt; are ultimately what makes these &lt;strong&gt;&lt;em&gt;mutable systems&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Immutable Systems
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Upgrades happen in the complete &lt;strong&gt;opposite way&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Instead of overwriting previous applications and files with their newest selves, an entirely new system state is created and stored separate from the previous one.&lt;/li&gt;
&lt;li&gt;This new state is then available at system boot, alongside any previous states from prior upgrades.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
&lt;strong&gt;Immutable systems function similarly to version management tools such as git.&lt;/strong&gt; Whenever you update or add new code to a project that's being tracked by git, you &lt;em&gt;&lt;strong&gt;commit&lt;/strong&gt;&lt;/em&gt; the new changes to the code base, which in turn receives a new hash and other metadata attached to it. Even though your code is updated, &lt;strong&gt;you're still able to &lt;em&gt;rollback&lt;/em&gt; to the previous commit and toss all those changes if something happened to break after the commit was made.&lt;/strong&gt;&lt;br&gt;
&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5rz5r12z217pnks0rll.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5rz5r12z217pnks0rll.png" alt="Simple versioning representation"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Some Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Version Control Mechanism:&lt;/strong&gt; Immutable operating systems enable easier version control and rollback capabilities. If an update or change results in an issue or unintended consequence, reverting to a previous version is as simple as switching back to a known stable image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Maintenance:&lt;/strong&gt; With immutable operating systems, the need for continuous patching and updates is significantly reduced. Since the system remains unchanged during runtime, there's no need for live updates or patches (unless of course you want to).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Stability:&lt;/strong&gt; Immutable operating systems provide a high level of stability due to their unchangeable nature. By eliminating the potential for unexpected modifications or conflicts, the system is less prone to errors and crashes.&lt;/li&gt;
&lt;/ol&gt;



&lt;h3&gt;
  
  
  A Few (Slight) Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Storage Requirements:&lt;/strong&gt; Since each system version or change requires the creation of a new instance or image, the storage requirements for immutable operating systems can be higher compared to traditional operating systems. &lt;strong&gt;This isn't always the case though, as long as you keep the number of stored snapshots to a minimum.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning Curves:&lt;/strong&gt; Moving from a traditional operating system to an immutable one can involve a learning curve for some, especially for a system like NixOS which utilizes a single configuration file for defining system state. Users sometimes need to acquaint themselves with new tools and workflows for managing and updating the system. &lt;strong&gt;As with everything, reading through documentation and user forums can quickly flatten any curve.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br&gt;
There have been a number of immutable systems that have increasingly become more popular with users, and each has its own implementation of immutable file structures.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;strong&gt;A few of these worth mentioning include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NixOS&lt;/li&gt;
&lt;li&gt;Fedora Silverblue&lt;/li&gt;
&lt;li&gt;VanillaOS&lt;/li&gt;
&lt;li&gt;macOS (through similar mechanisms)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00f497k3hka5uevbimaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00f497k3hka5uevbimaz.png" alt="Check it out!"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  So What?
&lt;/h3&gt;

&lt;p&gt;I can already hear some of you saying it out loud:&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;"So what? It sounds like just another flavor of something I don't really need"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;
And ya know, you may be right…&lt;strong&gt;or you may be dead wrong!&lt;/strong&gt; The thing is, &lt;em&gt;immutable operating systems aren't the be-all-end-all of things&lt;/em&gt;. For many, they are a means to an end, and for others…well, for others, they're the only option. &lt;/p&gt;

&lt;p&gt;Personally, I use NixOS on a daily basis on several of my laptops and desktops, but also love the bleeding edge and raw power that Arch Linux offers, and in certain scenarios the sysadmin qualities of CentOS/Rocky Linux.&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;The beautiful thing is, as with all things Linux…the choice is yours!&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sxjwvct485t3uiivqaf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sxjwvct485t3uiivqaf.jpeg" alt="Photo by Javier Allegue Barros on Unsplash"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;If you found this article intriguing, and would like to keep up with the wide world of application development and systems exploration, give me a follow and feel free to leave your thoughts! I try my best to respond to everyone's comments, and highly value all of your opinions!&lt;br&gt;
&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovrf759q24i5cnmrhu6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovrf759q24i5cnmrhu6c.png" alt="By the way..."&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__982241"&gt;
    &lt;a href="/dedsyn4ps3" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F982241%2F28109f0d-49cb-45b3-82dc-10dc59ae6686.jpeg" alt="dedsyn4ps3 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;Ed Rutherford&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dedsyn4ps3"&gt;IT Support Engineer, Cybersecurity Journeyman, Multi-Language Programmer. Avid learner of all things, and enjoy sharing with those willing to listen!&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;a href="https://github.com/dedsyn4ps3" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;💻 Check out my Github&lt;/a&gt;


</description>
      <category>productivity</category>
      <category>linux</category>
      <category>beginners</category>
      <category>systems</category>
    </item>
    <item>
      <title>Building a PinePhone App With React and Tauri</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Thu, 14 Sep 2023 03:04:08 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/building-a-pinephone-app-with-react-and-tauri-416b</link>
      <guid>https://dev.to/dedsyn4ps3/building-a-pinephone-app-with-react-and-tauri-416b</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dDk67o_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ps0263ujsuej7a5rwvtr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dDk67o_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ps0263ujsuej7a5rwvtr.png" alt="TLDR" width="800" height="183"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://gitlab.com/dedSyn4ps3/enviroplus-pinephone" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--XyaibTPa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://gitlab.com/uploads/-/system/project/avatar/39616956/pine.png" height="678" class="m-0" width="500"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://gitlab.com/dedSyn4ps3/enviroplus-pinephone" rel="noopener noreferrer" class="c-link"&gt;
          Ed Rutherford / Enviroplus Pinephone · GitLab
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          GitLab.com
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--IWHKqAKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://gitlab.com/assets/favicon-yellow-018213ceb87b472388095d0264be5b4319ef47471dacea03c83ecc233ced2fd5.png" width="32" height="32"&gt;
        gitlab.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  The Time Has Come
&lt;/h2&gt;

&lt;p&gt;Over the past few years, pure Linux-powered mobile devices have found their way into the mainstream. The ability to run a customized kernel on something like an Android device is nothing new, and the same can be said for iPhone jail-breaking.&lt;/p&gt;

&lt;p&gt;The difference here is that these devices (many of them at least) are built from the ground up with a focus on free and open-source technologies. As such, they aim to run fully open Linux-based operating systems, and in many cases include physical hardware switches to disable various components to provide additional user privacy.&lt;/p&gt;

&lt;p&gt;The rise of more powerful and inexpensive ARM-based chips now mean that many of the devices have the potential to function at levels equivalent or close to mid-range closed source devices running iOS or Android.&lt;/p&gt;

&lt;p&gt;Many hobbyists and developers (such as myself) have started flocking to obtain these devices, leaving many of us with the same question after getting one: &lt;strong&gt;“This is awesome, but how do I go about creating my own apps for this thing?”.&lt;/strong&gt; My hope is that this article will help some of you answer this question, and assist in developing your own applications for these popular devices!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OnAJuY8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kuqgcxxgopmnhsr10v6k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OnAJuY8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kuqgcxxgopmnhsr10v6k.png" alt="The PinePhone" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the most popular Tux phones on the market is without a doubt the PinePhone (and more recently the PinePhone Pro) made by &lt;a href="https://www.pine64.org"&gt;Pine64&lt;/a&gt;. I’ve unfortunately not had it in my budget to acquire a new Pro version, so had to settle on developing on the first-gen Community Edition instead. The project outlined here is by no means locked to running on just these devices. If you have something like a Librem 5 by Purism, see how you can make it work!&lt;/p&gt;

&lt;p&gt;In a previous article, I wrote about a new (and now maturing) framework called Tauri that I’ve started using to replace my old Electron-based projects. Unlike Electron, it uses Rust for handling all backend functionality, and allows for using web technologies to build your UI!&lt;/p&gt;

&lt;p&gt;Even though I initially used Tauri to create a new desktop application, &lt;strong&gt;I thought it would be awesome to test out its capabilities running on the PinePhone!&lt;/strong&gt; Let’s get to the good stuff, shall we?&lt;/p&gt;




&lt;h2&gt;
  
  
  Starting Off
&lt;/h2&gt;

&lt;p&gt;The Tauri documentation provides excellent guides on creating new projects from scratch using their command line tool, including the ability to generate a complete skeleton using the front-end framework of your choice. Because I already had developed a web app using React, I already had the UI code structure in place. Since that was the case, all I needed to do was create the necessary Rust and configuration files needed by Tauri in the project directory:&lt;/p&gt;

&lt;p&gt;Install CLI tool → &lt;code&gt;yarn add -D @tauri-apps/cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Initialize Tauri → &lt;code&gt;yarn tauri init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you’re creating a brand new project from scratch and you need to generate all the needed files &lt;strong&gt;for both front and backend, you’d run:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn create tauri-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Backend Functions
&lt;/h2&gt;

&lt;p&gt;Because I was building a dashboard application that needed to make regular GET requests to a Raspberry Pi on the local network, I had to make sure to include the same backend Rust function that the other versions of my app use to make these requests.&lt;/p&gt;

&lt;p&gt;With Tauri, there’s no need to create a &lt;code&gt;preload.js&lt;/code&gt; file for the UI to call backend functions. Instead, all that’s needed is the &lt;code&gt;@tauri-apps/api&lt;/code&gt; library added to your &lt;code&gt;package.json&lt;/code&gt; file. You can then invoke the function from your JavaScript/React code with the following import:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { invoke } from '@tauri-apps/api/tauri'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Using &lt;code&gt;invoke&lt;/code&gt;, you can then call your backend function by name, passing any arguments necessary. For my application, I make this call using a JavaScript function that passes the URL endpoint that I am making the request to in order to retrieve a particular sensor value:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The corresponding backend function gets included in the &lt;code&gt;main.rs&lt;/code&gt; file that Tauri creates in the projects &lt;code&gt;src-tauri&lt;/code&gt; directory:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;It’s important to keep in mind that since this application is being written to run specifically on the PinePhone (or some other mobile Linux device), &lt;strong&gt;component sizes and window dimensions need to be taken into consideration.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Binary Creation
&lt;/h2&gt;

&lt;p&gt;Once you’ve gone through the process of setting up your interface and any backend function calls, tested and debugged everything, you probably want to build a final product! Because these devices run Linux, Tauri will build a &lt;code&gt;.deb&lt;/code&gt; and &lt;code&gt;.AppImage&lt;/code&gt; binary for running and distributing your application. Building everything is as simple as running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn tauri build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I did notice an issue with the automated &lt;code&gt;AppImage&lt;/code&gt; build script while trying to run on the &lt;code&gt;aarch64&lt;/code&gt; platform, so to successfully finish building the AppImage for my app, I simply downloaded and ran the &lt;code&gt;appimagetool&lt;/code&gt; utility to finish packaging:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h2&gt;
  
  
  Test It Out!
&lt;/h2&gt;

&lt;p&gt;After that, you’ll end up with a shiny new AppImage with everything required to run built-in! &lt;strong&gt;Simply make it executable and run it to enjoy your new PinePhone (or similar) app!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UWl2Mr4H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfudt2g5jvnl1sitq6vt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UWl2Mr4H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfudt2g5jvnl1sitq6vt.png" alt="The Final Product" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Word of Warning
&lt;/h2&gt;

&lt;p&gt;I love my PinePhone, but when it comes to doing all of the development solely on the device, I’d advise against it. &lt;strong&gt;It’s plenty capable&lt;/strong&gt;, but hot reloading can take longer than you’d like, &lt;strong&gt;and the same goes for building the final binary&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I found doing the majority of development and debugging on a separate ARM-powered device (my Raspberry Pi 4) was much quicker. Once you figure out the right window dimensions, the devpreview still provides an accurate look as to how the app is coming along.&lt;/p&gt;

&lt;p&gt;After building the final executable on the Pi, it’s super simple to transfer over to the PinePhone using either &lt;code&gt;scp&lt;/code&gt; or a graphical &lt;code&gt;SFTP&lt;/code&gt; tool!&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Curious to see what you can make with this? Head over to the Gitlab repo and check it out! &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://gitlab.com/dedSyn4ps3/enviroplus-pinephone" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--XyaibTPa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://gitlab.com/uploads/-/system/project/avatar/39616956/pine.png" height="678" class="m-0" width="500"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://gitlab.com/dedSyn4ps3/enviroplus-pinephone" rel="noopener noreferrer" class="c-link"&gt;
          Ed Rutherford / Enviroplus Pinephone · GitLab
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          GitLab.com
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--IWHKqAKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://gitlab.com/assets/favicon-yellow-018213ceb87b472388095d0264be5b4319ef47471dacea03c83ecc233ced2fd5.png" width="32" height="32"&gt;
        gitlab.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;I hope to see even more great mobile Linux apps out there powered by Tauri in the near future.&lt;/strong&gt; For those of you interested in Android development, Tauri &lt;strong&gt;&lt;strong&gt;also&lt;/strong&gt;&lt;/strong&gt; has mobile capabilities currently in alpha!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I've also published a fairly lengthy walk-through of how to build such an Android app over on &lt;a href="https://medium.com/better-programming/getting-started-using-tauri-mobile-6f90de5b098"&gt;Medium&lt;/a&gt;&lt;/strong&gt; that I encourage you to check out if interested. I'll be publishing it here as well in the near future. 🌟&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ot2V-khC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kye5mgzb02z71bmkyj4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ot2V-khC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kye5mgzb02z71bmkyj4j.png" alt="Check out Medium" width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>mobile</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using PowerShell Forms for Repetitive (Work) Tasks</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Tue, 12 Sep 2023 03:06:04 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/using-powershell-forms-for-repetitive-work-tasks-cm7</link>
      <guid>https://dev.to/dedsyn4ps3/using-powershell-forms-for-repetitive-work-tasks-cm7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dGOHd3oU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b68ewlh04u8zdx22kj9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dGOHd3oU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b68ewlh04u8zdx22kj9k.png" alt="TL;DR" width="800" height="149"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dedSyn4ps3"&gt;
        dedSyn4ps3
      &lt;/a&gt; / &lt;a href="https://github.com/dedSyn4ps3/response-generator-example"&gt;
        response-generator-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1 id="user-content-response-generator"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#response-generator"&gt;Response Generator&lt;/a&gt;&lt;/h1&gt;
&lt;br&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/57aba7606717cb122d183f127a6357dd2ff664d6238882f3d055e25702059aba/68747470733a2f2f696d616765732d7769786d702d6564333061383662386334636138383737373335393463322e7769786d702e636f6d2f662f62636536316332642d663038652d346366662d616233332d3633363062646666643665382f64656e7a716e332d34343432366239302d616162392d343938332d626638382d6366323937353231653161352e706e672f76312f66696c6c2f775f313238302c685f3830302c737472702f6461726b6d7973745f706f7765727368656c6c5f77616c6c70617065725f5f3235363078313630305f5f62795f626173746172646f70657261746f725f64656e7a716e332d66756c6c766965772e706e673f746f6b656e3d65794a30655841694f694a4b563151694c434a68624763694f694a49557a49314e694a392e65794a7a645749694f694a31636d3436595842774f6a646c4d4751784f4467354f4449794e6a517a4e7a4e684e5759775a4451784e5756684d4751794e6d55774969776961584e7a496a6f6964584a754f6d467763446f335a54426b4d5467344f5467794d6a59304d7a637a5954566d4d4751304d54566c5954426b4d6a5a6c4d434973496d39696169493657317437496d686c6157646f64434936496a77394f444177496977696347463061434936496c77765a6c7776596d4e6c4e6a466a4d6d51745a6a41345a53303059325a6d4c5746694d7a4d744e6a4d324d474a6b5a6d5a6b4e6d55345843396b5a5735366357347a4c5451304e444932596a6b774c574668596a6b744e446b344d7931695a6a67344c574e6d4d6a6b334e5449785a5446684e533577626d63694c434a336157523061434936496a77394d5449344d434a3958563073496d46315a43493657794a31636d343663325679646d6c6a5a5470706257466e5a53357663475679595852706232357a496c31392e68766d452d65424246756e5535455f48416e2d43434c4e4b4131595f444c704530786c5571745459434b34"&gt;&lt;img src="https://camo.githubusercontent.com/57aba7606717cb122d183f127a6357dd2ff664d6238882f3d055e25702059aba/68747470733a2f2f696d616765732d7769786d702d6564333061383662386334636138383737373335393463322e7769786d702e636f6d2f662f62636536316332642d663038652d346366662d616233332d3633363062646666643665382f64656e7a716e332d34343432366239302d616162392d343938332d626638382d6366323937353231653161352e706e672f76312f66696c6c2f775f313238302c685f3830302c737472702f6461726b6d7973745f706f7765727368656c6c5f77616c6c70617065725f5f3235363078313630305f5f62795f626173746172646f70657261746f725f64656e7a716e332d66756c6c766965772e706e673f746f6b656e3d65794a30655841694f694a4b563151694c434a68624763694f694a49557a49314e694a392e65794a7a645749694f694a31636d3436595842774f6a646c4d4751784f4467354f4449794e6a517a4e7a4e684e5759775a4451784e5756684d4751794e6d55774969776961584e7a496a6f6964584a754f6d467763446f335a54426b4d5467344f5467794d6a59304d7a637a5954566d4d4751304d54566c5954426b4d6a5a6c4d434973496d39696169493657317437496d686c6157646f64434936496a77394f444177496977696347463061434936496c77765a6c7776596d4e6c4e6a466a4d6d51745a6a41345a53303059325a6d4c5746694d7a4d744e6a4d324d474a6b5a6d5a6b4e6d55345843396b5a5735366357347a4c5451304e444932596a6b774c574668596a6b744e446b344d7931695a6a67344c574e6d4d6a6b334e5449785a5446684e533577626d63694c434a336157523061434936496a77394d5449344d434a3958563073496d46315a43493657794a31636d343663325679646d6c6a5a5470706257466e5a53357663475679595852706232357a496c31392e68766d452d65424246756e5535455f48416e2d43434c4e4b4131595f444c704530786c5571745459434b34" height="400" width="100%"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;h4 id="user-content-a-simple-windows-form-utility-for-generating-quick-response-messages"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#a-simple-windows-form-utility-for-generating-quick-response-messages"&gt;&lt;b&gt;A simple Windows form utility for generating quick response messages&lt;/b&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;h2 id="user-content-about-"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#about-"&gt;About 🗃&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As IT Support Professionals, we are constantly sending correspondance to various clients and end users
Very rarely do we help only one or two customer groups each day, and because of that fact, it's normal
for us to have to create tailored response messages with contact info specific to that client.&lt;/p&gt;
&lt;br&gt;
&lt;blockquote&gt;
&lt;p&gt;This repository is meant to supplement the &lt;a href="https://medium.com/@erutherford_nullreturn/using-powershell-forms-for-repetitive-tasks-eeef814bee4" rel="nofollow"&gt;Medium article&lt;/a&gt;: &lt;strong&gt;"Using PowerShell Forms for Repetitive Tasks"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;h2 id="user-content-getting-started-"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#getting-started-"&gt;Getting Started 🖥&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The utility was designed as straightforward, custom module meant to be easily imported into a &lt;code&gt;powershell&lt;/code&gt; session
and invoked by the user. In order for this module to be imported, it's important to locate the designated system path
to place this project's inner directory in. The easiest way to find that location is by opening a powershell terminal
and typing the following:&lt;/p&gt;
&lt;div class="highlight highlight-source-powershell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;PS &lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; &lt;span class="pl-smi"&gt;$&lt;span class="pl-c1"&gt;env:&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dedSyn4ps3/response-generator-example"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  PowerShell...Seriously?
&lt;/h2&gt;

&lt;p&gt;Yes, really! I know that many of the excellent articles many of us read each day tend to follow the more flashy, exciting languages that dominate headlines as a result of their growing popularity and expansive use-cases. While that's all well and good, many of us that may work in IT aren't fortunate enough to use many of these new fancy releases in our day to day roles...usually because of this thing called Access Control Lists and Group Policy Objects (that's right, good ol' Active Directory management).&lt;br&gt;
There is a way, however, that many in IT are able to utilize automation and scripting that in most situations is allowed by GPO (depending on your role of course), and that's by utilizing Window's very own powerhouse scripting language, PowerShell!&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;p&gt;For those who may not be all that familiar with what PowerShell is, and just how powerful it can be for developers, here's a brief intro:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PowerShell is a modern command shell that includes the best features of other popular shells. Unlike most shells that only accept and return text, PowerShell accepts and returns .NET objects. The shell includes the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Robust command-line history&lt;/li&gt;
&lt;li&gt;Tab completion and command prediction (See about_PSReadLine)&lt;/li&gt;
&lt;li&gt;Supports command and parameter aliases&lt;/li&gt;
&lt;li&gt;Pipeline for chaining commands&lt;/li&gt;
&lt;li&gt;In-console help system, similar to Unix man pages&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;At its inception, PowerShell was originally developed on and designed to be a better and more feature-rich shell experience for Windows users and system administrators. As the project continued to grow and blossom, a decision was made by Microsoft to develop a cross-platform version of PowerShell and make it open source for the broader community to contribute to...&lt;strong&gt;and thus, PowerShell Core was born!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes this can be slightly confusing to new programmers that are trying to understand the differences between the PowerShell they see built in to their Windows device, and PS Core installs that they see online. It all comes down to the version of .NET that they run on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Windows PowerShell 5.1 is built on top of the .NET Framework v4.5. With the release of PowerShell 6.0, PowerShell became an open source project built on .NET Core 2.0. Moving from the .NET Framework to .NET Core allowed PowerShell to become a cross-platform solution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The project outlined in this article is solely dependent on &lt;strong&gt;Windows PowerShell&lt;/strong&gt;. It will not function if ran on any version of PS Core, regardless of whether you're running it on Windows, macOS, or Linux. If you're wondering why that is exactly, it's due to the fact that the Windows Forms API that we will use is only part of the native .NET Framework included in all recent versions of Windows.&lt;/p&gt;
&lt;h2&gt;
  
  
  Harness the Strength of PowerShell
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The goal of our project is pretty straightforward:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streamline and automate the generation of response emails for customers&lt;/li&gt;
&lt;li&gt;Build a custom PowerShell module to incorporate this functionality&lt;/li&gt;
&lt;li&gt;Create a simple graphical interface using the Forms API to interact with the module&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because this project is merely a starting point for future applications, its structure will be pretty mundane. Even so, it demonstrates a great way for organizing any future module projects.&lt;/p&gt;

&lt;p&gt;We're going to put together a relatively simple &lt;code&gt;ResponseGenerator&lt;/code&gt; UI using .NET Forms via PowerShell. It provides a means of quick email response generation depending on the client ID chosen by the user. The following will be its structure:&lt;/p&gt;

&lt;p&gt;.&lt;br&gt;
├── ResponseCore.ps1&lt;br&gt;
├── ResponseForm.ps1&lt;br&gt;
├── ResponseGenerator.psd1&lt;br&gt;
├── ResponseGenerator.psm1&lt;br&gt;
└── assets&lt;br&gt;
└── coding.ico&lt;/p&gt;
&lt;h2&gt;
  
  
  Building A Module
&lt;/h2&gt;

&lt;p&gt;As I mentioned previously, &lt;strong&gt;the best approach for building our utility is to create a dedicated module for it&lt;/strong&gt;. PowerShell modules are similar in structure to Python package directories and modules in other languages, so they should feel relatively familiar to many of you.&lt;/p&gt;

&lt;p&gt;At their simplest, new modules can be made up of a single file, though in most scenarios they will consist of several files located in a central root directory. One very important factor to keep in mind when building a new module:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The root directory should be named exactly the same as the module file itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To start out, we’ll go ahead and create the module directory and primary declaration file for our utility by running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS &amp;gt; New-Item -Type Directory -Path "ResponseGenerator"
PS &amp;gt; Set-Location -Path ./ResponseGenerator &amp;amp;&amp;amp; New-Item -Type File -Path "ResponseGenerator.psm1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You may have noticed already that the extension of our newly created file is &lt;code&gt;.psm1&lt;/code&gt;. These particular files are the “core” of a PowerShell module, in our case, &lt;strong&gt;ResponseGenerator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It will be the primary entry point of our utility, but will only contain a handful of code. The primary body of our module code will be spread out between two other files, which we will create right now:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS &amp;gt; New-Item -Type File -Path "ResponseForm.ps1" &amp;amp;&amp;amp; New-Item -Type File -Path "ResponseCore.ps1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Don’t worry about creating the psd1 file just yet, we'll get to it soon enough!&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating the Form
&lt;/h2&gt;

&lt;p&gt;Now that we’ve got our core files in place, we can start adding the code needed to generate a nice looking graphical utility!&lt;/p&gt;

&lt;p&gt;The following Gist shows how we declare our callback functions for specific button presses, as well as creating a ComboBox for storing the entire list of contacts to choose from, and a few quick response button shortcuts:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding the Rest
&lt;/h2&gt;

&lt;p&gt;The only thing left to do for our module at this point is to finish adding the remaining core functions and contact info arrays to the other file in our project, &lt;code&gt;ResponseCore.ps1&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


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

&lt;p&gt;Now that all of our utility code is written, the last thing to do to finish our PowerShell module is creating a &lt;code&gt;.psd1&lt;/code&gt; Module Manifest. This file allows developers to add fine-grained details about their module, as well as limit which functions are exported for use in the command line.&lt;/p&gt;

&lt;p&gt;PowerShell provides a handy &lt;code&gt;cmdlet&lt;/code&gt; (pronounced command-let) to generate this for us, which we can pass various arguments to in order to overwrite the default values for important fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New-ModuleManifest `
-Path "$PWD\ResponseGenerator.psd1" `
-Author "dedSyn4ps3" `
-RootModule ResponseGenerator.psm1 `
-Description "This module helps generate response messages"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will create the last piece of our utility! There is a line of code in this manifest that I recommend making a slight adjustment to, however. It’s good practice to not export every single function declared in your module, and by default the manifest generator does just that.&lt;/p&gt;

&lt;p&gt;Simply scroll down a ways until you see the field declaring FunctionsToExport and update it with the primary entry point to our utility, &lt;strong&gt;which we declared previously in the module file&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FunctionsToExport = 'Invoke-ResponseGenerator'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Run It!
&lt;/h2&gt;

&lt;p&gt;And with that, you’ve successfully put together a PowerShell module that can be imported and run from the command line! When it comes to custom modules, &lt;strong&gt;it’s extremely convenient to be able to call it from our shell without having to specify the actual location path of the module directory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to import and run our utility by name, it’s imperative that the module directory be placed in the designated location for all PowerShell modules for your user! This may very from system to system, so to be sure, simply type the following in your shell to find out the exact location to place the new module:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS &amp;gt; $env:PSModulePath
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With the module directory placed where it needs to go, importing and calling the main entry point is as simple as invoking any other command from our shell:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# import the custom module
PS &amp;gt; Import-Module ResponseGenerator

# start the utility by calling it's invoke method
PS &amp;gt; Invoke-ResponseGenerator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vU8WpKQa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0rrhr0exqjl20xuqlac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vU8WpKQa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0rrhr0exqjl20xuqlac.png" alt="Tip" width="586" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9vBT9sE4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9gvqnomstygl13htndb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9vBT9sE4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9gvqnomstygl13htndb.png" alt="The End Result" width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Code
&lt;/h2&gt;

&lt;p&gt;The entire project repository can be found on Github, and I highly encourage those looking for a great way to kickstart their PowerShell automation to check it out!&lt;/p&gt;

&lt;p&gt;Also be sure to give me a like if you found this article interesting, and be sure to subscribe for upcoming articles! And if you're on Medium as well, &lt;a href="https://medium.com/@erutherford_nullreturn"&gt;check me out there&lt;/a&gt; for early viewing! ✨&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dedSyn4ps3"&gt;
        dedSyn4ps3
      &lt;/a&gt; / &lt;a href="https://github.com/dedSyn4ps3/response-generator-example"&gt;
        response-generator-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1 id="user-content-response-generator"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#response-generator"&gt;Response Generator&lt;/a&gt;&lt;/h1&gt;
&lt;br&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/57aba7606717cb122d183f127a6357dd2ff664d6238882f3d055e25702059aba/68747470733a2f2f696d616765732d7769786d702d6564333061383662386334636138383737373335393463322e7769786d702e636f6d2f662f62636536316332642d663038652d346366662d616233332d3633363062646666643665382f64656e7a716e332d34343432366239302d616162392d343938332d626638382d6366323937353231653161352e706e672f76312f66696c6c2f775f313238302c685f3830302c737472702f6461726b6d7973745f706f7765727368656c6c5f77616c6c70617065725f5f3235363078313630305f5f62795f626173746172646f70657261746f725f64656e7a716e332d66756c6c766965772e706e673f746f6b656e3d65794a30655841694f694a4b563151694c434a68624763694f694a49557a49314e694a392e65794a7a645749694f694a31636d3436595842774f6a646c4d4751784f4467354f4449794e6a517a4e7a4e684e5759775a4451784e5756684d4751794e6d55774969776961584e7a496a6f6964584a754f6d467763446f335a54426b4d5467344f5467794d6a59304d7a637a5954566d4d4751304d54566c5954426b4d6a5a6c4d434973496d39696169493657317437496d686c6157646f64434936496a77394f444177496977696347463061434936496c77765a6c7776596d4e6c4e6a466a4d6d51745a6a41345a53303059325a6d4c5746694d7a4d744e6a4d324d474a6b5a6d5a6b4e6d55345843396b5a5735366357347a4c5451304e444932596a6b774c574668596a6b744e446b344d7931695a6a67344c574e6d4d6a6b334e5449785a5446684e533577626d63694c434a336157523061434936496a77394d5449344d434a3958563073496d46315a43493657794a31636d343663325679646d6c6a5a5470706257466e5a53357663475679595852706232357a496c31392e68766d452d65424246756e5535455f48416e2d43434c4e4b4131595f444c704530786c5571745459434b34"&gt;&lt;img src="https://camo.githubusercontent.com/57aba7606717cb122d183f127a6357dd2ff664d6238882f3d055e25702059aba/68747470733a2f2f696d616765732d7769786d702d6564333061383662386334636138383737373335393463322e7769786d702e636f6d2f662f62636536316332642d663038652d346366662d616233332d3633363062646666643665382f64656e7a716e332d34343432366239302d616162392d343938332d626638382d6366323937353231653161352e706e672f76312f66696c6c2f775f313238302c685f3830302c737472702f6461726b6d7973745f706f7765727368656c6c5f77616c6c70617065725f5f3235363078313630305f5f62795f626173746172646f70657261746f725f64656e7a716e332d66756c6c766965772e706e673f746f6b656e3d65794a30655841694f694a4b563151694c434a68624763694f694a49557a49314e694a392e65794a7a645749694f694a31636d3436595842774f6a646c4d4751784f4467354f4449794e6a517a4e7a4e684e5759775a4451784e5756684d4751794e6d55774969776961584e7a496a6f6964584a754f6d467763446f335a54426b4d5467344f5467794d6a59304d7a637a5954566d4d4751304d54566c5954426b4d6a5a6c4d434973496d39696169493657317437496d686c6157646f64434936496a77394f444177496977696347463061434936496c77765a6c7776596d4e6c4e6a466a4d6d51745a6a41345a53303059325a6d4c5746694d7a4d744e6a4d324d474a6b5a6d5a6b4e6d55345843396b5a5735366357347a4c5451304e444932596a6b774c574668596a6b744e446b344d7931695a6a67344c574e6d4d6a6b334e5449785a5446684e533577626d63694c434a336157523061434936496a77394d5449344d434a3958563073496d46315a43493657794a31636d343663325679646d6c6a5a5470706257466e5a53357663475679595852706232357a496c31392e68766d452d65424246756e5535455f48416e2d43434c4e4b4131595f444c704530786c5571745459434b34" height="400" width="100%"&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;div&gt;
  &lt;h4 id="user-content-a-simple-windows-form-utility-for-generating-quick-response-messages"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#a-simple-windows-form-utility-for-generating-quick-response-messages"&gt;&lt;b&gt;A simple Windows form utility for generating quick response messages&lt;/b&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;/div&gt;



&lt;h2 id="user-content-about-"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#about-"&gt;About 🗃&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;As IT Support Professionals, we are constantly sending correspondance to various clients and end users
Very rarely do we help only one or two customer groups each day, and because of that fact, it's normal
for us to have to create tailored response messages with contact info specific to that client.&lt;/p&gt;
&lt;br&gt;
&lt;blockquote&gt;
&lt;p&gt;This repository is meant to supplement the &lt;a href="https://medium.com/@erutherford_nullreturn/using-powershell-forms-for-repetitive-tasks-eeef814bee4" rel="nofollow"&gt;Medium article&lt;/a&gt;: &lt;strong&gt;"Using PowerShell Forms for Repetitive Tasks"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;h2 id="user-content-getting-started-"&gt;&lt;a class="heading-link" href="https://github.com/dedSyn4ps3/response-generator-example#getting-started-"&gt;Getting Started 🖥&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The utility was designed as straightforward, custom module meant to be easily imported into a &lt;code&gt;powershell&lt;/code&gt; session
and invoked by the user. In order for this module to be imported, it's important to locate the designated system path
to place this project's inner directory in. The easiest way to find that location is by opening a powershell terminal
and typing the following:&lt;/p&gt;
&lt;div class="highlight highlight-source-powershell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;PS &lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; &lt;span class="pl-smi"&gt;$&lt;span class="pl-c1"&gt;env:&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dedSyn4ps3/response-generator-example"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>powershell</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Custom theming for React Native Applications</title>
      <dc:creator>Ed Rutherford</dc:creator>
      <pubDate>Mon, 26 Dec 2022 03:40:31 +0000</pubDate>
      <link>https://dev.to/dedsyn4ps3/custom-theming-for-react-native-applications-2bem</link>
      <guid>https://dev.to/dedsyn4ps3/custom-theming-for-react-native-applications-2bem</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR&lt;br&gt;
If you prefer to dive straight into some code or follow along using project files, head over to the Github repo for this article and clone it to test and make your own changes!&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dedSyn4ps3" rel="noopener noreferrer"&gt;
        dedSyn4ps3
      &lt;/a&gt; / &lt;a href="https://github.com/dedSyn4ps3/react-native-theming" rel="noopener noreferrer"&gt;
        react-native-theming
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;React Native Theming&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://reactjs.org/docs/getting-started.html" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f70f5828cb41ce69290f947a528beff4d0a0119d3140e382e296bf6e8432dae5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72656163742d7631382e302e302d696e666f726d6174696f6e616c" alt="React Version"&gt;&lt;/a&gt;
&lt;a href="https://reactnative.dev" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bb9746a9907bcfd1f46755e43721881d91b2758f3e44419771349f9f94b6739c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72656163745f6e61746976652d76302e36392e362d73756363657373" alt="React Native Version"&gt;&lt;/a&gt;
&lt;a href="https://www.expo.io" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2b7ef89a1757d5b7b16564f999d34d51033a52d68870859cab307361866fdff6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6578706f2d7634362e302e31362d707572706c65" alt="Expo Version"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;br&gt;
&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/dedSyn4ps3/react-native-theming/raw/main/screenshots/banner.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FdedSyn4ps3%2Freact-native-theming%2Fraw%2Fmain%2Fscreenshots%2Fbanner.png"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;blockquote&gt;
&lt;p&gt;This repo is meant to hold the code files for the Medium article &lt;a href="https://medium.com/@erutherford_nullreturn/hail-to-the-theme-919de887120e" rel="nofollow noopener noreferrer"&gt;Hail to the Theme&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;



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

&lt;p&gt;This is a demo application that utilizes the Expo framework to create a React Native-based mobile app capable of switching between custom &lt;em&gt;light&lt;/em&gt; and &lt;em&gt;dark&lt;/em&gt; color palettes depending on the host device settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The application makes use primarily of customized components offered by the awesome React Native Paper and React Navigation frameworks&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;You can create your own custom &lt;em&gt;Material UI&lt;/em&gt; color palettes by going to &lt;code&gt;react-native-paper&lt;/code&gt;'s theme generator &lt;a href="https://callstack.github.io/react-native-paper/theming.html" rel="nofollow noopener noreferrer"&gt;page&lt;/a&gt;.&lt;/p&gt;



&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/dedSyn4ps3/react-native-theming/raw/main/screenshots/theme-generator.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FdedSyn4ps3%2Freact-native-theming%2Fraw%2Fmain%2Fscreenshots%2Ftheme-generator.png"&gt;&lt;/a&gt;
&lt;/div&gt; 

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Live Development&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;To run in live development mode, run &lt;code&gt;npx expo start&lt;/code&gt; in the project root directory. This will start an interactive command line utility allowing you choose which device to run your app on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test on a physical device using the &lt;code&gt;Expo Go&lt;/code&gt; mobile app (scan the QR for easy setup)&lt;/li&gt;
&lt;li&gt;Run on an Android emulator…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dedSyn4ps3/react-native-theming" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  A Brief Introduction
&lt;/h3&gt;

&lt;p&gt;Love them or hate theme, themes are all around us! Our operating systems provide custom theme options (some more than others), many popular web browsers allow for installing custom theme extensions…and of course, so do our mobile phones!&lt;/p&gt;

&lt;p&gt;While mobile device theming may be a bit more limited than the other avenues mentioned above, there’s still the underlying commonality between both iOS and Android of now providing Light and Dark themes for core applications.&lt;/p&gt;

&lt;p&gt;Before we dive into coding our app, it’s important to explain the means in which we do it! The example application used for this article will be written almost exclusively in JavaScript…more specifically Extended JavaScript (or JSX). This may come as a shock to those new to cross-platform development, who typically think of Java and Swift as being the only way to build a mobile app. It’s true, both Java/Kotlin as well as Swift/Objective-C are primary languages used to build mobile applications for Android and iOS respectively…but they aren’t the only way!&lt;/p&gt;
&lt;h3&gt;
  
  
  Enter React Native
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;React Native combines the best parts of native development with React, a best-in-class JavaScript library for building user interfaces…&lt;br&gt;
…Create platform-specific versions of components so a single codebase can share code across platforms. With React Native, one team can maintain two platforms and share a common technology — React.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By using React Native, we’ll be able to take advantage of the power and flexibility offered by React, and also have the ability to re-use custom components to build mobile apps that can be run on both Android and iOS…all with the same code base!&lt;/p&gt;

&lt;p&gt;To get our project set up, we’ll be using the outstanding Expo framework and its CLI (command line interface). Expo has become one of the most widely used tools for mobile development with react native, not just because of how simple it makes getting a project started, but also for the wealth of libraries it offers to customize the look and functionality of your app!&lt;/p&gt;

&lt;p&gt;It’s important to make sure we have the following system requirements installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js LTS Release (using the LTS specific release is important)&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Watchman (for Linux/macOS systems)&lt;/li&gt;
&lt;li&gt;Yarn (not required, but recommended by Expo)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open up your favorite terminal application or PowerShell, and navigate to where you plan to create your project directory. Once there, run the following to create a new expo project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-expo-app example-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;example-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


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

&lt;p&gt;Alright, let’s get to the good stuff! Now that we have our basic setup, we’ll go ahead and create some components to put together in a small example app to look at how theming can be utilized in a straightforward way. The application will represent a store shopping list app, which adjusts its component theming based on whether the user’s device is set to light or dark mode.&lt;/p&gt;

&lt;p&gt;The first and arguably most important step for us is to create a set of colors to use for our app’s theme. This project utilizes an awesome React Native framework react-native-paper. It will provide the key components used for building our UI. A great feature that can be found on their website is a generator for Material UI themes based on a provided primary color:&lt;/p&gt;

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

&lt;p&gt;This fantastic tool not only takes the hard work out of creating proper light and dark color palette objects, but also follows the &lt;em&gt;&lt;strong&gt;Material Design&lt;/strong&gt;&lt;/em&gt; guidelines that all new versions of Android follow…allowing our app to effectively feel and look like any other natively built application!&lt;/p&gt;

&lt;p&gt;If you haven’t done so already, make sure to add the following dependencies to your &lt;code&gt;package.json&lt;/code&gt; to get all the magic installed:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/expo/AppEntry.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"android"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start --android"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ios"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start --ios"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"web"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start --web"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@react-navigation/bottom-tabs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^6.4.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@react-navigation/native"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^6.0.13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~46.0.16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expo-app-loading"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~2.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expo-font"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~10.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expo-status-bar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~1.4.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expo-system-ui"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~1.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-native"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.69.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-native-gesture-handler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~2.5.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-native-paper"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.0.0-rc.8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-native-reanimated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~2.9.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-native-safe-area-context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.3.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-native-screens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~3.15.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-native-svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12.3.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@babel/core"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.12.9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@babel/plugin-proposal-decorators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.20.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To use the theme objects we previously created, go ahead and open your project's &lt;code&gt;App.js&lt;/code&gt; file and add them, as well as the other import statements for &lt;code&gt;expo&lt;/code&gt; and &lt;code&gt;react-native-paper&lt;/code&gt; :&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The above gist is where all the theming magic happens in our app! We declare our theme objects using the color palette values generated by &lt;code&gt;react-native-paper&lt;/code&gt;. Expo provides an API for adjusting the top status bar color depending on whether the device is set to dark or light mode, so we make sure to include that as well. The other important piece of this code involves the use of the &lt;code&gt;useColorScheme&lt;/code&gt; hook when defining our two theme providers. This will allow our themes to be passed down and accessed by all child components in the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speaking of Components
&lt;/h3&gt;

&lt;p&gt;You may have noticed a particular import statement in the code above adding a &lt;code&gt;MainNavigator&lt;/code&gt; component. This is where the primary navigation functionality of our app resides, and makes use of another powerful and appropriately named &lt;code&gt;react-navigation&lt;/code&gt; framework to do so. Before we take a look at our Navigator, let’s throw together a couple smaller components to incorporate in our UI:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With our component files defined, we can now go ahead and import them into our MainNavigator file, along with the navigation components provided by react-navigation :&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If you paid close attention, you may have noticed the key line(s) of code that allow us to apply our custom theme colors to the app’s components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ..., useTheme, ... } from 'react-native-paper';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It’s this &lt;code&gt;useTheme&lt;/code&gt; hook that allows us to access the custom theme objects passed down from the very top of our application. All that’s required to use these colors is calling the hook and storing the return value inside a variable, like in our &lt;code&gt;PrimaryScreen&lt;/code&gt; component:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;To run our new project in live development mode, run npx expo start in the project root directory. This will start an interactive command line utility allowing you choose which device to test your app on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test on a physical device using the Expo Go mobile app (scan the QR for easy setup)&lt;/li&gt;
&lt;li&gt;Run on an Android emulator (using Android Studio)&lt;/li&gt;
&lt;li&gt;Run on iOS emulator device (using Xcode)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The process of implementing custom themes can seem rather daunting at first for many developers, including myself. &lt;strong&gt;With the help of some amazing frameworks, however, it can be accomplished (&lt;em&gt;relatively&lt;/em&gt;) painlessly!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
  </channel>
</rss>
