<?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: Pluralsight</title>
    <description>The latest articles on DEV Community by Pluralsight (@pluralsight).</description>
    <link>https://dev.to/pluralsight</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%2Forganization%2Fprofile_image%2F953%2Fb41d3128-3536-43b5-9fe4-92393b3eea45.jpg</url>
      <title>DEV Community: Pluralsight</title>
      <link>https://dev.to/pluralsight</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pluralsight"/>
    <language>en</language>
    <item>
      <title>The newest must-have developer tool is ChatGPT</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Fri, 17 Mar 2023 17:10:32 +0000</pubDate>
      <link>https://dev.to/pluralsight/the-newest-must-have-developer-tool-is-chatgpt-3gng</link>
      <guid>https://dev.to/pluralsight/the-newest-must-have-developer-tool-is-chatgpt-3gng</guid>
      <description>&lt;h2&gt;
  
  
  &lt;em&gt;Rather watch this as a video? &lt;a href="https://youtu.be/PsIhcpzwf7U" rel="noopener noreferrer"&gt;Click here to view&lt;/a&gt;&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;You might be thinking: another article about ChatGPT? Really?&lt;/p&gt;

&lt;p&gt;There's been no shortage of press dedicated to this tool, but let's get specific. Let's talk about how you can use it as a software developer.&lt;/p&gt;

&lt;p&gt;I've been using this tool since its release. The output has been outstanding. It has made &lt;em&gt;me better at software development&lt;/em&gt;. That's right, this tool has improved my work tremendously. Is it because now I generate all my code with ChatGPT and work 10x faster?&lt;/p&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;But it has made me more productive. So I will share some tips with you that will help you learn more and leverage this tool for your software work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ChatGPT?
&lt;/h2&gt;

&lt;p&gt;Generative Pre-trained Transformer 3, or GPT-3, is a language processing model developed by &lt;a href="https://openai.com" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;. ChatGPT is a GPT model trained on &lt;em&gt;conversational data&lt;/em&gt;. It's designed to be a hyper-intelligent chat bot. It uses articles, research papers, books, documentation, and more to predict answers to questions. We'll get into that a bit more.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://chat.openai.com/chat" rel="noopener noreferrer"&gt;try out ChatGPT here&lt;/a&gt; for free.&lt;/p&gt;

&lt;p&gt;If you're wondering what all the hype is about, you can sign up and immediately use it through an easy-to-use chat interface:&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%2Fo92hfdi6pevt8vgl30bu.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%2Fo92hfdi6pevt8vgl30bu.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No, I didn't use ChatGPT to write this article. It's written by a human being (this time). However, I did have &lt;a href="https://www.youtube.com/watch?v=Rt7CuhFv8xM" rel="noopener noreferrer"&gt;ChatGPT write an application for me&lt;/a&gt; the other day. I'm impressed.&lt;/p&gt;

&lt;p&gt;If you want to learn more about ChatGPT and how it works, check out &lt;a href="https://www.pluralsight.com/library/courses/chatgpt-generative-ai-big-picture/table-of-contents?utm_source=allhandsontech&amp;amp;utm_medium=organic-web&amp;amp;utm_campaign=allhandsontech" rel="noopener noreferrer"&gt;this awesome course on ChatGPT&lt;/a&gt; by Amber Israelsen. It covers what you need to know to understand and use it better.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;You've probably heard about people using ChatGPT to generate content, rewrite their bios, or come up with catchy names for a company. It's great at that. Many folks have been using it as a supercharged search engine.&lt;/p&gt;

&lt;p&gt;ChatGPT thinks like a person and speaks like a machine. It learns from words and predicts the next word or set of words. This is an important distinction because many think it is a giant database, or "Google on steroids." It's not. It's a much different tool for another purpose: predicting text.&lt;/p&gt;

&lt;p&gt;Put simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ChatGPT doesn't do an internet search for answers; It predicts Answers based on its training data - Amber Israelsen&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's great news for you as a developer. If you're searching for the meaning of an error message, Google and Stack Overflow are still your best bet. However, if you want to know, "what's a better way to write this?" ChatGPT is the tool to use. Let's explore that deeper.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it as a developer
&lt;/h2&gt;

&lt;p&gt;You can extract valuable information from ChatGPT using prompt engineering. Asking the tool what you want from it can be tricky, but changing the questions will improve your answer. Let's look at some prompts we can use to improve our code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 1: What's a better way to do this?
&lt;/h3&gt;

&lt;p&gt;This is one of my favorite prompts, so I'm listing it first.&lt;/p&gt;

&lt;p&gt;After a few years, you're dusting off your C# skills and are writing an application. You create a vehicle class with a few properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Vehicle
{
    private int _numberOfWheels;
    private string _typeOfCar;
    private string _color;

    public int NumberOfWheels
    {
        get
        {
            return _numberOfWheels;
        }
        set
        {
            _numberOfWheels = value;
        }
    }

    public string TypeOfCar
    {
        get
        {
            return _typeOfCar;
        }
        set
        {
            _typeOfCar = value;
        }
    }

    public string Color
    {
        get
        {
            return _color;
        }
        set
        {
            _color = value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is this valid code? Sure. It uses getters and setters, and you can implement data protection on your properties. It will compile and work just fine.&lt;/p&gt;

&lt;p&gt;However, this isn't how we implement properties in C# anymore. But you have no way of knowing that, especially if you haven't written C# since version 3.0.&lt;/p&gt;

&lt;p&gt;So out of curiousity, you go into ChatGPT and paste in 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;What's a better way to write this class? &amp;lt;insert code here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ChatGPT takes this prompt and spits out the following:&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%2Fo6oxi4e9nydz98gd0w52.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%2Fo6oxi4e9nydz98gd0w52.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only does it tell you about auto-implemented properties, but it tells you &lt;em&gt;why you should use this suggestion&lt;/em&gt;. Now you know that you can perform the same thing that 41 lines of code used to do in just six lines of code. It tells you why that's important. You just learned something.&lt;/p&gt;

&lt;p&gt;Let's look at another example.&lt;/p&gt;

&lt;p&gt;You have an array of data in Python that you'd like to iterate through. You write the following code to do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my_array = [1, 2, 3, 4, 5]

for i in range(len(my_array)):
    print("The value at index", i, "is", my_array[i])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Does it work? Yes. It makes sense, and it is pretty concise. But is there a better way?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What's a better way to write this &amp;lt;insert code here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ChatGPT returns this:&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%2Fuzu3359eby87q32yy1yk.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%2Fuzu3359eby87q32yy1yk.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While less drastic than the first example, you just learned a new way to do something and why it matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 2: How do I (do something)
&lt;/h3&gt;

&lt;p&gt;This is yet another way to use ChatGPT. However, there is a caveat attached. You can always ask it how to do something:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;how do I connect to postgresql with php?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fghmtki90sm7p1n6jd9zg.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%2Fghmtki90sm7p1n6jd9zg.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And for many common things, it will usually spit out an answer that's correct.&lt;/p&gt;

&lt;p&gt;You can have it generate a variety of great boilerplate code for various tasks.&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%2F0h90664jw2pwzy3ito10.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%2F0h90664jw2pwzy3ito10.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only will it write the code for you, but it will explain the reasoning behind 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%2Fxddkw0vmr0kdag7uscuy.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%2Fxddkw0vmr0kdag7uscuy.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This can be incredible if it's a concept you are unfamiliar with. ChatGPT can generate things like this much faster than a Google query.&lt;/p&gt;

&lt;p&gt;As I said earlier, I pretended to know nothing about Go, JavaScript, and HTML and &lt;a href="https://www.youtube.com/watch?v=Rt7CuhFv8xM" rel="noopener noreferrer"&gt;created an entire web application with ChatGPT&lt;/a&gt;. Even if I knew little about these technologies, I could assemble an application using ChatGPT as the primary resource.&lt;/p&gt;

&lt;p&gt;But what's the caveat I mentioned earlier?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You must understand the code you are generating.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can't stress this enough. Don't blindly say, "how do I do this" and dump the code into your application. Generate the code, study it, and understand it. You can also use ChatGPT for this, as we'll see with the next prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 3: How does (this) work in the code you just generated?
&lt;/h3&gt;

&lt;p&gt;You can dig deeper into what ChatGPT generates with this prompt. ChatGPT keeps a conversational context by bundling your queries in a single conversation. That means you can keep iterating on the results, just like in a real conversation with a human.&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%2Fzddccvgqkjoxcvqzotds.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%2Fzddccvgqkjoxcvqzotds.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives you a deeper explanation of how things work before you use them.&lt;/p&gt;

&lt;p&gt;This is one example of how ChatGPT has made me a better developer. I have gone down some rabbit holes for sure and gained a deeper understanding of the things I'm working on. I suggest doing this. Especially if you are generating code you don't fully understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 4: Rewrite this code with syntactic sugar
&lt;/h3&gt;

&lt;p&gt;This is another one of my favorites. If you don't know, Syntactic sugar is programming language syntax that is concise and (sometimes) easier to read and express. It's not for everyone, but I like it, especially when it de-clutters my code.&lt;/p&gt;

&lt;p&gt;Let's take this example in C#:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;nullableValue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nullableValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nullableValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, we're looking for values that may be null, and if they are, we'll assign them a value of 0. If they have a value stored, we'll pass that value.&lt;/p&gt;

&lt;p&gt;Pretty straightforward, right? But one look at this code tells you there's a shorter way to do this. So we'll ask ChatGPT:&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%2Fg6xf6dyzeat7cnmlyoq8.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%2Fg6xf6dyzeat7cnmlyoq8.png" alt="How to use ChatGPT for Software Development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we get this, which is much better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int value = nullableValue ?? 0;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is yet another way ChatGPT can teach you and help you be a better programmer. Keep in mind this isn't bulletproof. I have seen some code generated using this that didn't work as expected. But it's pretty cool when it does!&lt;/p&gt;

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

&lt;p&gt;ChatGPT is cool and a lot of fun to play with. However, it can also be a useful tool to improve productivity, as we've shown. It can teach you new ways to write code.&lt;/p&gt;

&lt;p&gt;We didn't cover some of the other ways it helps, such as generating documentation, providing answers to support questions, and more. I'll share a follow-up article to this, so keep checking back.&lt;/p&gt;

&lt;p&gt;It might sound like a dumb fad, but it isn't. From here forward, developers need to learn this tool. This is a significant turning point for software development, and I can only see it improving.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pluralsight.com/library/courses/chatgpt-generative-ai-big-picture/table-of-contents?utm_source=allhandsontech&amp;amp;utm_medium=organic-web&amp;amp;utm_campaign=allhandsontech" rel="noopener noreferrer"&gt;Check out this great course&lt;/a&gt; if you'd like to learn more about ChatGPT.&lt;/p&gt;




&lt;p&gt;Questions, comments? &lt;a href="https://www.twitter.com/JeremyCMorgan" rel="noopener noreferrer"&gt;Let me know!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>ai</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Building a QR Code Generator with Azure Functions</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Fri, 27 May 2022 18:34:33 +0000</pubDate>
      <link>https://dev.to/pluralsight/building-a-qr-code-generator-with-azure-functions-2fi3</link>
      <guid>https://dev.to/pluralsight/building-a-qr-code-generator-with-azure-functions-2fi3</guid>
      <description>&lt;p&gt;Here's a fun project if you want to learn how to build &lt;a href="https://bit.ly/383UrOi"&gt;Azure Functions&lt;/a&gt;. This project is going to be a little silly but educational.&lt;/p&gt;

&lt;p&gt;We will build a QR Code Generator that runs 100% within an Azure function. There are thousands of QR Code generators on the internet, so this is a silly exercise, but I wanted to push the limits of what an Azure Function can do, show you how cool they are, and inspire you to build cool stuff with them.&lt;/p&gt;

&lt;p&gt;If you'd rather watch a video, we have it here:&lt;/p&gt;

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

&lt;h3&gt;
  
  
  In this tutorial, you will learn:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How Azure Functions work and how simple they are&lt;/li&gt;
&lt;li&gt;How to generate QR codes with .NET libraries&lt;/li&gt;
&lt;li&gt;How little effort is required to build something like this&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It'll be fun, and I hope you follow along. What we'll do in this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an Azure Function&lt;/li&gt;
&lt;li&gt;Implement a QR generator&lt;/li&gt;
&lt;li&gt;Build a crude frontend for it&lt;/li&gt;
&lt;li&gt;deploy it to Azure with Azure Functions Core Tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end of this tutorial, you'll have a functional QR code generator, and it may inspire you to build more cool things with Azure Functions. They are compact, simple, and easy to build.&lt;/p&gt;

&lt;p&gt;You can find the full &lt;a href="https://github.com/JeremyMorgan/QRCode-Generator-Azure-Function"&gt;source code to this project here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Azure Function?
&lt;/h2&gt;

&lt;p&gt;Azure Functions are serverless applications that run in Azure. They're small bits of code you can execute without a server or complicated instance. Most Azure Functions are "microservices" that do one small task and do it well.&lt;/p&gt;

&lt;p&gt;Azure Functions can also respond to HTTP triggers to act as a sort of "mini API." They respond to HTTP requests just like a Web API would, but it takes much less setup with functions.&lt;/p&gt;

&lt;p&gt;I'm starting to sound like an advertisement, but it is awesome. Years ago, this same project required you to set up a server or set up an ASP.NET Web API on an IIS server somewhere. Now we can do it in a few lines of code and push it to the cloud. Azure Functions allow you to focus on building cool stuff instead of all that setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Here's what you'll need for this tutorial. I'll build this in Windows 11, but we're not using Visual Studio. I'll use the &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/#driver"&gt;dotnet driver&lt;/a&gt; for this, so you can replicate it on Mac or OSX if you'd like. You will have to have this (free) software installed on your machine.&lt;/p&gt;

&lt;p&gt;You will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://azure.microsoft.com"&gt;Microsoft Azure&lt;/a&gt; Account&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dotnet.microsoft.com/en-us/download/visual-studio-sdks"&gt;.NET 6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash"&gt;Azure Functions Core Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"&gt;Azure CLI Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/download"&gt;Visual Studio Code&lt;/a&gt; (or editor of your choice)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a new Project
&lt;/h2&gt;

&lt;p&gt;We're going to use the Azure CLI to create a new Azure function for us, and we'll use the dotnet driver to install software.&lt;/p&gt;

&lt;p&gt;Visual Studio can automate this for us, but doing it this way gives a better view of the steps involved and can be done on many platforms.&lt;/p&gt;

&lt;p&gt;First, we'll initialize a new function. We'll use the &lt;code&gt;func&lt;/code&gt; command to create a new project named QRCodeGen. We'll specify the worker runtime as "dotnet" to choose C# as the language used.&lt;/p&gt;

&lt;p&gt;Run this command in your project or repositories folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func init QRCodeGen --worker-runtime dotnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look in the folder, there isn't much here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OZO34hc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5n3nwy0kgxt0t64w5ttk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OZO34hc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5n3nwy0kgxt0t64w5ttk.png" alt='"How to build Azure Functions"' width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We still need to create an Azure Function within the project. Azure Functions have a set of templates, depending on what type of application you're making. We want to create an HTTP trigger, a function that responds to an HTTP request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func new --template "Http Trigger" --name QRCodeGen --authlevel anonymous
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9bXQb_V1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfl1m1hjnei0vlzbarxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9bXQb_V1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfl1m1hjnei0vlzbarxy.png" alt='"How to build Azure Functions"' width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're using Visual Studio Code, you may see this message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SjzHU5wi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djwvjea9uo7mxyjz1agd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SjzHU5wi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djwvjea9uo7mxyjz1agd.png" alt='"How to build Azure Functions"' width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select yes to install the extensions.&lt;/p&gt;

&lt;p&gt;Now you will see a sample function that &lt;code&gt;func&lt;/code&gt; created for you:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5HYfN_CV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jg4yg2xlqrhnqguup03c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5HYfN_CV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jg4yg2xlqrhnqguup03c.png" alt='"How to build Azure Functions"' width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can run it locally if you want to try it out. Type in&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You will then see the function startup, and the console will give you some guidance on how to use the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--09xvMeIY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nu9pa333g20ctb4zkikk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--09xvMeIY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nu9pa333g20ctb4zkikk.png" alt='"How to build Azure Functions"' width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, we can either send a &lt;strong&gt;GET&lt;/strong&gt; or a &lt;strong&gt;POST&lt;/strong&gt; to &lt;code&gt;http://localhost:7071/api/QRCodeGen&lt;/code&gt;. Let's load it up in a browser and see what a simple GET returns:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k9D07HK0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdcajlss8mlc7vsbd1t5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k9D07HK0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdcajlss8mlc7vsbd1t5.png" alt='"How to build Azure Functions"' width="800" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a message showing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This HTTP triggered function was executed successfully. Pass a name in the query string or in the request body for a personalized response.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok cool. Let's dig into the code and see what this message means.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;responseMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$"Hello, &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. This HTTP triggered function executed successfully."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the code above, it's doing a check for a value in &lt;code&gt;name&lt;/code&gt;. If that variable is empty or null, it will display the message we just saw.&lt;/p&gt;

&lt;p&gt;But how do we populate that value? A few lines up, we see a parameter in the query that we can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will display a message with the name included if it's populated. We need to send it a URL with the &lt;code&gt;name&lt;/code&gt; as a parameter like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:7071/api/QRCodeGen?name=Jeremy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's try that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ENgrAERu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b920glzslarvy5nubiaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ENgrAERu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b920glzslarvy5nubiaz.png" alt='"How to build Azure Functions"' width="800" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there's my message. So now we know the function is working as expected. We load up a URL, get the parameter and modify the output.&lt;/p&gt;

&lt;p&gt;For simplicity, we'll use this model for our QR code generator. We'll establish our URL to listen for requests, and pass the value in a GET command, then return a QR code. Let's start with generating that QR Code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install QRCode Generation tools
&lt;/h2&gt;

&lt;p&gt;Turning text into a QR code is relatively complex. Luckily, you're using .NET. You won't have to build your generator by hand. The problem was solved a long time ago. We will use a library to generate a .PNG QR code for us. We only have to write some code around it and build a tool that solves our problem.&lt;/p&gt;

&lt;p&gt;First, let's install the &lt;a href="https://github.com/manuelbl/QrCodeGenerator"&gt;QRCode Generator&lt;/a&gt; package from Manuel BL. We'll do that using the dotnet driver. I'll specify the latest version at the time of this writing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Net.Codecrete.QrCodeGenerator --version 2.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The QRCode generator works great but can only generate .svgs. Since we want a .PNG (bitmap) format, and want it to work under multiple environments, we need to install the &lt;a href="https://www.nuget.org/packages/SkiaSharp/2.88.0-preview.256"&gt;SkiaSharp package&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package SkiaSharp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SkiaSharp includes the ability to generate bitmaps. But you must download and add this file to your project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/manuelbl/QrCodeGenerator/blob/master/Demo-SkiaSharp/QrCodeBitmapExtensions.cs"&gt;https://github.com/manuelbl/QrCodeGenerator/blob/master/Demo-SkiaSharp/QrCodeBitmapExtensions.cs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a file named QrCodeBitmapExtensions.cs in your project folder and copy the contents of this file to it. This will allow you to work with bitmaps, specifically .PNG files.&lt;/p&gt;

&lt;p&gt;Now we have our QR Code generator tools, so let's make it work in our function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the QR Code Generator Function
&lt;/h2&gt;

&lt;p&gt;If you open up &lt;code&gt;QRCodeGen.cs&lt;/code&gt;, you'll see the Azure Function (a method) generated for us. It will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"QRCodeGen"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthorizationLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anonymous&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C# HTTP trigger function processed a request."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

            &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ReadToEndAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kt"&gt;dynamic&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JsonConvert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeserializeObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;responseMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."&lt;/span&gt;
                &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$"Hello, &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. This HTTP triggered function executed successfully."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;OkObjectResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's delete this method. The only thing you should see in &lt;code&gt;QRCodeGen.cs&lt;/code&gt; is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;QRCodeGen&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QRCodeGen&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's add a new method to generate QR codes.&lt;/p&gt;

&lt;p&gt;First, add in the name decorator. This will give the method a name and change the URL to access it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GenerateQRCode"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we run our app, the URL will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:7071/api/GenerateQRCode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will be the URL we call to generate a QR code, and we'll call it from JavaScript.&lt;/p&gt;

&lt;p&gt;Next, create the method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthorizationLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anonymous&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're creating a method named Generate. We're passing in some parameters to tell the application we want an HttpTrigger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpTrigger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And within that trigger, we are passing some parameters.&lt;/p&gt;

&lt;p&gt;We want to set our authorization to anonymous so that anyone can access it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;AuthorizationLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anonymous&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We only want to accept &lt;code&gt;GET&lt;/code&gt; requests to this URL, so the following parameter specifies that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we'll set our route to null. If we wanted a different URL or particular route, we could specify it here. For simplicity's sake, we'll leave it as it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will pass in an HttpRequest object. This will contain the data from the incoming request so that we can grab parameters from it. When a GET request is sent to our function, we can extract things like headers, parameters, and more.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we'll pass in a logger so we can log messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great now we have the method constructed. Let's fill it out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gathering Info from the Query String.
&lt;/h3&gt;

&lt;p&gt;The user must send the text they want turned into a QR Code. It's usually a URL. We decided early on to keep things simple. We'll just gather this info from the query string sent to the API.&lt;/p&gt;

&lt;p&gt;Remember that HttpRequest we passed into the method? We can get our Query parameter from that. We can establish a string variable and then grab the parameter from the query string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;qrtext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"qrtext"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add in the following message to log our output. We want to display what was sent to our &lt;code&gt;qrtext&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generating QR Code for {0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qrtext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, we can doublecheck what was sent.&lt;/p&gt;

&lt;p&gt;Now, let's generate our QR Code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generating the QR Code to PNG
&lt;/h3&gt;

&lt;p&gt;Next, we want to take our string, encode it into a QR Code, then export that to a PNG.&lt;/p&gt;

&lt;p&gt;So we'll make a static call to the &lt;a href="https://github.com/manuelbl/QrCodeGenerator"&gt;QRCode library&lt;/a&gt; we installed earlier. We'll pass in the text we want to generate and the &lt;a href="https://scanova.io/blog/blog/2018/07/26/qr-code-error-correction/"&gt;error correction&lt;/a&gt; value. Medium should be fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QrCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EncodeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qrtext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QrCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ecc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is all it takes to generate a QR Code. But it's in an SVG format. We need to convert it into a PNG so we can display it.&lt;/p&gt;

&lt;p&gt;Since we added that bitmap extension above, now our &lt;code&gt;qr&lt;/code&gt; object has a method to turn the QR code into a PNG with a few parameters.&lt;/p&gt;

&lt;p&gt;We need to add a scale: I used 10, which seemed to generate a decent size.&lt;/p&gt;

&lt;p&gt;I used 1 for the border.&lt;/p&gt;

&lt;p&gt;And I set the foreground (code) to SKColors.Black, and the background to SKColors.White.&lt;/p&gt;

&lt;p&gt;Here's the code to enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pngout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToPng&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SkiaSharp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SKColors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SkiaSharp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SKColors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;White&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, so now we have our QR Code. That was easy! Now let's package it up in JSON and send it out!&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a JSON Return Object
&lt;/h3&gt;

&lt;p&gt;We've been creating this code within &lt;code&gt;public static class GenerateQRCode&lt;/code&gt;. Let's create another class that will create a simple object we can return when the API is called.&lt;/p&gt;

&lt;p&gt;Just outside of the GenerateQRCode class (before the last } ) create a ReturnObject class.&lt;/p&gt;

&lt;p&gt;This class will have a single property named &lt;code&gt;Image&lt;/code&gt;. This will be a string and we'll encode our PNG as text into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReturnObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now back in the GenerateQRCode class, let's go back to where we were. We'll create a new ReturnObject:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ourResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ReturnObject&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we'll take our PNG image and convert it into a Base64 string, and add that string to our return object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;ourResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pngout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy. Now we'll just return our POCO (Plain old class object) as a new JsonResult, so it returns JSON to the caller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JsonResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ourResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's there is to it. In about seven lines of code, we're taking a string, converting it to a QR code, and shipping it out the door.&lt;/p&gt;

&lt;p&gt;Let's try it out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start up the Function Locally
&lt;/h3&gt;

&lt;p&gt;We will start up the function and have it listening locally. We'll send a GET request with a query to test it out.&lt;/p&gt;

&lt;p&gt;Type the following at the command line:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;To start up the function.&lt;/p&gt;

&lt;p&gt;You should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rMFc1c0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqwn0qt34w5vfomhly30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rMFc1c0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqwn0qt34w5vfomhly30.png" alt='"How to build Azure Functions"' width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we'll send a request to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:7071/api/GenerateQRCode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember the parameter we specified in our code was &lt;code&gt;qrtext&lt;/code&gt;, so I'll add that to the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:7071/api/GenerateQRCode?qrtext="hello world"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm using Postman for this, so I can see the JSON rendered out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N9uRx4Ya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mecpebkpg9jqq05umuui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N9uRx4Ya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mecpebkpg9jqq05umuui.png" alt='"How to build Azure Functions"' width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the bit of logging we did shows that it's rendering for "hello world":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CiVEixwd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcqhdx3qi0gk4rz6hzof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CiVEixwd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcqhdx3qi0gk4rz6hzof.png" alt='"How to build Azure Functions"' width="800" height="38"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the steps are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send a GET to our URL&lt;/li&gt;
&lt;li&gt;Append the text to generate and add it to qrtext&lt;/li&gt;
&lt;li&gt;Accept the JSON.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's all the code we entered so far:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QRCodeGen&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GenerateQRCode"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
       &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GenerateQRCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthorizationLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anonymous&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;qrtext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"qrtext"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
           &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generating QR Code for {0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qrtext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

           &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QrCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EncodeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qrtext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QrCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ecc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
           &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pngout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToPng&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SkiaSharp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SKColors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SkiaSharp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SKColors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;White&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

           &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ourResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ReturnObject&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
           &lt;span class="n"&gt;ourResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pngout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
           &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JsonResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ourResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReturnObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's fantastic, but we're not done. We still need to deploy it. But before we do that, let's build a small, simple JavaScript front end to interact with this function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Front End
&lt;/h2&gt;

&lt;p&gt;We want this QR Code generator to be totally self-contained. While Azure Functions aren't really designed to serve up web pages, it is possible. In this case, we can set this up so we don't need to host our front end somewhere else. It's just a simple webpage so let's serve it up.&lt;/p&gt;

&lt;p&gt;First, we'll create our index.html.&lt;/p&gt;

&lt;p&gt;Create a folder named &lt;code&gt;www&lt;/code&gt; and create a file named &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is going to be a super simple, crude front end—nothing fancy, just enough to get the job done.&lt;/p&gt;

&lt;p&gt;Add in the following at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;h2&amp;gt;QR Code Generator&amp;lt;/h2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is our basic header. Next, we'll need to add an input to get text from the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input id="inputbox" style="width: 250px;" &amp;gt;&amp;lt;/input&amp;gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This input has an id of inputbox, so we can grab this text with JavaScript. I added a couple of line breaks after it to space it out.&lt;/p&gt;

&lt;p&gt;Next, we'll create a button that will call a JavaScript function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button type="button" onclick="GetQRCode()"&amp;gt;Create QR Code&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we'll have a place where we will insert the QR code. Remember this will be Base64 encoded so that we can populate this div with an image in our &lt;code&gt;GetQRCode&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div id="demo"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll put in the &lt;code&gt;GetQRCode&lt;/code&gt; function, which makes an XMLHttpRequest back into our Azure Function and retrieves the JSON. It then parses it and replaces the "demo" div with our image. Note that we're adding an &lt;code&gt;img&lt;/code&gt; tag with the header information so it creates an image we can view in our browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function GetQRCode() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 &amp;amp;&amp;amp; this.status == 200) {
      var ourJSON = JSON.parse(this.responseText);
      document.getElementById("demo").innerHTML = "&amp;lt;img src=\"data:image/png;base64, " + ourJSON.image + "\"&amp;gt;";
    }
  };
  input = document.getElementById('inputbox').value
  xhttp.open("GET", "/api/GenerateQRCode?qrtext=" + input, true);
  xhttp.send();
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! So now we have an index page that will draw up a small UI for our QRCode Generator.&lt;/p&gt;

&lt;p&gt;I know we could add in error correction/handling or use a library for this, but I want to keep it as simple as possible.&lt;/p&gt;

&lt;p&gt;Next, we need to serve this up with our Azure Function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serving the Index Page
&lt;/h2&gt;

&lt;p&gt;Azure Functions are not intended to be web servers. In fact, &lt;a href="https://azure.microsoft.com/en-us/services/app-service/static/"&gt;Azure Static Web Apps&lt;/a&gt; do a much better job, but we're trying to keep this as simple as it can be. One single Azure Function to accomplish this task.&lt;/p&gt;

&lt;p&gt;We can push out the index.html file so it will be served up by a browser. This gives a small interface for our application, and we can go back later and build a complete web app that takes advantage of this function or add it into a bundle of microservices if we like.&lt;/p&gt;

&lt;p&gt;Open up GenerateQRCode.cs again, and at the top of our class (above [FunctionName("Form")]) let's add in another function.&lt;/p&gt;

&lt;p&gt;We want this function to return a HttpResponseMessage this time. We're still going to make this an HttpTrigger, with anonymous authentication, and pass in the same values as before.&lt;/p&gt;

&lt;p&gt;This time though, we need to pass in &lt;code&gt;ExecutionContext context&lt;/code&gt;. This gives us our execution context so we can locate files within the local filesystem, and I'll explain why in a bit.&lt;/p&gt;

&lt;p&gt;Another is this will return HttpResponseMessage instead of an IActionResult.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[FunctionName("Form")]
          public static HttpResponseMessage Form(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
            ILogger log, ExecutionContext context)
        {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we're going to open the &lt;code&gt;index.html&lt;/code&gt; file we put in the &lt;code&gt;www&lt;/code&gt; folder and read it all in as text. This is where the execution context comes from.&lt;/p&gt;

&lt;p&gt;We want to open up the index.html file that lives in the www folder on the filesystem where the application is running. We do that with this line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;indexPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FunctionAppDirectory&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/www/index.html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we'll create a new HttpResponseMessage with status code of OK (200):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpResponseMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll need to add some headers to that, and fill the "content" with the text we read from our index file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MediaTypeHeaderValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ByteArrayContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indexPage&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have a 200 OK message with text/html header, and we have all the text from our index.html added to the content section of the header.&lt;/p&gt;

&lt;p&gt;It's pretty hacky, but it works.&lt;/p&gt;

&lt;p&gt;Then we simply return it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the entire function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Form"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;HttpResponseMessage&lt;/span&gt; &lt;span class="nf"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthorizationLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anonymous&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;indexPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FunctionAppDirectory&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/www/index.html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpResponseMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MediaTypeHeaderValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ByteArrayContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indexPage&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, since we're introducing this outside file (index.html) that will need to be included in the build, we need to add this to our .csproj file.&lt;br&gt;
In an ItemGroup, add in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;None&lt;/span&gt; &lt;span class="na"&gt;Update=&lt;/span&gt;&lt;span class="s"&gt;"www\index.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;CopyToOutputDirectory&amp;gt;&lt;/span&gt;Always&lt;span class="nt"&gt;&amp;lt;/CopyToOutputDirectory&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/None&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added mine in with the other file publishing settings:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l05tsBsK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1ek92gzraxbr3plrls7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l05tsBsK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1ek92gzraxbr3plrls7.png" alt='"How to build Azure Functions"' width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save it, and let's run our Azure Function Locally again:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;And let's see how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing our Front End
&lt;/h2&gt;

&lt;p&gt;Now I have my function up and running locally, so I can just bring up a web browser to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:7071/api/Form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and there it is in all its glory:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L77Xz2kS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwrgjto67sta5clrwecr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L77Xz2kS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwrgjto67sta5clrwecr.png" alt='"How to build Azure Functions"' width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I'll drop in a URL,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---E-PBpIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9f9kz1x82vwnm3bg4vzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---E-PBpIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9f9kz1x82vwnm3bg4vzw.png" alt='"How to build Azure Functions"' width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there's my QR Code, temporarily generated. Awesome!!&lt;/p&gt;

&lt;p&gt;Let's deploy this to Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying our Application
&lt;/h2&gt;

&lt;p&gt;So I'm now calling this an "application" because it is. We've gone beyond the expected functionality of a simple function, just to show how powerful Azure Functions can be. Let's deploy this and see how it works.&lt;/p&gt;

&lt;p&gt;With the Azure CLI, type in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll be directed via a web browser to log into Azure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_jGv0ou4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mhki1os44z951lfdhf3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_jGv0ou4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mhki1os44z951lfdhf3c.png" alt='"How to build Azure Functions"' width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your Azure Console, create a new Azure Function App. You can name this whatever you'd like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B5lNaUmR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhepf3cc4xpouuwwq2yk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B5lNaUmR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhepf3cc4xpouuwwq2yk.png" alt='"How to build Azure Functions"' width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select to publish as code, and use the following Runtime stack. You can choose whatever region you'd like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zmMK7U0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hsz0ogc5omkqybi9p0j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zmMK7U0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hsz0ogc5omkqybi9p0j.png" alt='"How to build Azure Functions"' width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll choose Windows and the Consumption (Serverless) model:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XqhkDcQ2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6rfto2j6rhrh7xbzavrs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XqhkDcQ2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6rfto2j6rhrh7xbzavrs.png" alt='"How to build Azure Functions"' width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll create a new storage account and press "review and create"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WA4ZNF5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iaaqsqy47dgyufy7c6i2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WA4ZNF5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iaaqsqy47dgyufy7c6i2.png" alt='"How to build Azure Functions"' width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make a note of your details:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XWdE3GiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97vl4wy3mwikkrsshu5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XWdE3GiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97vl4wy3mwikkrsshu5h.png" alt='"How to build Azure Functions"' width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to publish with the Azure CLI. We'll do that by using the &lt;code&gt;func&lt;/code&gt; command and specifying that we want to publish an azure functionapp, the name, and we'll put "--nozip" to tell the command we aren't deploying a zip of the application, but rather the source code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func azure functionapp publish qrcodegen --nozip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something like this when it's done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Db1k44fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3er8ee4hb8knsow6l4c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Db1k44fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3er8ee4hb8knsow6l4c.png" alt='"How to build Azure Functions"' width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will need to log into your Azure portal, load up the function app and select "configuration".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X1oqiboQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zar9gkiv8eiusn9fv5iy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X1oqiboQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zar9gkiv8eiusn9fv5iy.png" alt='"How to build Azure Functions"' width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then find &lt;code&gt;WEBSITE_RUN_FROM_PACKAGE&lt;/code&gt; and set the value to &lt;code&gt;0&lt;/code&gt;. This will allow our function to run from the files we've published.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ruQ0mY0D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j4idr76hadhoat6662f3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ruQ0mY0D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j4idr76hadhoat6662f3.png" alt='"How to build Azure Functions"' width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look!&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Application on Azure
&lt;/h2&gt;

&lt;p&gt;After deployment, you should see a screen like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FU33gNGu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k72ey4me1d3vy2m9fnwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FU33gNGu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k72ey4me1d3vy2m9fnwk.png" alt='"How to build Azure Functions"' width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The "Form" URL is the one that will bring up our UI for the function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FYYgQrTq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rojcljv5p0e0ou1mr3qi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FYYgQrTq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rojcljv5p0e0ou1mr3qi.png" alt='"How to build Azure Functions"' width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can punch in your website and create a QR code from it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7HN1aoeZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0f7kk9qawdmx3ah3r964.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7HN1aoeZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0f7kk9qawdmx3ah3r964.png" alt='"How to build Azure Functions"' width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it works!! Our very own QR code generator that runs 100% from an Azure Function.&lt;/p&gt;

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

&lt;p&gt;If you've been following along, thanks for sticking with it! You now have a cool project and a better familiarity with Azure Functions.&lt;/p&gt;

&lt;p&gt;Serving up websites isn't exactly what Azure functions are designed for, but I wanted this to be a complete solution front to back on an Azure Function. No servers, no databases, and you don't have several services to keep track of.&lt;/p&gt;

&lt;p&gt;We learned how Azure Functions work and how simple they can be. We didn't write much code here! We learned how to generate QR codes with .NET libraries, build a mini-application and deploy it to the cloud. I wanted to keep this as simple as possible for a good introduction. If you were building a "real" application, here's what I would recommend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hosting the front end on Azure Static Web Apps or similar service&lt;/li&gt;
&lt;li&gt;Error checking the heck out of the input&lt;/li&gt;
&lt;li&gt;Graceful error handling and logging&lt;/li&gt;
&lt;li&gt;Pushing the images into storage for later retrieval&lt;/li&gt;
&lt;li&gt;Designing the API so that it can be used by other types of applications as well&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this was fun! If you want to learn more about Azure Functions, we have several great courses here at Pluralsight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://bit.ly/383UrOi"&gt;Azure Functions Fundamentals&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://bit.ly/3scZbYM"&gt;Microsoft Azure Developer: Choosing a Storage Solution&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://bit.ly/3w73WEi"&gt;Microsoft Azure Developer: Implement Azure Functions&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
Again here's the video version of this tutorial:&lt;/p&gt;

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

&lt;p&gt;Questions? Comments? &lt;a href="https://www.twitter.com/JeremyCMorgan"&gt;Let me Know!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>dotnet</category>
      <category>azure</category>
    </item>
    <item>
      <title>When Instagram becomes TikTok</title>
      <dc:creator>Silvia Cristina Higareda</dc:creator>
      <pubDate>Mon, 09 May 2022 17:46:28 +0000</pubDate>
      <link>https://dev.to/pluralsight/when-instagram-becomes-tiktok-150e</link>
      <guid>https://dev.to/pluralsight/when-instagram-becomes-tiktok-150e</guid>
      <description>&lt;p&gt;Did you notice the recent changes to the Instagram Feed? Although subtle, they're loudly warning where social platforms are heading. A world of social-first content creation and consumption that keeps people on the platform.&lt;/p&gt;

&lt;p&gt;If you want to geek out with me on what these changes mean and why they matter here are 4 points:&lt;/p&gt;

&lt;p&gt;📱 FULL SCREEN: Social media consumption happens largely on mobile, with the years platforms have expanded the aspect ratios. TikTok went full screen and now Instagram has followed. This was true on IG Reels, but now it's true to the feed as well.&lt;/p&gt;

&lt;p&gt;💡 WHY THIS MATTERS: Content creation will have to be made for mobile or your content will appear so small compared to your competitors, brand awareness and relevance will suffer.&lt;/p&gt;

&lt;p&gt;🔉 SOUND &amp;amp; ENGAGEMENT BUTTONS FRONT AND CENTER: TikTok started it, that sound button you can so easily click, discover new artists, but more importantly... remix and create your own content. This same functionality is there on your feed now.&lt;/p&gt;

&lt;p&gt;💡 WHY THIS MATTERS: Having this sound button readily available is pushing not only toward native consumption but also native creation! This is the button that gave the great Khaby the ability to remix content and curate a 137M following. The platforms want us to create and consume social-first content on their platform. This means traditional ways of content creation will be pushed out.&lt;/p&gt;

&lt;p&gt;💰 PAID ADS: Paid ads on TikTok and now Instagram as well are blending seamlessly into the rest of the organic content. I don't know about you but sometimes, especially on TikTok, it takes me a few seconds to realize it's an ad.&lt;/p&gt;

&lt;p&gt;💡 WHY THIS MATTERS: If you're ads ain't blending into the native platform you are spending money on... you're at a loss. This will require innovation. This will require entire teams stepping out of their comfort zone to adapt to this new world.&lt;/p&gt;

&lt;p&gt;🥊 THE HOOK: Straight to the point. This new way of consuming content is forcing content creators to get straight to the point. You have to immediately deliver: education, inspiration, entertainment or value, if not you lost your audience.&lt;/p&gt;

&lt;p&gt;💡 WHY THIS MATTERS: Whether you’re teaching grammar or programming the winners in these platforms are those who are able to educate and entertain in snackable sized content.&lt;/p&gt;

&lt;p&gt;✨ CONCLUSION: This is a blatant example of where Social Media Platforms are heading: video, social-first video content that keeps you watching, engaging and creating in the platform. &lt;/p&gt;

&lt;p&gt;TikTok came to disrupt the way content is created and consumed, all the other platforms are catching on and implementing these changes. These subtle changes are hugely important, we need to notice them and prepare for them because the algorithms are changing whether we want to or to not. &lt;/p&gt;

&lt;p&gt;PLEASE SHARE YOUR THOUGHTS WITH ME AND LET'S CONTINUE TO GEEK OUT ON THE FUTURE OF SOCIALS.&lt;/p&gt;

</description>
      <category>socialmedia</category>
      <category>content</category>
      <category>tiktok</category>
    </item>
    <item>
      <title>Building an application with Go and SQLite</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Fri, 15 Apr 2022 21:34:59 +0000</pubDate>
      <link>https://dev.to/pluralsight/building-an-application-with-go-and-sqlite-11h</link>
      <guid>https://dev.to/pluralsight/building-an-application-with-go-and-sqlite-11h</guid>
      <description>&lt;p&gt;Today we're going to learn how to use SQLite with Go. By the time you finish this tutorial, you can build CRUD (Create Read Update Delete) applications with Go easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pluralsight.com/paths/go-core-language?utm_source=allhandsontech&amp;amp;utm_medium=organic-web&amp;amp;utm_campaign=allhandsontech" rel="noopener noreferrer"&gt;Go&lt;/a&gt; is one of the hottest languages in development right now, known for its simple structure and blazing performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.sqlite.org/index.html" rel="noopener noreferrer"&gt;SQLite&lt;/a&gt; has been trending among developers for its ability to host small data very quickly, safely, and contained in a single file.&lt;/p&gt;

&lt;p&gt;Why SQLite?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great Performance&lt;/li&gt;
&lt;li&gt;Tiny footprint&lt;/li&gt;
&lt;li&gt;Self contained (file based)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In fact, you're likely already using SQLite every day and you don't know it. It's ubiquitous in mobile phones and devices, and SQLite powers many websites today.&lt;/p&gt;

&lt;p&gt;So we're going to combine these two technologies to show you how easy it is to marry the two.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this tutorial covers
&lt;/h2&gt;

&lt;p&gt;We'll build a CLI (command-line interface) application with Go and SQLite. It will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating&lt;/li&gt;
&lt;li&gt;Reading&lt;/li&gt;
&lt;li&gt;Updating&lt;/li&gt;
&lt;li&gt;Deleting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With SQLite. You can follow along and build this application or use this as a reference to build something of your own. I'll start with pre-populated database you can &lt;a href="https://github.com/JeremyMorgan/GoSqliteDemo/blob/main/names.db" rel="noopener noreferrer"&gt;download here&lt;/a&gt;. It has a database full of people with their first name, last name, email address, and IP address.&lt;/p&gt;

&lt;p&gt;We'll start by creating a menu, then building out methods for each operation, and in the end, you'll have an application that looks like this:&lt;/p&gt;

&lt;p&gt;So let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the menu system
&lt;/h2&gt;

&lt;p&gt;We will build a CLI application that accesses a SQLite database. I'm going to use &lt;a href="https://github.com/dixonwille/wmenu" rel="noopener noreferrer"&gt;The WMenu package from Dixonwille&lt;/a&gt; for this, so we have an interface for our data. We'll use this menu and a scanner to accept input to interact with our database.&lt;/p&gt;

&lt;p&gt;We won't focus too heavily on the menu system itself because the intent of this article is to show you how to utilize SQLite.&lt;/p&gt;

&lt;p&gt;First, we'll &lt;a href="https://golang.org/doc/tutorial/create-module" rel="noopener noreferrer"&gt;create a Go module&lt;/a&gt; and work with &lt;code&gt;main.go&lt;/code&gt; to start.&lt;/p&gt;

&lt;p&gt;Install the WMenu package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/dixonwille/wmenu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a &lt;code&gt;main.go&lt;/code&gt; that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "log"
    "github.com/dixonwille/wmenu/v5"
)

func main() {

    menu := wmenu.NewMenu("What would you like to do?")

    menu.Action(func(opts []wmenu.Opt) error { handleFunc(opts); return nil })

    menu.Option("Add a new Person", 0, true, nil)
    menu.Option("Find a Person", 1, false, nil)
    menu.Option("Update a Person's information", 2, false, nil)
    menu.Option("Delete a person by ID", 3, false, nil)
    menuerr := menu.Run()

    if menuerr != nil {
        log.Fatal(menuerr)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create a menu with the following options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a new Person&lt;/li&gt;
&lt;li&gt;Find a Person&lt;/li&gt;
&lt;li&gt;Update a Person's information&lt;/li&gt;
&lt;li&gt;Delete a person by ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice we are calling a function named 'handleFunc(opts)' to handle which option is chosen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;menu.Action(func(opts []wmenu.Opt) error { handleFunc(opts); return nil })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's create that function and have it display some values for now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func handleFunc(opts []wmenu.Opt) {

    switch opts[0].Value {

    case 0:
        fmt.Println("Adding a new Person")
    case 1:
        fmt.Println("Finding a Person")
    case 2:
        fmt.Println("Update a Person's information")
    case 3:
        fmt.Println("Deleting a person by ID")
    case 4:
        fmt.Println("Quitting application")
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we run the application, you should see a menu that looks like this:&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%2Fir7lekrd8s4wygh78l7p.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%2Fir7lekrd8s4wygh78l7p.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you make a selection, it should display what you selected:&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%2Fh19apnoy84jhx57ufjz6.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%2Fh19apnoy84jhx57ufjz6.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the menu we will use to interact with our SQLite Go code. I will break it up into CRUD parts, and we'll add to it as we go along.&lt;/p&gt;

&lt;p&gt;So let's dive in. We'll start with a quick look at the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SQLite database
&lt;/h2&gt;

&lt;p&gt;The database we're using for this exercise is available here.&lt;/p&gt;

&lt;p&gt;The Schema is pretty simple. We are storing "people" with the following attributes:&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%2Fbxo3jtjza89j33hc6139.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%2Fbxo3jtjza89j33hc6139.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The create statement is here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;"people"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;"id"&lt;/span&gt;    &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"first_name"&lt;/span&gt;    &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"last_name"&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"email"&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"ip_address"&lt;/span&gt;    &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"id"&lt;/span&gt; &lt;span class="n"&gt;AUTOINCREMENT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've populated it with fake data from &lt;a href="https://www.mockaroo.com/" rel="noopener noreferrer"&gt;Mockaroo&lt;/a&gt;, my favorite test data generator. We will access this data, and add to it without our Go CLI application.&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%2Fp5bw61g6lm6e85o64046.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%2Fp5bw61g6lm6e85o64046.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the spirit of CRUD, we'll build out our application in that order, &lt;strong&gt;C&lt;/strong&gt;reate, &lt;strong&gt;R&lt;/strong&gt;ead, &lt;strong&gt;U&lt;/strong&gt;pdate, &lt;strong&gt;D&lt;/strong&gt;elete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to the database
&lt;/h2&gt;

&lt;p&gt;We'll need to add some additional code to connect to the database. We'll use an object to create a connection, and we can pass it to other parts of the program.&lt;/p&gt;

&lt;p&gt;First, to catch errors in our code, let's create a simple function named &lt;code&gt;checkErr&lt;/code&gt; that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func checkErr(err error) {
    if err != nil {
        log.Fatal(err)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's add the &lt;a href="https://github.com/mattn/go-sqlite3" rel="noopener noreferrer"&gt;go-sqlite3 library from mattn&lt;/a&gt; to connect with SQLite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/mattn/go-sqlite3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is by far the best SQLite library for Go that I've used. It's easy, fast, and well documented.&lt;/p&gt;

&lt;p&gt;Then, we'll create a connection to our database, in the &lt;code&gt;main()&lt;/code&gt; func:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Connect to database
db, err := sql.Open("sqlite3", "./names.db")
checkErr(err)
// defer close
defer db.Close()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does is create a &lt;code&gt;db&lt;/code&gt; object. The &lt;code&gt;sql.Open&lt;/code&gt; method opens up &lt;code&gt;names.db&lt;/code&gt; as a SQLite 3 database. It's a simple step. Then we &lt;a href="https://tour.golang.org/flowcontrol/12" rel="noopener noreferrer"&gt;defer&lt;/a&gt; the close of the database.&lt;/p&gt;

&lt;p&gt;Now let's refactor our menu code so we can pass this object into our menu actions.&lt;/p&gt;

&lt;p&gt;Change this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;menu.Action(func(opts []wmenu.Opt) error { handleFunc(opts); return nil })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;menu.Action(func(opts []wmenu.Opt) error { handleFunc(db, opts); return nil })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add the parameter to our function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func handleFunc(opts []wmenu.Opt) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func handleFunc(db *sql.DB, opts []wmenu.Opt) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can pass this database connection and use it with our options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a model
&lt;/h2&gt;

&lt;p&gt;Let's create a model we can use to store and transport our &lt;code&gt;person&lt;/code&gt; records. We'll want to separate this into a new file. I've named it &lt;code&gt;person.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In that file, I'll create a struct that matches the datatype of our record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    _ "github.com/mattn/go-sqlite3"
)

type person struct {
    id         int
    first_name string
    last_name  string
    email      string
    ip_address string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a new record
&lt;/h2&gt;

&lt;p&gt;We will add the functionality to create a new record in the database. You can use &lt;a href="https://sqlitebrowser.org" rel="noopener noreferrer"&gt;DB Browser for SQLite&lt;/a&gt; to access this database to verify changes.&lt;/p&gt;

&lt;p&gt;First, we'll add some code to handle the data.&lt;/p&gt;

&lt;p&gt;If you remember, back in &lt;code&gt;main.go&lt;/code&gt;, we have a switch statement within handleFunc that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func handleFunc(opts []wmenu.Opt) {

    switch opts[0].Value {

    case 0:
        fmt.Println("Adding a new Person")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's change that to handle accepting a new record as input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 0:

    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter a first name: ")
    firstName, _ := reader.ReadString('\n')
    fmt.Print("Enter a last name: ")
    lastName, _ := reader.ReadString('\n')
    fmt.Print("Enter an email address: ")
    email, _ := reader.ReadString('\n')
    fmt.Print("Enter an IP address: ")
    ipAddress, _ := reader.ReadString('\n')

    newPerson := person{
        first_name: firstName,
        last_name:  lastName,
        email:      email,
        ip_address: ipAddress,
    }

    addPerson(db, newPerson)

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

&lt;/div&gt;



&lt;p&gt;Here we use a bufio scanner to read in the first name, last name, email address, and IP address of a new person. We read those values into a buffer one by one, then create a new &lt;code&gt;person&lt;/code&gt; struct, and pass that to the &lt;code&gt;addPerson&lt;/code&gt; method (which doesn't exist yet)&lt;/p&gt;

&lt;p&gt;The menu system will prompt us for these values, one by one and then save them to the database.&lt;/p&gt;

&lt;p&gt;Open up &lt;code&gt;person.go&lt;/code&gt; and let's create the &lt;code&gt;addPerson&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func addPerson(db *sql.DB, newPerson person) {

    stmt, _ := db.Prepare("INSERT INTO people (id, first_name, last_name, email, ip_address) VALUES (?, ?, ?, ?, ?)")
    stmt.Exec(nil, newPerson.first_name, newPerson.last_name, newPerson.email, newPerson.ip_address)
    defer stmt.Close()

    fmt.Printf("Added %v %v \n", newPerson.first_name, newPerson.last_name)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function takes the &lt;code&gt;db&lt;/code&gt; object and the new &lt;code&gt;person&lt;/code&gt; struct and inserts it into the database.  We create a new SQL statement, &lt;code&gt;stmt&lt;/code&gt;. We use &lt;code&gt;db.Prepare&lt;/code&gt; to prepare our insert statement, and protect the application from SQL injection. Then we run &lt;code&gt;stmt.Exec&lt;/code&gt; with the parameters we want to insert. Then defer the close method and print our results.&lt;/p&gt;

&lt;p&gt;Save the file, and let's run 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%2Fuf731a30vsdb6hsqjnvu.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%2Fuf731a30vsdb6hsqjnvu.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see our menu come up, ask us for each part of the record, then save it. We can check the database and confirm that it was saved:&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%2Fgqvbgwmerhn8eh858hut.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%2Fgqvbgwmerhn8eh858hut.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you may notice something here. Notice the line breaks right after the first name?&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%2Fwn5171rg6d8btp8axexk.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%2Fwn5171rg6d8btp8axexk.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is because the newline (when you press enter) is scanned into the buffer, and it saves into the database this way. But we can fix this problem easily.&lt;/p&gt;

&lt;p&gt;We can trim the suffix of each of those strings like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firstName = strings.TrimSuffix(firstName, "\n")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To remove the newline before it's inserted into the database.&lt;/p&gt;

&lt;p&gt;So refactor your case statement to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 0:

    reader := bufio.NewReader(os.Stdin)

    fmt.Print("Enter a first name: ")
    firstName, _ := reader.ReadString('\n')
    if firstName != "\n" {
        firstName = strings.TrimSuffix(firstName, "\n")
    }

    fmt.Print("Enter a last name: ")
    lastName, _ := reader.ReadString('\n')
    if lastName != "\n" {
        lastName = strings.TrimSuffix(lastName, "\n")
    }

    fmt.Print("Enter an email address: ")
    email, _ := reader.ReadString('\n')
    if email != "\n" {
        email = strings.TrimSuffix(email, "\n")
    }

    fmt.Print("Enter an IP address: ")
    ipAddress, _ := reader.ReadString('\n')
    if ipAddress != "\n" {
        ipAddress = strings.TrimSuffix(ipAddress, "\n")
    }

    newPerson := person{
        first_name: firstName,
        last_name:  lastName,
        email:      email,
        ip_address: ipAddress,
    }

    addPerson(db, newPerson)

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

&lt;/div&gt;



&lt;p&gt;Now let's rerun it and add another person:&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%2Fiii7cl0svqije6sasmic.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%2Fiii7cl0svqije6sasmic.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can see that the newline was removed, and it even looks proper in the database:&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%2Fqf5y1vpuymq3xat6abtj.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%2Fqf5y1vpuymq3xat6abtj.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll go back and fix Lloyd at a later time.&lt;/p&gt;

&lt;p&gt;Now we have our &lt;strong&gt;Create&lt;/strong&gt; portion finished! We can now create new people for this database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading a record
&lt;/h2&gt;

&lt;p&gt;Now we want to read a record, the functionality in our second menu option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;menu.Option("Find a Person", 1, false, nil)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create code to find a person by their name.&lt;/p&gt;

&lt;p&gt;Add the following to the case statement in &lt;code&gt;handleFunc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;change&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 1:
    fmt.Println("Finding a Person")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 1:

        reader := bufio.NewReader(os.Stdin)
        fmt.Print("Enter a name to search for : ")
        searchString, _ := reader.ReadString('\n')
    searchString = strings.TrimSuffix(searchString, "\n")
        people := searchForPerson(db, searchString)

        fmt.Printf("Found %v results\n", len(people))

        for _, ourPerson := range people {
            fmt.Printf("\n----\nFirst Name: %s\nLast Name: %s\nEmail: %s\nIP Address: %s\n", ourPerson.first_name, ourPerson.last_name, ourPerson.email, ourPerson.ip_address)
        }
        break
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we create another bufio reader to read from standard input (your keyboard).  We read in the name you search for into &lt;code&gt;searchString&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, we will create a variable named &lt;code&gt;people&lt;/code&gt; to store our results in. It's populated by the &lt;code&gt;searchForPerson&lt;/code&gt; function that we'll create.&lt;/p&gt;

&lt;p&gt;This function returns a list of people results based on our search string. It could be one or more results, so we'll print out how many people we find.&lt;/p&gt;

&lt;p&gt;Then we'll loop through the results and display them on the screen.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;person.go&lt;/code&gt; let's create a searchForPerson function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func searchForPerson(db *sql.DB, searchString string) []person {

    rows, err := db.Query("SELECT id, first_name, last_name, email, ip_address FROM people WHERE first_name like '%" + searchString + "%' OR last_name like '%" + searchString + "%'")

    defer rows.Close()

    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }

    people := make([]person, 0)

    for rows.Next() {
        ourPerson := person{}
        err = rows.Scan(&amp;amp;ourPerson.id, &amp;amp;ourPerson.first_name, &amp;amp;ourPerson.last_name, &amp;amp;ourPerson.email, &amp;amp;ourPerson.ip_address)
        if err != nil {
            log.Fatal(err)
        }

        people = append(people, ourPerson)
    }

    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }

    return people
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll create this function that takes the &lt;code&gt;db&lt;/code&gt; object and a search string and returns a slice of &lt;code&gt;person&lt;/code&gt; objects (structs).&lt;/p&gt;

&lt;p&gt;We'll run a SELECT statement to select id, first and last name, email, and IP address based on whether the first or last name matches our search string.&lt;/p&gt;

&lt;p&gt;We iterate through each row, create a &lt;code&gt;person&lt;/code&gt; struct and populate it with the resulting data. Then we append it to our slice and return the completed collection with the function.&lt;/p&gt;

&lt;p&gt;Let's build it and run 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%2F5f636g7matatylvosad8.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%2F5f636g7matatylvosad8.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the program and select &lt;strong&gt;2&lt;/strong&gt; to find a person, and search for a first and last name, and you'll see the results! Great stuff.&lt;/p&gt;

&lt;p&gt;Now let's build something to update these records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating a record
&lt;/h2&gt;

&lt;p&gt;Now we can add people and look them up. What if we want to update the information? If you remember, we inserted Lloyd Christmas with newlines attached to it. So let's build something to update the record and save it.&lt;/p&gt;

&lt;p&gt;This one will be a little different. Here's how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get an ID from user input&lt;/li&gt;
&lt;li&gt;Retrieve a record from that ID and put it in a person struct.&lt;/li&gt;
&lt;li&gt;Display the current value when asking for a new value&lt;/li&gt;
&lt;li&gt;Save new value into a new struct&lt;/li&gt;
&lt;li&gt;Save the update(s) to the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;code&gt;main.go&lt;/code&gt; let's add another case for our third menu option.&lt;/p&gt;

&lt;p&gt;replace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 2:
    fmt.Println("Update a Person's information")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 2:

    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter an id to update: ")
    updateid, _ := reader.ReadString('\n')

    currentPerson := getPersonById(db, updateid)

    fmt.Printf("First Name (Currently %s):", currentPerson.first_name)
    firstName, _ := reader.ReadString('\n')
    if firstName != "\n" {
        currentPerson.first_name = strings.TrimSuffix(firstName, "\n")
    }

    fmt.Printf("Last Name (Currently %s):", currentPerson.last_name)
    lastName, _ := reader.ReadString('\n')
    if lastName != "\n" {
        currentPerson.last_name = strings.TrimSuffix(lastName, "\n")
    }

    fmt.Printf("Email (Currently %s):", currentPerson.email)
    email, _ := reader.ReadString('\n')
    if email != "\n" {
        currentPerson.email = strings.TrimSuffix(email, "\n")
    }

    fmt.Printf("IP Address (Currently %s):", currentPerson.ip_address)
    ipAddress, _ := reader.ReadString('\n')
    if ipAddress != "\n" {
        currentPerson.ip_address = strings.TrimSuffix(ipAddress, "\n")
    }

    affected := updatePerson(db, currentPerson)

    if affected == 1 {
        fmt.Println("One row affected")
    }

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

&lt;/div&gt;



&lt;p&gt;We create another bufio scanner to read in the ID you want to update.&lt;/p&gt;

&lt;p&gt;Then we search for that id with &lt;code&gt;getPersonById&lt;/code&gt; and store it in &lt;code&gt;currentPerson&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then we go through each value and display the current value while asking for a new value.&lt;/p&gt;

&lt;p&gt;If the user presses enter, it will keep the current value. If they type in something new, it will be updated in the &lt;code&gt;currentPerson&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;Then, we'll create a variable named &lt;code&gt;affected&lt;/code&gt; and call the &lt;code&gt;updatePerson&lt;/code&gt; method, and pass in the db connection method and the &lt;code&gt;currentPerson&lt;/code&gt; object with the new information.&lt;/p&gt;

&lt;p&gt;If the update is successful, we'll return a message.&lt;/p&gt;

&lt;p&gt;Let's create the methods we need in &lt;code&gt;person.go&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func getPersonById(db *sql.DB, ourID string) person {

    rows, _ := db.Query("SELECT id, first_name, last_name, email, ip_address FROM people WHERE id = '" + ourID + "'")
    defer rows.Close()

    ourPerson := person{}

    for rows.Next() {
        rows.Scan(&amp;amp;ourPerson.id, &amp;amp;ourPerson.first_name, &amp;amp;ourPerson.last_name, &amp;amp;ourPerson.email, &amp;amp;ourPerson.ip_address)
    }

    return ourPerson
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method takes our &lt;strong&gt;db&lt;/strong&gt; object and an ID as a string. We run a query to select records that match that ID. Then we create a new &lt;code&gt;person&lt;/code&gt; object and iterate through the row, and scan in each value to the object. Once complete, we return it.&lt;/p&gt;

&lt;p&gt;After displaying the current values and taking in new ones in &lt;code&gt;main.go&lt;/code&gt;, we need to process the new &lt;code&gt;person&lt;/code&gt; object and update the database. We'll do that with the &lt;code&gt;updatePerson&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func updatePerson(db *sql.DB, ourPerson person) int64 {

    stmt, err := db.Prepare("UPDATE people set first_name = ?, last_name = ?, email = ?, ip_address = ? where id = ?")
    checkErr(err)
    defer stmt.Close()

    res, err := stmt.Exec(ourPerson.first_name, ourPerson.last_name, ourPerson.email, ourPerson.ip_address, ourPerson.id)
    checkErr(err)

    affected, err := res.RowsAffected()
    checkErr(err)

    return affected
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use a prepared statement and use the values from the person object passed in to run an UPDATE against the database. We execute the statement and return the rows affected, which should be one.&lt;/p&gt;

&lt;p&gt;Save the file and run it. Let's fix Lloyd's record.&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%2F05bmklwqygqzcqqy7feg.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%2F05bmklwqygqzcqqy7feg.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice the display is all messed up. That's because these records contained a newline, so it looks funny. But we've updated that record now so they are gone.&lt;/p&gt;

&lt;p&gt;The next time we go to update it, we see the newlines are gone:&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%2Fu01x4wz67n9w588zrq13.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%2Fu01x4wz67n9w588zrq13.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we can now update any record we like and change all the values except for the ID. Great!&lt;/p&gt;

&lt;h2&gt;
  
  
  Deleting a record
&lt;/h2&gt;

&lt;p&gt;Finally, we need to delete a record from the database. This is easy.&lt;/p&gt;

&lt;p&gt;in &lt;code&gt;main.go&lt;/code&gt; let's add the following case option:&lt;/p&gt;

&lt;p&gt;Change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 3:
    fmt.Println("Deleting a person by ID")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 3:

    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter the ID you want to delete : ")
    searchString, _ := reader.ReadString('\n')

    idToDelete := strings.TrimSuffix(searchString, "\n")

    affected := deletePerson(db, idToDelete)

    if affected == 1 {
        fmt.Println("Deleted person from database")
    }

    break

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

&lt;/div&gt;



&lt;p&gt;This will look familiar. We're reading in an ID from standard input. Then, we're trimming the newline and passing that string to a &lt;code&gt;deletePerson&lt;/code&gt; method. This method takes our &lt;code&gt;db&lt;/code&gt; object and the ID we want to delete and returns affected, which should be 1.&lt;/p&gt;

&lt;p&gt;Let's add the &lt;code&gt;deletePerson&lt;/code&gt; method to our &lt;code&gt;person.go&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func deletePerson(db *sql.DB, idToDelete string) int64 {

    stmt, err := db.Prepare("DELETE FROM people where id = ?")
    checkErr(err)
    defer stmt.Close()

    res, err := stmt.Exec(idToDelete)
    checkErr(err)

    affected, err := res.RowsAffected()
    checkErr(err)

    return affected
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deletePerson method is pretty simple. It takes in our db connection and the ID to delete. It prepares a statement that's a DELETE and accepts a parameter for id. That is inserted into stmt.Exec and executed. Since there's no output from this command we look for the rows affected and return that as our output. Easy.&lt;/p&gt;

&lt;p&gt;Let's delete a record from the database. We'll find the id of Lloyd (1001):&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%2Fhvcqvr0y281awwzvslqy.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%2Fhvcqvr0y281awwzvslqy.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we'll build and run our program, and enter that ID:&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%2F90w96ti01te71d3dsex2.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%2F90w96ti01te71d3dsex2.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now record 1001 is gone:&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%2F47rsxt3cx2ahj7avxgj2.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%2F47rsxt3cx2ahj7avxgj2.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now we can successfully &lt;strong&gt;C&lt;/strong&gt;reate, &lt;strong&gt;R&lt;/strong&gt;ead, &lt;strong&gt;U&lt;/strong&gt;pdate, and &lt;strong&gt;D&lt;/strong&gt;elete records with our application!&lt;/p&gt;

&lt;h2&gt;
  
  
  Exiting the program
&lt;/h2&gt;

&lt;p&gt;Finally, we need to be able to exit the program.&lt;/p&gt;

&lt;p&gt;Replace&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 4:
    fmt.Println("Quitting application")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 4:
    fmt.Println("Goodbye!")
    os.Exit(3)

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

&lt;/div&gt;



&lt;p&gt;Now let's build and run 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%2F9jlou1q4p8ucymslwyls.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%2F9jlou1q4p8ucymslwyls.png" alt="How to use SQLite with Go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! Now we have a complete &lt;em&gt;CRUD&lt;/em&gt; app with SQLite and Go!&lt;/p&gt;

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

&lt;p&gt;Fast, small, cross-platform applications are excellent for many use cases. This is why Go is becoming so popular. Fast, small and self-contained databases are the perfect addition to such applications which makes SQLite and Go a natural combination. This stack is no silver bullet and won't solve every problem, but there are many great uses for this.&lt;/p&gt;

&lt;p&gt;The source code for this demo application is &lt;a href="https://github.com/JeremyMorgan/GoSqliteDemo" rel="noopener noreferrer"&gt;available here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any questions, or comments, &lt;a href="https://www.twitter.com/JeremyCMorgan" rel="noopener noreferrer"&gt;let me know&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you'd like to learn more about Go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://play.golang.org/" rel="noopener noreferrer"&gt;The Go Playground&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pluralsight.com/paths/go-core-language?utm_source=allhandsontech&amp;amp;utm_medium=organic-web&amp;amp;utm_campaign=allhandsontech" rel="noopener noreferrer"&gt;The Go Core Language Path&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more about SQLite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.sqlitetutorial.net" rel="noopener noreferrer"&gt;SQLite tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sqlite.org/quickstart.html" rel="noopener noreferrer"&gt;SQLite in Five minutes or less&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>sql</category>
    </item>
    <item>
      <title>Linux Commands You Need to know Part 2: Working with Files</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Mon, 11 Apr 2022 17:42:45 +0000</pubDate>
      <link>https://dev.to/pluralsight/linux-commands-you-need-to-know-part-2-working-with-files-4ep0</link>
      <guid>https://dev.to/pluralsight/linux-commands-you-need-to-know-part-2-working-with-files-4ep0</guid>
      <description>&lt;p&gt;In the last article in our series, &lt;a href="https://dev.to/pluralsight/linux-commands-you-need-to-know-part-1-navigation-15k5"&gt;Linux Commands You Need to Know - Navigation&lt;/a&gt; we learned how to travel around the file system in Linux. Today, we're going to learn how to work with files.&lt;/p&gt;

&lt;p&gt;We will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to make a directory
&lt;/li&gt;
&lt;li&gt;Remove a directory&lt;/li&gt;
&lt;li&gt;Make a copy of a file&lt;/li&gt;
&lt;li&gt;Move or rename a file&lt;/li&gt;
&lt;li&gt;Create an empty file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So let's dig in!!&lt;/p&gt;




&lt;h2 id="mkdir"&gt;1. mkdir&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to create a directory&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;As we covered in the last article, folders in Linux are called "directories". They serve the same purpose as folders in Windows.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir [directory name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here's mkdir in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7IbWcVYJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccca1pkatyuoly49vkjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7IbWcVYJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccca1pkatyuoly49vkjg.png" alt='"Linux Commands for Working with Files - mkdir"' width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can even make a directory within a directory, even if the base one doesn't exist with the &lt;code&gt;-p&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;Here I will create a new directory called test2 within a test directory, with the -p option:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y3Kijujm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu4yevr30mq9rhq2ucc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y3Kijujm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu4yevr30mq9rhq2ucc4.png" alt='"Linux Commands for Working with Files - mkdir -p"' width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2 id="rmdir"&gt; 2. rmdir&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to remove a directory&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;With the &lt;code&gt;rmdir&lt;/code&gt; command, you can remove a directory quickly and easily.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rmdir [directory name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here's rmdir in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tf7gUGbP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jp9q0cngz290v4iijkl9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tf7gUGbP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jp9q0cngz290v4iijkl9.png" alt='"Helpful Linux Commands"' width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now this works great if the directory is empty. But what about the directory I created that has another directory in it? Here's what happens when I try to use rmdir on that directory:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gc3yIZHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnzzgwrongi5phxser57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gc3yIZHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnzzgwrongi5phxser57.png" alt='"Helpful Linux Commands"' width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;rmdir cannot remove directories that have files or directories in them. To do that, you must use the rm command (which we'll cover again in command #5 )&lt;/p&gt;

&lt;p&gt;Do that we need to type in&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm -rf [directory name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---pUaWFiW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3rrrd1mbeyzhsyjurx1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---pUaWFiW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3rrrd1mbeyzhsyjurx1.png" alt='"Helpful Linux Commands"' width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: &lt;em&gt;this will delete all files and directories within the directory.&lt;/em&gt;&lt;/p&gt;




&lt;h2 id="cp"&gt; 3. cp &lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to make a copy of a file&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Here's one you'll use all the time, especially if you're making a config file backup. Let's use that as an example. I want to make a backup of this file. If I mess something up, I can go back to the old version.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp [file name] [new file name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tPxlf-90--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fx6jwd91snx0xleairja.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tPxlf-90--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fx6jwd91snx0xleairja.png" alt='"Helpful Linux Commands"' width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also copy the file to another directory and keep the same file name:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp [file name] [new location]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WR01-QGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf72zn6dlcp3e9j81nxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WR01-QGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf72zn6dlcp3e9j81nxt.png" alt='"Helpful Linux Commands"' width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a great way to make copies of a file. But what if I want to move it?&lt;/p&gt;




&lt;h2 id="mv"&gt; 4. mv&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to move a file to another location or rename it&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;This one is pretty straightforward. You use it to move a file from one place to the other.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mv [file name] [new location]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It's used the same way as cp, though it moves the file instead of making a copy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L9_V18jg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwc0k6zuji85mj13rc3f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L9_V18jg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwc0k6zuji85mj13rc3f.png" alt='"Helpful Linux Commands"' width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is also how you &lt;strong&gt;rename a file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mv [file name] [new file name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So if I want to rename my nginx configuration file, I can do this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h0OUNUwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9p57dqr8q25y0560pq9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h0OUNUwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9p57dqr8q25y0560pq9v.png" alt='"Helpful Linux Commands"' width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it's done. What if I want to remove it?&lt;/p&gt;




&lt;h2 id="rm"&gt; 5. rm&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to delete a file&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;We used rm earlier to remove a directory. It's also you delete individual files.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm [file name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZwY7vxnH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2z0aojnz3d4r6nu9b5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZwY7vxnH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2z0aojnz3d4r6nu9b5a.png" alt='"Helpful Linux Commands"' width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can remove all the files in a directory with the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm -rf *&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It's a handy command for removing files.&lt;/p&gt;




&lt;h2 id="touch"&gt;6. touch&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: create an empty file&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;You may have noticed my "nginx.conf" was zero bytes. This is a nifty command for creating empty files. This is handy for creating a new file or testing things.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;touch [file name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates a file with nothing in it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dGXOJSzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kmcjn61003oy8d8h39p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dGXOJSzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kmcjn61003oy8d8h39p.png" alt='"Helpful Linux Commands"' width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="find"&gt;7. find a file (find)&lt;/h2&gt;

&lt;p&gt;This is a powerful command for finding files in the file system.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;find [path to search] -name filename&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's say I want to find my hello world code. I know the filename. I just don't know where it's located.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u71wVRPK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzqchi7io6zx8l2ezcup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u71wVRPK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzqchi7io6zx8l2ezcup.png" alt='"Helpful Linux Commands"' width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I can see exactly where my file is located with a simple command. &lt;/p&gt;

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

&lt;p&gt;In this article, we learned how to work with files. Working from the command prompt can be very fast and efficient, so now we know how to create, move, copy, and rename files from the command line.&lt;/p&gt;

&lt;p&gt;Please keep checking back to this site as we add to this series. We'll get into some advanced command line topics that will have you feeling like a Linux wizard in no time.&lt;/p&gt;

&lt;p&gt;You can test your Linux skills to see where you're at:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5zQH56Qg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1u8ju3ogo0k4jykwqdx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5zQH56Qg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1u8ju3ogo0k4jykwqdx.png" alt='"Helpful Linux Commands"' width="685" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I scored a 203, so I still have some room to grow. What's your score? &lt;a href="https://www.pluralsight.com/redeemlink/genericV4?redemptionId=7a28c861-d736-41d3-842a-28a97d8e5714&amp;amp;mac=368c7cca1cac8158bae0da91fa137b5d01891402f7f7119a10a6a8be938da98a&amp;amp;utm_source=allhandsontech&amp;amp;utm_medium=organic-web&amp;amp;utm_campaign=allhandsontech"&gt;Take your SkillIQ now.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have any questions? Comments? &lt;a href="https://www.twitter.com/jeremycmorgan"&gt;Let me know!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;--Jeremy&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>linux</category>
      <category>learning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Linux Commands You Need to know Part 1: Navigation</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Wed, 06 Apr 2022 17:36:21 +0000</pubDate>
      <link>https://dev.to/pluralsight/linux-commands-you-need-to-know-part-1-navigation-15k5</link>
      <guid>https://dev.to/pluralsight/linux-commands-you-need-to-know-part-1-navigation-15k5</guid>
      <description>&lt;p&gt;The command prompt in Linux can be intimidating. It's one of the reasons many people avoid trying Linux if they come from a Windows or Mac environment. For years you had to know the command prompt very well to use Linux, so many people avoided it.&lt;/p&gt;

&lt;p&gt;This series will tackle the mystery of the command prompt, and help you learn how to use Linux better and faster.&lt;/p&gt;

&lt;p&gt;Popular Linux distributions like &lt;a href="https://ubuntu.com/download"&gt;Ubuntu&lt;/a&gt;, &lt;a href="https://pop.system76.com"&gt;Pop!_OS&lt;/a&gt;, &lt;a href="https://getfedora.org/en/workstation/download/"&gt;Fedora&lt;/a&gt;, etc., are very graphical. You don't have to do much with the command prompt to use Linux. However, it's still a valuable skill to have, especially if you're developing software or websites in Linux. In this series, we will dive into Linux commands, how they are used, and why we use them.&lt;/p&gt;

&lt;p&gt;If you can't navigate around the file system, you can't do much. So in part one of this series, we'll learn how to explore the file system from the prompt.&lt;/p&gt;

&lt;p&gt;Here is a typical file system in Linux:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1Z1m78hF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cty38bvimq4mqf4bovge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1Z1m78hF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cty38bvimq4mqf4bovge.png" alt='"Helpful Linux Commands"' width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll notice it looks a lot like Windows and Mac. However, if you notice at the top where it says &lt;code&gt;/home/jeremy&lt;/code&gt;, there is a file structure there, and that's what we're going to explore. Note that in Linux, we usually call folders "directories." They're the same concept, but it can be confusing at first.&lt;/p&gt;

&lt;p&gt;Let's dive into some well known commands for navigation.&lt;/p&gt;

&lt;p&gt;We will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to tell where you are in the filesystem
&lt;/li&gt;
&lt;li&gt;Change your location&lt;/li&gt;
&lt;li&gt;Show the objects in a directory&lt;/li&gt;
&lt;li&gt;Return to your home folder&lt;/li&gt;
&lt;li&gt;Visualize the file system&lt;/li&gt;
&lt;/ul&gt;




&lt;h2 id="pwd"&gt;1. pwd&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to show where you are located on the filesystem&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;This stands for "print working directory," it tells you where you're at on the file system. It's handy because it's easy to get "lost" on the file system.&lt;/p&gt;

&lt;p&gt;usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When I run pwd on my machine, it shows I'm in /home/jeremy:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1l8uObfA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mb5z3x9ox6prwswzrch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1l8uObfA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mb5z3x9ox6prwswzrch.png" alt='"Helpful Linux Commands"' width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2 id="cd"&gt; 2. cd&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to navigate the file system&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;This stands for "change directory," and it allows you to navigate.&lt;/p&gt;

&lt;p&gt;usage&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd (name of the directory you want to go to)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now this one has more than a few interesting options.&lt;/p&gt;

&lt;p&gt;You can go into the next folder up by typing its name.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd [name of directory]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So if I'm in &lt;code&gt;/home/jeremy&lt;/code&gt; and I want to go to &lt;code&gt;games&lt;/code&gt; I would just type in &lt;code&gt;cd games&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wmhADAtp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrubfmlionmhh864wfbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wmhADAtp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrubfmlionmhh864wfbq.png" alt='"Helpful Linux Commands"' width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's a &lt;em&gt;relative&lt;/em&gt; path. If I want to do an &lt;em&gt;absolute&lt;/em&gt; path, I will type in &lt;code&gt;cd /home/jeremy/games&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now I'm in that directory. What if I want to go directly to my Go bin folder? I would type in&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd /usr/local/go/bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and you'll move directly to that folder:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--12Neaqgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mvneh3yjur292ww9ppg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--12Neaqgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mvneh3yjur292ww9ppg.png" alt='"Helpful Linux Commands"' width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can cd into a directory above where you are, or explicitly.&lt;/p&gt;

&lt;p&gt;You can also go down one directory by typing&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you want to go down two directories, you can do that too.&lt;/p&gt;

&lt;p&gt;So let's say you're in &lt;code&gt;/usr/local/go/bin&lt;/code&gt; and you want to go to &lt;code&gt;/usr/local&lt;/code&gt; you would type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ../..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LadBWOx5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mn7v3xjig50cmnjj0yxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LadBWOx5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mn7v3xjig50cmnjj0yxg.png" alt='"Helpful Linux Commands"' width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there you have it! &lt;code&gt;cd&lt;/code&gt; is a great navigation tool.&lt;/p&gt;




&lt;h2 id="ls"&gt;3. ls&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Purpose: to list the objects in a directory&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;ls&lt;/code&gt; command lists all the objects in a directory. So, we're in our &lt;code&gt;/usr/local&lt;/code&gt; directory. If we type in &lt;code&gt;ls&lt;/code&gt; we'll see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9RFXL8eg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7n8cfidchy04le54pwm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9RFXL8eg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7n8cfidchy04le54pwm.png" alt='"Helpful Linux Commands"' width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This isn't super helpful. I prefer something like &lt;code&gt;ls -la&lt;/code&gt; which shows "all" of the information about the objects:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TCNM2-vg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1zp23ybh8q96epnsux2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TCNM2-vg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1zp23ybh8q96epnsux2.png" alt='"Helpful Linux Commands"' width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to show what's in the directories as well, type &lt;code&gt;ls -R&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5U84v3En--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wnlk1buzwggq4zz9wehb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5U84v3En--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wnlk1buzwggq4zz9wehb.png" alt='"Helpful Linux Commands"' width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to search for a specific file name or extension, use the &lt;code&gt;*&lt;/code&gt; symbol. Let's say I want to find every .toml file in my directory.&lt;/p&gt;

&lt;p&gt;I type in &lt;code&gt;ls -la *.toml&lt;/code&gt;. The asterisk means "everything that has .toml" at the end:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xh-U7OCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tzlc4iy5ga90ocjd12q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xh-U7OCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tzlc4iy5ga90ocjd12q.png" alt='"Helpful Linux Commands"' width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or, we can look for "every file with the name staging in it" by typing &lt;code&gt;ls -la *staging*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_OG7kmGP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60cwnw8n1pvq6ziort8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_OG7kmGP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60cwnw8n1pvq6ziort8n.png" alt='"Helpful Linux Commands"' width="800" height="149"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ls is a simple command that can be very powerful.&lt;/p&gt;




&lt;h2 id="home"&gt;4. ~&lt;/h2&gt;

&lt;p&gt;Ok, so &lt;code&gt;~&lt;/code&gt; isn't a command, but something you append to commands. It simply means "home".&lt;/p&gt;

&lt;p&gt;if you type in &lt;code&gt;cd ~&lt;/code&gt; it will take you to your home directory:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cZ-Cp5Rb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pzx2nakzwiud1xa4vuh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cZ-Cp5Rb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pzx2nakzwiud1xa4vuh.png" alt='"Helpful Linux Commands"' width="800" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only that, you can create directories using ~ as a shortcut for home. You can navigate to directories under your home directory with ease.&lt;/p&gt;

&lt;p&gt;Let's say I'm in /etc/X11/init and doing some work. But I want to get to a specific directory in my home directory.&lt;/p&gt;

&lt;p&gt;Instead of typing out &lt;code&gt;cd /home/jeremy/repos/JeremyMorganDotCom&lt;/code&gt;,&lt;/p&gt;

&lt;p&gt;I can type &lt;code&gt;cd ~/repos/JeremyMorganDotCom&lt;/code&gt; as a shortcut.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tVdAznfS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zg0envv2zhrd6tye2nf3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tVdAznfS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zg0envv2zhrd6tye2nf3.png" alt='"Helpful Linux Commands"' width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This may seem like a small thing but can add up to big savings once you get into the habit of using it.&lt;/p&gt;




&lt;h2 id="tree"&gt;5. tree&lt;/h2&gt;

&lt;p&gt;Tree is a helpful command for visualizing a file system. As a note: this command doesn't come with all Linux distributions. You may need to install it. It's a great way of visualizing the directory layout in the filesystem where you're at. Here's an example in a repository of one of my projects.&lt;/p&gt;

&lt;p&gt;To use it, you type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tree&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4qKrWACE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oxnm3on7nb17intsp2b2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4qKrWACE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oxnm3on7nb17intsp2b2.png" alt='"Helpful Linux Commands"' width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven't used this one as much, but it can be helpful for confusing filesystem layouts.&lt;/p&gt;

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

&lt;p&gt;Here are the typical commands for navigating in Linux. I encourage you to try them out and get comfortable with moving around. If you haven't installed Linux yet, you can still get some practice doing this. Here are some options so you can try it out on your Windows or Mac machine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac"&gt;Terminal&lt;/a&gt; on your Mac. It's the same commands.&lt;/li&gt;
&lt;li&gt;Install &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install"&gt;WSL&lt;/a&gt; (Windows Subsystem for Linux) and get a Linux installation within Windows.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://www.virtualbox.org/wiki/Downloads"&gt;Virtualbox&lt;/a&gt; and create a virtual Linux installation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are some ways you can try out Linux virtually risk-free. If you've already been bitten by the Linux bug, start expanding your skills with our &lt;a href="https://www.pluralsight.com/paths/skill/linux-fundamentals-1?utm_source=allhandsontech&amp;amp;utm_medium=organic-web&amp;amp;utm_campaign=allhandsontech"&gt;Linux Fundamentals Path&lt;/a&gt; where you can advance your Linux skills quickly.&lt;/p&gt;

&lt;p&gt;You can test your Linux skills to see where you're at:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VfnjktzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grm7kskbaqb6qxsxp913.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VfnjktzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grm7kskbaqb6qxsxp913.png" alt='"Helpful Linux Commands"' width="685" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I scored a 203, so I still have some room to grow. What's your score? &lt;a href="https://www.pluralsight.com/redeemlink/genericV4?redemptionId=7a28c861-d736-41d3-842a-28a97d8e5714&amp;amp;mac=368c7cca1cac8158bae0da91fa137b5d01891402f7f7119a10a6a8be938da98a&amp;amp;utm_source=allhandsontech&amp;amp;utm_medium=organic-web&amp;amp;utm_campaign=allhandsontech"&gt;Take your SkillIQ now.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have any questions? Comments? &lt;a href="https://www.twitter.com/jeremycmorgan"&gt;Let me know!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;--Jeremy&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>linux</category>
      <category>learning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What's the Best Way to Optimize Images for the Web?</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Mon, 06 Dec 2021 17:00:53 +0000</pubDate>
      <link>https://dev.to/pluralsight/whats-the-best-way-to-optimize-images-for-the-web-23m6</link>
      <guid>https://dev.to/pluralsight/whats-the-best-way-to-optimize-images-for-the-web-23m6</guid>
      <description>&lt;p&gt;Want fast loading web pages?&lt;/p&gt;

&lt;p&gt;You probably aren't optimizing your images enough. Image optimization is frequently overlooked because it's only a small difference and takes some time to do. But a series of small changes will lead to a screaming fast website. It's worth it. Your pages will load faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does this matter?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It's better for your user&lt;/li&gt;
&lt;li&gt;It makes your page more accessible in low bandwidth situations&lt;/li&gt;
&lt;li&gt;It's better for SEO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this in exchange for a few minutes of your time. Do you need any more reasons to optimize your images?&lt;/p&gt;

&lt;h3&gt;
  
  
  What We'll Do
&lt;/h3&gt;

&lt;p&gt;In this article, I will show you four ways to optimize your images and the results from each of them. I'll explain how I tested them and show you the results.&lt;/p&gt;

&lt;p&gt;You can download the files and perform your own tests by &lt;a href="https://github.com/JeremyMorgan/Image-optimization-test"&gt;downloading this repo&lt;/a&gt;. Feel free to play around with it.&lt;/p&gt;

&lt;p&gt;For testing, I decided to grab random images from &lt;a href="https://www.unsplash.com"&gt;unsplash&lt;/a&gt;. I randomized the width and height to get various dimensions you might see on the web.&lt;/p&gt;

&lt;p&gt;I used &lt;a href="https://github.com/JeremyMorgan/Image-optimization-test/blob/main/get-images.sh"&gt;this script&lt;/a&gt; to pull down 32 images and put them into a folder.&lt;/p&gt;

&lt;p&gt;We're going to look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The raw files - with nothing done to them&lt;/li&gt;
&lt;li&gt;Photoshop optimizing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://riot-optimizer.com"&gt;RIOT&lt;/a&gt; optimizing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.xnview.com/en/xnconvert/"&gt;XNConvert&lt;/a&gt; JPEG optimizing&lt;/li&gt;
&lt;li&gt;XNConvert to Webp optimizing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And we'll see how these methods stack up. We will examine &lt;strong&gt;file size&lt;/strong&gt; and &lt;strong&gt;page load time&lt;/strong&gt;. As a note, I do not change the resolution or color depth of these images, so they are all the same except for the optimizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I'm Testing Load time
&lt;/h3&gt;

&lt;p&gt;I'm testing load time by creating a simple index.html file in each folder that loads up a table of the images. I am serving it up with the &lt;a href="https://www.npmjs.com/package/serve"&gt;NPM serve&lt;/a&gt; package because it's a simple HTML server that runs locally. I don't want network latency to affect the results.&lt;/p&gt;

&lt;p&gt;Then I use CURL to grab the load time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -s -o /dev/null -w "%{time_total}\n" -H "Pragma: no-cache" https://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's optimize some images and see the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Raw Images
&lt;/h2&gt;

&lt;p&gt;This is a test with the images straight from Unsplash. It is our baseline measurement.&lt;/p&gt;

&lt;p&gt;Here is the total file size for all images:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EzlUt47p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cx42hwreay37o24j0zqi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EzlUt47p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cx42hwreay37o24j0zqi.jpg" alt="How to Optimize JPG images for the Web" width="790" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we're starting with &lt;strong&gt;3.1MB&lt;/strong&gt; of images. Not too shabby, but not small either.&lt;/p&gt;

&lt;p&gt;Here is the page load time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--777p-_I5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97k8aeumxuk1pw9tnqhj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--777p-_I5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97k8aeumxuk1pw9tnqhj.jpg" alt="How to Optimize JPG images for the Web" width="790" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I ran the test ten times and got an average load time of &lt;strong&gt;0.0013495&lt;/strong&gt; seconds. It seems fast, but we can improve on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimized with Photoshop
&lt;/h2&gt;

&lt;p&gt;For the next set of images, I optimized these with Photoshop. I used the following settings:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lq5TMNEd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/de1n2qynk7wb47pefwfu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lq5TMNEd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/de1n2qynk7wb47pefwfu.jpg" alt="How to Optimize JPG images for the Web" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I set a quality of &lt;strong&gt;60&lt;/strong&gt; and set it to progressive with no metadata. I got some interesting results.&lt;/p&gt;

&lt;p&gt;Here is the total file size for all images:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hTV3O-00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yg2lmkqieb2j6ui9waji.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hTV3O-00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yg2lmkqieb2j6ui9waji.jpg" alt="How to Optimize JPG images for the Web" width="790" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's &lt;strong&gt;3.3MB&lt;/strong&gt;, which is &lt;strong&gt;more&lt;/strong&gt; than we started with. I have no idea why this is and will investigate and update later. But most of the time, this creates smaller images.&lt;/p&gt;

&lt;p&gt;Here is the page load time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L6XXCUAj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzxtywnpcbrp3tmxm576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L6XXCUAj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzxtywnpcbrp3tmxm576.jpg" alt="How to Optimize JPG images for the Web" width="790" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our average load time is &lt;strong&gt;0.001213&lt;/strong&gt; seconds, which is a little above the raw files. Not much of a surprise with this file size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimized with RIOT
&lt;/h2&gt;

&lt;p&gt;Next, I optimized the images with the &lt;a href="https://riot-optimizer.com"&gt;Radical Image Optimization Tool (RIOT)&lt;/a&gt;. This is only available in Windows, but it's an excellent tool I've been using for years.&lt;/p&gt;

&lt;p&gt;I used the following settings:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dlZq4ERK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj5pm7lfctbzl74qlhey.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dlZq4ERK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj5pm7lfctbzl74qlhey.jpg" alt="How to Optimize JPG images for the Web" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And even though I left the quality pretty high at 82%, it shrunk the files down considerably:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PtJX_QID--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqx6s80gtp26323bjbpx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PtJX_QID--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqx6s80gtp26323bjbpx.jpg" alt="How to Optimize JPG images for the Web" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the total file size for all images:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Lx1dgSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20wb8wgqxnx71kxoigwd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Lx1dgSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20wb8wgqxnx71kxoigwd.jpg" alt="How to Optimize JPG images for the Web" width="790" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;2.3MB&lt;/strong&gt;, that's quite a bit of savings. This reduces your website's footprint without sacrificing quality.&lt;/p&gt;

&lt;p&gt;Here is the page load time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AOwz3d2C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0cl7unj1k0qn24yecze.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AOwz3d2C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0cl7unj1k0qn24yecze.jpg" alt="How to Optimize JPG images for the Web" width="790" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our average load time is &lt;strong&gt;0.0010877&lt;/strong&gt; seconds, which is our fastest yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimized with XNConvert (JPG)
&lt;/h2&gt;

&lt;p&gt;For this test, I optimized the images with &lt;a href="https://www.xnview.com/en/xnconvert/"&gt;XNConvert&lt;/a&gt; and used it to optimize the JPEGs. This is the tool I use the most because it runs in Windows, Mac, or Linux and does batch processing quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lku-Kg-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zg6rb50aafnxotmude1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lku-Kg-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zg6rb50aafnxotmude1.jpg" alt="How to Optimize JPG images for the Web" width="768" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I removed the metadata:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R5cpxcSe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmnjsvcekgxiyqkuiqds.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R5cpxcSe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmnjsvcekgxiyqkuiqds.jpg" alt="How to Optimize JPG images for the Web" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then saved them with the following settings:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TfcetGiG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ei002crcrmtd5hbbk9ae.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TfcetGiG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ei002crcrmtd5hbbk9ae.jpg" alt="How to Optimize JPG images for the Web" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the total file size for all images:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gnM969HZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z914bg8kiiyoh6ut1c0a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gnM969HZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z914bg8kiiyoh6ut1c0a.jpg" alt="How to Optimize JPG images for the Web" width="790" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;2.2MB&lt;/strong&gt;, this is the smallest we've seen yet. However, I don't expect it will significantly improve load time over the previous &lt;strong&gt;2.3MB&lt;/strong&gt; of images.&lt;/p&gt;

&lt;p&gt;Here is the page load time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rjkh1VGa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1013u28a1l06xm5dl1ce.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rjkh1VGa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1013u28a1l06xm5dl1ce.jpg" alt="How to Optimize JPG images for the Web" width="790" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The average is &lt;strong&gt;0.001085&lt;/strong&gt; seconds, which is a little faster than RIOT. Great!&lt;/p&gt;

&lt;p&gt;I highly recommend XNConvert for image optimization. But, we can take this even a step further and convert everything to Webp images. These will be significantly smaller and hopefully faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimized with XNConvert (WebP)
&lt;/h2&gt;

&lt;p&gt;So I took the same set of raw images and converted them to .webp images. This is Google's recommended image format these days, and it's easy to see why.&lt;/p&gt;

&lt;p&gt;Here are the settings I used:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JnYFfGx4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hh575l49k3sn39dgrzvq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JnYFfGx4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hh575l49k3sn39dgrzvq.jpg" alt="How to Optimize JPG images for the Web" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the total file size for all images:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w0Eub9Pb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u1ke5m8p34cho2hkypcr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w0Eub9Pb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u1ke5m8p34cho2hkypcr.jpg" alt="How to Optimize JPG images for the Web" width="790" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wow! We went from &lt;strong&gt;3.1MB&lt;/strong&gt; of images to &lt;strong&gt;1.5MB&lt;/strong&gt;. That's significant. Let's see what it does to load time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KLP7W15---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pe7owfn81ns1v331clg4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KLP7W15---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pe7owfn81ns1v331clg4.jpg" alt="How to Optimize JPG images for the Web" width="790" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The average is &lt;strong&gt;0.0010326&lt;/strong&gt; seconds, which is a new record. Great!&lt;/p&gt;

&lt;p&gt;This is something you should consider when doing image optimization on your site. Webp images are the way forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Look at the Results!
&lt;/h2&gt;

&lt;p&gt;This is the total file size for all images:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NQKVSxHn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rr25oe300s5u6fjj4lpm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NQKVSxHn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rr25oe300s5u6fjj4lpm.jpg" alt="How to Optimize JPG images for the Web" width="600" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;File Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw images&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;3.1MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Photoshop&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;3.3MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RIOT&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;2.3MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XNConvert (JPG)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;2.2MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XNConvert (Webp)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;1.5MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mjJvsyXt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6s3b19qf626nvu2b9fm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mjJvsyXt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6s3b19qf626nvu2b9fm.jpg" alt="How to Optimize JPG images for the Web" width="600" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Load Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw images&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;0.0013495&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Photoshop&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;0.001213&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RIOT&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;0.0010877&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XNConvert (JPG)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;0.001085&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XNConvert (Webp)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;0.0010326&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Optimize your images! As you can see, it makes a difference, even with this small page with 32 images on it. I will do this experiment again with a larger image set to see how the changes scale.&lt;/p&gt;

&lt;p&gt;Overall it's pretty clear that .webp images are smaller and more efficient.&lt;/p&gt;

&lt;p&gt;It's definitely worth the few minutes of extra time.&lt;/p&gt;

&lt;p&gt;Questions? Comments?  &lt;strong&gt;&lt;a href="https://twitter.com/jeremycmorgan"&gt;yell at me on Twitter!&lt;/a&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;-- Jeremy&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>html</category>
      <category>performance</category>
    </item>
    <item>
      <title>Pop!_OS 21.04 First Impressions</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Mon, 12 Jul 2021 14:39:35 +0000</pubDate>
      <link>https://dev.to/pluralsight/pop-os-21-04-first-impressions-cjh</link>
      <guid>https://dev.to/pluralsight/pop-os-21-04-first-impressions-cjh</guid>
      <description>&lt;p&gt;Pop!_OS has become one of my favorite Linux distributions over the last couple of years. It's a fantastic distro for many reasons, most of which is the way it "just works." Sorry Apple, that's not exclusive to you. System76 released version Pop!_OS 21.04 and I upgraded immediately. Here are my first impressions.&lt;/p&gt;

&lt;p&gt;I'm basing this review on a native install on my &lt;a href="https://amzn.to/2UlIjAP" rel="noopener noreferrer"&gt;Lenovo Thinkpad E590&lt;/a&gt; laptop. I use this laptop for personal projects, website maintenance and building articles/tutorials like the one you're reading now.&lt;/p&gt;

&lt;p&gt;Here's what I generally do with this laptop running Pop!_OS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend development (Golang, .NET Core)&lt;/li&gt;
&lt;li&gt;Frontend Development (recently Vue)&lt;/li&gt;
&lt;li&gt;Virtualization (small VMs)&lt;/li&gt;
&lt;li&gt;Container stuff&lt;/li&gt;
&lt;li&gt;Data stuff (MariaDB, SQLite)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this can be done extremely well with Pop!_OS. The thing I enjoy most:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;In January I slated my laptop, installed Pop!_OS, and forgot about it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm able to do the work I want to do without thinking about my operating system and configuring it. While I generally love to tinker with operating systems, if I have a machine dedicated to work, I'd prefer not to. I got tired of updating Arch Linux and diagnosing things when I fired up the machine to write some code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pop!_OS 20.10 Experience
&lt;/h2&gt;

&lt;p&gt;Version 20.10 is based off &lt;a href="https://releases.ubuntu.com/20.10/" rel="noopener noreferrer"&gt;Ubuntu 20.10&lt;/a&gt; and it's important to know that Pop!_OS is Ubuntu under the hood. But it's not just a reskinned Ubuntu.&lt;/p&gt;

&lt;p&gt;System76 knows that all the effort spent to make Pop!_OS great will make their hardware run great. So they pour efforts into the system as a whole and it shows when you use it, even if you don't have System76 hardware. (I'm still waiting for &lt;a href="https://system76.com/laptops/gazelle" rel="noopener noreferrer"&gt;the Gazelle&lt;/a&gt; to become available again so I can purchase one.)&lt;/p&gt;

&lt;p&gt;While you can use whatever desktop you want, System76 offers its own desktop environment, and that's one of the biggest draws for the distribution. It's more than a skin, but it's a pretty great skin.&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%2Fya7c3t9a8fmu8n4l94u4.jpg" 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%2Fya7c3t9a8fmu8n4l94u4.jpg" alt="Pop!_OS Linux Review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once I'd gotten used to this desktop, my productivity soared. It's easy to use and I developed habits to quickly navigate around and do what I need to do. I can bounce between Windows with ease and generally move fast. I'm not a person who cares a lot about aesthetics but it looks great. And works great.&lt;/p&gt;

&lt;p&gt;Then I found out &lt;a href="https://support.system76.com/articles/desktop-environment" rel="noopener noreferrer"&gt;they're changing the desktop&lt;/a&gt; in 21.04. Great.&lt;/p&gt;

&lt;p&gt;I was a bit concerned. I can always roll it back to the old desktop if I want, so I took the plunge and upgraded the system. YOLO and what not.&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%2Ff5y1dumgaz0ky8lb8jid.jpg" 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%2Ff5y1dumgaz0ky8lb8jid.jpg" alt="Pop!_OS Linux Review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How long did I take to get used to it? The answer surprised me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pop!_OS 21.04 Experience
&lt;/h2&gt;

&lt;p&gt;I upgraded to the new OS, and everything went as planned. Zero problems. It found my hardware, configured everything, and still had a bunch of settings from before. Painless to say the least. Microsoft, take note!&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%2Fayx4zw5gidh2e64sqe38.jpg" 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%2Fayx4zw5gidh2e64sqe38.jpg" alt="Pop!_OS Linux Review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And hey this UI looks.... oddly familiar. Yes, it's now using the OSX style dock. You could configure something similar before, but now it's a default.&lt;/p&gt;

&lt;p&gt;This doesn't bother me as I use a Mac every day for work and I like the UI. Thankfully this isn't a clone of the OSX UI though.&lt;/p&gt;

&lt;p&gt;You can &lt;strong&gt;maximize windows&lt;/strong&gt;. Yes, unlike OSX you can have Microsoft Windows style window handling. Love 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%2Fizxqa5uo0gxc1vtn4aaf.jpg" 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%2Fizxqa5uo0gxc1vtn4aaf.jpg" alt="Pop!_OS Linux Review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It also offers a ton of customization. You can make it like OSX, like Windows, or like neither. You can take the best of both worlds if you like.&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%2F5un88zrsol2yamfqu61o.jpg" 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%2F5un88zrsol2yamfqu61o.jpg" alt="Pop!_OS Linux Review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bottom line: I jumped in and made it what I wanted it to be. Once I got to work I found the new desktop environment very fluid and fast. I adapted to the changes quickly.&lt;/p&gt;

&lt;p&gt;Also, I love the window tiling:&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%2Fon0obqw9wov2u0fad8jp.jpg" 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%2Fon0obqw9wov2u0fad8jp.jpg" alt="Pop!_OS Linux Review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can't remember an operating system upgrade I've done that went so smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;An operating system upgrade is a risky and sometimes annoying process. Not so much with Pop!_OS 21.04. It's easy. I didn't have any hardware or configuration problems and I love the new desktop. I'm already incredibly used to it.&lt;/p&gt;

&lt;p&gt;If you're thinking about &lt;a href="https://support.system76.com/articles/upgrade-pop" rel="noopener noreferrer"&gt;the upgrade&lt;/a&gt; do it. If you've never used Pop!_OS before, now's the time. I recommend it frequently for new Linux users because it's so easy to install and use. Now it's one step closer to being the ultimate replacement for OSX or Windows if you want to leave those platforms.&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%2Fywle61prrw5cfxnq30f1.jpg" 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%2Fywle61prrw5cfxnq30f1.jpg" alt="Pop!_OS Linux Review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's also highly performant and configurable like other versions of Linux. (&lt;a href="https://browser.geekbench.com/v5/cpu/8675566" rel="noopener noreferrer"&gt;Geekbench&lt;/a&gt;) You aren't giving up either of those things to have an easy painless experience. So check it out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://bit.ly/PopOSDownload" rel="noopener noreferrer"&gt;Download Pop_OS! 21.04 Here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Questions or comments? &lt;strong&gt;&lt;a href="http://bit.ly/JeremyCMorgan" rel="noopener noreferrer"&gt;Yell at me!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;--Jeremy&lt;/p&gt;

</description>
      <category>linux</category>
      <category>productivity</category>
      <category>development</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>How to Run Windows 10 on the Apple M1</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Sat, 05 Jun 2021 17:24:48 +0000</pubDate>
      <link>https://dev.to/pluralsight/how-to-run-windows-10-on-the-apple-m1-1he7</link>
      <guid>https://dev.to/pluralsight/how-to-run-windows-10-on-the-apple-m1-1he7</guid>
      <description>&lt;p&gt;In January I picked up an Apple M1 Mac Mini. I immediately put a bunch of miles on it. It does much of what I need it to do well. But the one thing it doesn't do that I need it to: virtualization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IpXZtms7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jr69lp5aqn8a2rxzyxhp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IpXZtms7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jr69lp5aqn8a2rxzyxhp.jpg" alt="Windows 10 on Apple M1" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This stands to reason: The M1 is an ARM processor and nearly everything running on this machine uses &lt;a href="https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment"&gt;Rosetta&lt;/a&gt; translation technology to translate x86_64 instructions to ARM. It's so well designed and tightly integrated with the hardware that some x86 applications run &lt;em&gt;faster&lt;/em&gt; on the M1 than they do on Intel Macs. It's incredible. But it doesn't support something as complex as an x86 virtual machine... yet.&lt;/p&gt;

&lt;p&gt;But I set up a couple VMs on here, and I'll show you how to do it, and what you need to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One: Parallels
&lt;/h2&gt;

&lt;p&gt;I'm not a &lt;a href="https://www.parallels.com/"&gt;Parallels&lt;/a&gt; expert. In fact, I purchased it for the first time, installed it, then &lt;a href="https://www.twitch.tv/videos/1016216011"&gt;started up a live stream&lt;/a&gt; to try it out.&lt;/p&gt;

&lt;p&gt;You can't run the standard version of Parallels on the M1. You'll need to download &lt;a href="https://www.parallels.com/blogs/parallels-desktop-apple-silicon-mac/"&gt;Parallels for Mac with Apple M1 Chip&lt;/a&gt;. This is a version specially built to work with Rosetta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iGkA54Kx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cblh6aqgb56hnmqdldd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iGkA54Kx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cblh6aqgb56hnmqdldd.jpg" alt="Windows 10 on Apple M1" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok cool, so Parallels runs on the M1, that means we can run any Virtual Machine now right?&lt;/p&gt;

&lt;p&gt;No. Not exactly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K4v1v8TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wf4jejekodw1lrlmzktk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K4v1v8TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wf4jejekodw1lrlmzktk.jpg" alt="Windows 10 on Apple M1" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, I wanted to run Windows on this thing. However, we have no option for Bootcamp, and I can't download a x86_64 Windows 10 ISO and install it.&lt;/p&gt;

&lt;p&gt;So what do we do?&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two: Get the Windows 10 for ARM Preview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U0sDc_Q7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sue9ox0pzji082r5euwb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U0sDc_Q7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sue9ox0pzji082r5euwb.jpg" alt="Windows 10 on Apple M1" width="720" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewARM64"&gt;Windows 10 for ARM preview&lt;/a&gt; will run in Parallels. It's a Windows Insider preview. If you're not a Windows Insider, you can &lt;a href="https://insider.windows.com/"&gt;sign up here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can download and install it in a few clicks just like any version of Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three: Enjoy Windows 10 on the M1
&lt;/h2&gt;

&lt;p&gt;This is a preview version of Windows 10 for ARM processors. Here are some things you need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is not officially supported on the M1&lt;/li&gt;
&lt;li&gt;It cannot be activated (for now)&lt;/li&gt;
&lt;li&gt;It runs x86_64 apps under emulation (the reverse of Rosetta)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So it will run, but it's not perfect. Let's talk about how it went.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Impressions
&lt;/h2&gt;

&lt;p&gt;So in my &lt;a href="https://www.twitch.tv/videos/1016216011"&gt;live stream&lt;/a&gt; I installed Windows 10. It installed fairly quickly. I installed several x86 applications and set up my machine for some front end development. What I noticed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I can go full screen&lt;/li&gt;
&lt;li&gt;It runs fairly snappy&lt;/li&gt;
&lt;li&gt;It "feels" like any other version of Windows&lt;/li&gt;
&lt;li&gt;Can't do much for memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I then ran a &lt;a href="https://www.geekbench.com/"&gt;Geekbench&lt;/a&gt; test on it. It was less than impressive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IIFsyOCw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp5z472ipfdd4su335fo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IIFsyOCw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp5z472ipfdd4su335fo.jpg" alt="Windows 10 on Apple M1" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Less than half on the Single-Core score and about 12% of the native Multi-Core score. Ouch.&lt;/p&gt;

&lt;p&gt;Full scores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://browser.geekbench.com/v5/cpu/7797139"&gt;Mac M1 Running Windows 10 in Parallels&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://browser.geekbench.com/v5/cpu/5746625"&gt;Mac M1 in OSX Big Sur&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are several reasons for this. One being going through &lt;em&gt;two translation layers&lt;/em&gt;. So running Geekbench "natively" on Big Sur isn't even truly native, it's running through the Rosetta system, but pretty fast.&lt;/p&gt;

&lt;p&gt;In Windows 10, it's a x86_64 app translated to ARM, going through Parallels back as x86_64 then translated again for native ARM. Yikes.&lt;/p&gt;

&lt;p&gt;That being said, the machine didn't feel all that slow. I should note &lt;em&gt;you won't be able to assign much memory to this&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is because the M1 is limited, in my case I have 16G of memory, and about 10G is being used up before I even start the Windows machine. So, you can add virtual memory at your own peril.&lt;/p&gt;

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

&lt;p&gt;This is how you can run Windows 10 on your new Apple M1. I haven't spent a lot of time with it yet, but you can do basic "Windows stuff" on your M1 if you really need it. If there are a few applications you need to run, it can probably handle it. I don't see a compelling reason to run Windows 10 this way as a full-time machine. You're giving up memory and CPU power for it. You won't be able to run games so don't even try it.&lt;/p&gt;

&lt;p&gt;But it's nice to at least have this option available if you need it.&lt;/p&gt;

&lt;p&gt;Have you tried this? &lt;a href="http://bit.ly/JeremyCMorgan"&gt;Let me know how it goes&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>windows</category>
      <category>productivity</category>
    </item>
    <item>
      <title>It's Tech Skills Day!</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Thu, 22 Apr 2021 14:17:04 +0000</pubDate>
      <link>https://dev.to/pluralsight/it-s-tech-skills-day-13n7</link>
      <guid>https://dev.to/pluralsight/it-s-tech-skills-day-13n7</guid>
      <description>&lt;p&gt;Hello friends! It's Tech Skills Day, and I want you to join me!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Tech Skills Day is an annual holiday that brings the global tech community together to honor the spirit of lifelong learning, helping each other grow and celebrating what technology can create&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  &lt;a href="http://plrsig.ht/TSD21Jeremy" rel="noopener noreferrer"&gt;It's a 100% FREE Virtual Event. Click here to join.&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;This year &lt;a href="https://twitter.com/cassidoo" rel="noopener noreferrer"&gt;Cassidy Williams&lt;/a&gt; and I are hosting Tech Skills day, and it's going to be fantastic. Tech Skills Day combines valuable content, inspired experiences and thought-provoking narratives together in one incredible virtual experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who will be at Tech Skills Day?
&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%2Fw4b315gjwdp8ulj7tj35.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%2Fw4b315gjwdp8ulj7tj35.png" alt="Levar Burton"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Levar Burton
&lt;/h3&gt;

&lt;p&gt;Multi-talented actor LeVar Burton is best known for his role as Lieutenant Commander Geordi Laforge in syndicated science fiction hit Star Trek: The Next Generation and his role as "Kunta Kinte" in television miniseries Roots, which broke viewing records and inspired a national discussion on the issue of race. He is also host and co-producer of the long running, Emmy-winning PBS educational series Reading Rainbow.&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%2F58embrpe7wmgn2m48m20.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%2F58embrpe7wmgn2m48m20.png" alt="Scott Hanselman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scott Hanselman
&lt;/h3&gt;

&lt;p&gt;Scott Hanselman is a web developer, Pluralsight author and speaker. He works in open source on ASP.NET and the Azure Cloud for Microsoft out of his home office in Portland. Scott has three podcasts, has written a number of books and spoken in person to almost a half million developers worldwide.&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%2Fg96dqf3rvv40gqoya8ml.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%2Fg96dqf3rvv40gqoya8ml.png" alt="Deborah Kurata"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deborah Kurata
&lt;/h3&gt;

&lt;p&gt;Deborah Kurata is a software developer, consultant, conference speaker and Pluralsight author. For her work in support of software developers, she has been recognized with the Microsoft Most Valuable Professional (MVP) award and is a Google Developer Expert (GDE).&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%2Fypmmyezf01s03wgc4ug8.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%2Fypmmyezf01s03wgc4ug8.png" alt="John Papa"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  John Papa
&lt;/h3&gt;

&lt;p&gt;John Papa is a Principal Cloud Advocate with Microsoft and an alumni of the Google Developer Expert, Microsoft Regional Director and MVP programs. John is a co-host of the popular Adventures in Angular podcast and author of the Angular Style Guide, several books and many popular Pluralsight courses.&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%2Fyv5g2ptuu6mnhp7iizrw.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%2Fyv5g2ptuu6mnhp7iizrw.png" alt="Troy Hunt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Troy Hunt
&lt;/h3&gt;

&lt;p&gt;Troy Hunt is an Australian Microsoft Regional Director and Microsoft Most Valuable Professional for Developer Security. He also creates courses for Pluralsight and travels the world speaking at events and teaching technology professionals. You'll regularly find him in the press talking about security and even testifying before the U.S. Congress on the impact of data breaches.&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%2Fkfeit5zji5y3977oxlof.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%2Fkfeit5zji5y3977oxlof.png" alt="April Speight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  April Speight
&lt;/h3&gt;

&lt;p&gt;April Speight is an author, developer and style aficionado from Los Angeles. She began her career in luxury fashion as a menswear stylist and visual merchandiser, but in 2013, she made her transition to working in IT. She’s since been dabbling in coding (primarily Python, some C# and JavaScript) and has found her forever home within Developer Relations at Microsoft.&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%2Fs7flbmkggjs32ee1e75p.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%2Fs7flbmkggjs32ee1e75p.png" alt="Mona Chalabi"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mona Chalabi
&lt;/h3&gt;

&lt;p&gt;Mona Chalabi is a data journalist in New York. Her work has appeared in The New Yorker, The New York Times, The Guardian, as well as on NPR, Gimlet, Netflix and many more. Before she became a journalist, Mona worked with large data sets in jobs at the Bank of England, Transparency International and the International Organization for Migration.&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%2Fm1wxmdmt3hmowshh2duq.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%2Fm1wxmdmt3hmowshh2duq.png" alt="Cassidy Williams"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cassidy Williams
&lt;/h3&gt;

&lt;p&gt;Cassidy Williams is a Principal Developer Experience Engineer at Netlify. She's active in the developer community and one of Glamour Magazine's 35 Women Under 35 Changing the Tech Industry and LinkedIn's Top Professionals 35 &amp;amp; Under.&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%2Fjgr6jphpf6vmbqoys4ya.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%2Fjgr6jphpf6vmbqoys4ya.png" alt="Jeremy Morgan"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Jeremy Morgan
&lt;/h3&gt;

&lt;p&gt;Pluralsight Developer Evangelist, tech blogger, and passionate geek. Jeremy likes to stay immersed with the latest in .NET development and DevOps during the day, and tinkers with Linux machines and microcontrollers at night.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let's Go!
&lt;/h2&gt;

&lt;p&gt;So join me today for this fun and exciting time with these tech superstars!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="http://plrsig.ht/TSD21Jeremy" rel="noopener noreferrer"&gt;Watch Tech Skills Day Live Now!&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;See you there!!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Pluralsight is FREE in April!!</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Sat, 10 Apr 2021 17:13:52 +0000</pubDate>
      <link>https://dev.to/pluralsight/pluralsight-is-free-in-april-57el</link>
      <guid>https://dev.to/pluralsight/pluralsight-is-free-in-april-57el</guid>
      <description>&lt;p&gt;Great news!! Pluralsight is FREE for the entire month of April! If you've been wanting to skill up, and have never tried the platform, here's your chance!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://bit.ly/PSFreeApril2021" rel="noopener noreferrer"&gt;Try out Pluralsight Now!&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;If you sign up now, here are a few things you can do to take advantage of Free April. Here are some things you can do &lt;strong&gt;right now&lt;/strong&gt; if you sign up and get started.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Learn Angular
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://bit.ly/2k1RW5S" rel="noopener noreferrer"&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%2F4vwkg35uael0iausnqnh.jpg" alt="Free Pluralsight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the &lt;a href="http://bit.ly/2k1RW5S" rel="noopener noreferrer"&gt;Angular Getting Started course&lt;/a&gt;, you can finally jump in and learn some Angular! Deborah Kurata teaches things like nobody else I know. Her expert instruction will get you on the right track.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Artificial Intelligence
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://bit.ly/3g0bh28" rel="noopener noreferrer"&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%2Fpr8vm1o45bqwvoypfgv7.jpg" alt="Free Pluralsight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Curious about AI? Do you want to get into it but don't know where to start?  &lt;a href="https://bit.ly/3g0bh28" rel="noopener noreferrer"&gt;Artificial Intelligence: The Big Picture of AI&lt;/a&gt; will get you where you need to go fast!&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Learn C
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://bit.ly/PluralsightCSPath" rel="noopener noreferrer"&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%2Fts4u871p03ket970s9qr.jpg" alt="Free Pluralsight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;C# is one of my favorite languages of all time. I absolutely love coding in it, and if it's something you've been curious about &lt;a href="http://bit.ly/PluralsightCSPath" rel="noopener noreferrer"&gt;The C# Path at Pluralsight&lt;/a&gt; will get you where you need to be, FAST.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Get Started with Python
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://bit.ly/3d3PAMG" rel="noopener noreferrer"&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%2Fynrwiek0jdwnsgbmxg7r.jpg" alt="Free Pluralsight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OK if you know me, you already know about my love of Python. The ultimate “glue” language that empowers you to do SO many things. You can take this &lt;a href="https://bit.ly/3d3PAMG" rel="noopener noreferrer"&gt;Getting Started with Python&lt;/a&gt; course and hit the ground running! You'll be amazed at what you can accomplish with this.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Learn Some React
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://bit.ly/2m3rzx9" rel="noopener noreferrer"&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%2Fakwh5hz6xjdzyshstibn.jpg" alt="Free Pluralsight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React is undoubtedly one of the hottest front end frameworks out there, and it's taking over the world. &lt;a href="http://bit.ly/2m3rzx9" rel="noopener noreferrer"&gt;React Getting Started&lt;/a&gt; is the course that will launch you into this world head first and you'll understand the basics of React FAST.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's So Great About Pluralsight?
&lt;/h2&gt;

&lt;p&gt;You might ask, what's the difference between Pluralsight and just going on to YouTube and learning stuff?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Courses are Organized&lt;/strong&gt; - Finding tutorials and videos online, and trying to piece things together is difficult. It's tough to know what you need to know, find it all, and get full coverage of a topic. Pluralsight does that for you and puts together a solid package of the right knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Taught by Experts&lt;/strong&gt; - Not anyone can just record a few videos and put a course up on Pluralsight. Expert authors are recruited from the field and vetted. They are experienced, knowledgeable folks who have done real work in the field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Courses Meet Strict Standards&lt;/strong&gt; - Every course goes through a quality control process to make sure they are clear and accurate. The content is thoroughly checked to make sure you're getting accurate, useful information about a topic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://bit.ly/PSFreeApril2021" rel="noopener noreferrer"&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%2Fye7mk61bs0wg3fke47kg.jpg" alt="Free Pluralsight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Take a Course&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check Your Knowledge with SkillIQ&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get HANDS ON with Cloud Labs and Sandboxes&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what are you waiting for? Give it a shot! It's Free during the month of April.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://bit.ly/PSFreeApril2021" rel="noopener noreferrer"&gt;Try out Pluralsight Now!&lt;/a&gt;
&lt;/h1&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>What Do You Do for a Living Anyway?</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Sat, 06 Mar 2021 18:34:39 +0000</pubDate>
      <link>https://dev.to/pluralsight/what-do-you-do-for-a-living-anyway-14d7</link>
      <guid>https://dev.to/pluralsight/what-do-you-do-for-a-living-anyway-14d7</guid>
      <description>&lt;p&gt;I get asked this question a lot. My friends and family barely understand what I do, and my title &lt;strong&gt;Technical Marketing Manager&lt;/strong&gt; doesn’t help at all. So I’ll try to explain it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: &lt;em&gt;My job is awesome. I build cool stuff, talk with amazing people, and have fun. If you want to join me, &lt;a href="https://bit.ly/PSDevEvangelist"&gt;click here&lt;/a&gt; and let’s talk&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In 2002, I went from being a Network Administrator/IT person to a developer. With a background in administration, I would take on those duties with most jobs I had. So for around 18 years my job description was "write software and keep systems running."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s7LMxu82--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jgsoaznodjngeemebcnz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s7LMxu82--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jgsoaznodjngeemebcnz.jpg" alt="Devrel at Pluralsight" width="720" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When asked, "what do you do for a living?"&lt;/p&gt;

&lt;p&gt;My answer was "I write software for ____&lt;strong&gt;&lt;em&gt;" or "I lead a team that writes software for _&lt;/em&gt;&lt;/strong&gt;____"&lt;/p&gt;

&lt;p&gt;It was easy to explain. Simple to understand. Most non-technical people could grasp it and move the conversation to another topic.&lt;/p&gt;

&lt;p&gt;My current role is not so easy to describe. But it’s certainly more interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pluralsight: Customer to Author to Employee
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6L9TScpo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1on0jl9m9e7eda569y6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6L9TScpo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1on0jl9m9e7eda569y6.jpg" alt="DevRel at Pluralsight" width="674" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I discovered Pluralsight in 2012 when I was an Engineer looking for ways to "sharpen my axe" and get better at my job. I fell in love with the platform. The first course I took was by the late, great &lt;a href="https://www.pluralsight.com/authors/scott-allen"&gt;Scott Allen&lt;/a&gt;. He broke things down in a clear and understandable way. It inspired me immediately.&lt;/p&gt;

&lt;p&gt;I’d always loved teaching those around me, but I never pictured myself as an "instructor" until that point. I’d always imagined the loud, egotistical, showboat professor types and never identified with that. Scott’s relaxed, ego-free method of delivery showed there was room for someone like me in this space. Years later, I shared this with him over lunch. He’ll always be one of my heroes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sESdSKyO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ri48e66fnp7rtsccohnv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sESdSKyO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ri48e66fnp7rtsccohnv.jpg" alt="DevRel at Pluralsight" width="720" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In 2016 I auditioned to be a Pluralsight author and was accepted. My first course experience was rough, but I got through it and enjoyed it. I particularly enjoyed working with Pluralsight. They treated me very well, and the people were great to work with. So when an opportunity came up at Pluralsight as a Technical Marketing Manager, I was stoked.&lt;/p&gt;

&lt;p&gt;Imagine interviewing with a company where you had four years of exposure to the company, culture, and people. I already had an excellent preview. If it were any other company, it’s unlikely I would have accepted walking away from day-to-day coding. It was risky, but it was the best move of my career.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Marketing Manager
&lt;/h2&gt;

&lt;p&gt;My job when I started was much different than it is now. What it has evolved into is a mission-driven position that is fun, motivating, and fulfilling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jyohn6oQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7mqn26ylw77srhvqu2ej.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jyohn6oQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7mqn26ylw77srhvqu2ej.jpg" alt="DevRel at Pluralsight" width="720" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every day I get to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Host a &lt;a href="http://bit.ly/AllHandsOnTech"&gt;podcast&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Build instructional / fun videos&lt;/li&gt;
&lt;li&gt;Present new tech at conferences and meetups&lt;/li&gt;
&lt;li&gt;Write articles&lt;/li&gt;
&lt;li&gt;Build presentations&lt;/li&gt;
&lt;li&gt;Give input to marketing materials&lt;/li&gt;
&lt;li&gt;Speak with brilliant, passionate leaders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s my core mission:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share what I’ve learned in 18 years of development&lt;/li&gt;
&lt;li&gt;Demystify new technology and present it in a way that makes sense&lt;/li&gt;
&lt;li&gt;Speak with others who share their wisdom and knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the "North Star":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Help technologists get better at their job&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kOgT4lTw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7mr2iwcvbrxfthg5klu8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kOgT4lTw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7mr2iwcvbrxfthg5klu8.jpg" alt="DevRel at Pluralsight" width="720" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s what Pluralsight is all about. We make sure that anyone coming to Pluralsight looking for help to improve their skills will succeed. They will get relevant, accurate information and a path to success. Which is part of what makes this job so fun. The "ace in the hole" is knowing I'm helping promote the most solid toolset for engineers in the world.&lt;/p&gt;

&lt;p&gt;I work with smart, talented, and passionate people. I get to talk tech with people every day, some who I’m teaching and some are teaching me. I also get to work with some of the most renowned leaders in technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Team is Expanding
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6VE01TXj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhl6winuxmy1j5lyhm1p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6VE01TXj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhl6winuxmy1j5lyhm1p.jpg" alt="DevRel at Pluralsight" width="720" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re looking for another "Developer Evangelist" to join the team. Someone who is passionate about technology, teaching, and the tech community. We are looking for someone who wants to create great learner content. Someone who loves learning new things and makes sure hears about it. Someone who wants to engage with leaders and add to the body of knowledge in tech.&lt;/p&gt;

&lt;p&gt;If you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Love to write and speak about your work&lt;/li&gt;
&lt;li&gt;Get excited about connecting with the dev community&lt;/li&gt;
&lt;li&gt;Are passionate about learning and continuous improvement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then we want to hear from you. &lt;a href="https://bit.ly/PSDevEvangelist"&gt;Full Description Here&lt;/a&gt;. Go ahead and SMASH THAT APPLY BUTTON!!&lt;/p&gt;

&lt;p&gt;You can ask me anything or apply for the position. I’d love to &lt;a href="http://bit.ly/JeremyCMorgan"&gt;hear from you&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>career</category>
      <category>devjournal</category>
    </item>
  </channel>
</rss>
