<?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>Forem: Michael Currin</title>
    <description>The latest articles on Forem by Michael Currin (@michaelcurrin).</description>
    <link>https://forem.com/michaelcurrin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F48064%2F82de4775-b05d-42fe-947a-a2f2088c970b.png</url>
      <title>Forem: Michael Currin</title>
      <link>https://forem.com/michaelcurrin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/michaelcurrin"/>
    <language>en</language>
    <item>
      <title>Features of popular GenAI platforms in 2025</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Tue, 18 Mar 2025 10:00:20 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/feature-comparison-of-popular-genaillm-platforms-2jai</link>
      <guid>https://forem.com/michaelcurrin/feature-comparison-of-popular-genaillm-platforms-2jai</guid>
      <description>&lt;p&gt;A comparison of popular GenAI tools and what their capabilities are, so you can pick one or more tools for your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links to services
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://chatgpt.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; by OpenAI.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://copilot.microsoft" rel="noopener noreferrer"&gt;Microsoft Copilot&lt;/a&gt;. Previously named &lt;em&gt;Bing Chat&lt;/em&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;a href="http://gemini.google.com/" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt; by Google. Previously named &lt;em&gt;Google Bard&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://claude.ai/" rel="noopener noreferrer"&gt;Claude&lt;/a&gt; by Anthropic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MS Copilot should not be confused with Microsoft 365 Copilot (formerly office) or Microsoft's coding AIs such as &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt; or the &lt;a href="https://code.visualstudio.com/docs/copilot/overview" rel="noopener noreferrer"&gt;VS Code Copilot&lt;/a&gt; extension. MS Copilot can also be accessed via the Copilot sidebar in &lt;a href="https://www.microsoft.com/en-us/edge/download" rel="noopener noreferrer"&gt;MS Edge&lt;/a&gt; browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;Last updated March 2025, here is what you can do on each platform on the &lt;strong&gt;free tier&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For more details including screenshots and sample prompts, see &lt;a href="https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/artificial-intelligence/feature-comparison.html" rel="noopener noreferrer"&gt;Feature comparison&lt;/a&gt; on my Dev Cheatsheets site.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Functionality&lt;/th&gt;
&lt;th&gt;ChatGPT&lt;/th&gt;
&lt;th&gt;Copilot&lt;/th&gt;
&lt;th&gt;Google Gemini&lt;/th&gt;
&lt;th&gt;Claude&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model used&lt;/td&gt;
&lt;td&gt;GPT-4o&lt;/td&gt;
&lt;td&gt;Microsoft Prometheus&lt;/td&gt;
&lt;td&gt;Gemini 2.0&lt;/td&gt;
&lt;td&gt;Claude3.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile app available&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API available&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search the web&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File upload&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins or extensions&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Drive access&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text-to-speech output&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speech recognition&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌ web, ✅ mobile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voice call mode&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌ web, ✅ mobile&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reasoning (deep think, think before responding)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate images with AI&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canvas/artifacts (output document or code as a file)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Live app preview (HTML page in sidepanel)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dataviz (inline graphs using Python code)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory about you&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Cover image
&lt;/h2&gt;

&lt;p&gt;Generated using Microsoft Bing Image Creator.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>llm</category>
      <category>openai</category>
    </item>
    <item>
      <title>AI: Your Coding Boost or Your Crutch? Here’s How to Balance It</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Thu, 27 Feb 2025 10:17:11 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/ai-your-coding-boost-or-your-crutch-heres-how-to-balance-it-kgf</link>
      <guid>https://forem.com/michaelcurrin/ai-your-coding-boost-or-your-crutch-heres-how-to-balance-it-kgf</guid>
      <description>&lt;p&gt;AI can supercharge your coding skills, but if rely on it too much as a crutch they can get weaker too. How can we tackle this?&lt;/p&gt;

&lt;p&gt;I keep hearing about devs, from junior to experienced, who move quickly by getting answers from the AI but don’t understand the reasons or tradeoffs of what they wrote. Their error rate is higher and they even forget how to do syntax.&lt;/p&gt;

&lt;p&gt;I also hear that our determination and emotional regulation drops with excessive AI use. Such that when we hit a wall for a problem that AI can't solve or the internet is off, we don't know anymore how to sit with that uncomfortable feeling and how to patiently seek a solution without aid.&lt;/p&gt;

&lt;p&gt;If you want to learn, you have to "suffer". You can read all you like about coding, fitness, or music, but if you want to grow you have to think about the coding you're typing, sweat from the exercise, or play the notes.&lt;/p&gt;

&lt;p&gt;How can we do this practically?&lt;/p&gt;

&lt;p&gt;I've followed an approach from a friend. Let the AI do the very well-defined routine tasks, treat it like a junior engineer that has access to the whole internet but needs a lot of guidance and checking.&lt;/p&gt;

&lt;p&gt;Here's another tip I heard this week. If you want to learn, do not let AI generate the code answers, but only use it to explain things to you. Use it as your personal assistant or copilot to ask about concepts or code you encounter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cover image credit
&lt;/h2&gt;

&lt;p&gt;Photo by Markus Winkler: &lt;a href="https://www.pexels.com/photo/ai-terminology-in-letter-tiles-on-wooden-desk-30901568/" rel="noopener noreferrer"&gt;https://www.pexels.com/photo/ai-terminology-in-letter-tiles-on-wooden-desk-30901568/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>learning</category>
      <category>chatgpt</category>
      <category>growth</category>
    </item>
    <item>
      <title>AI as a language teacher</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Tue, 26 Dec 2023 10:06:30 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/ai-as-a-language-teacher-11pe</link>
      <guid>https://forem.com/michaelcurrin/ai-as-a-language-teacher-11pe</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;How to turn a chatbot into an interactive and informative language assistant&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have a passion for languages and am excited to learn Dutch (in the Netherlands) as well as bits of other languages. AI tools like ChatGPT have made my learning process faster, more fun, and personalized. I'm here to share insights so you can achieve that too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overview:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why use AI?&lt;/li&gt;
&lt;li&gt;
Ways to use AI as a language tutor

&lt;ul&gt;
&lt;li&gt;Conversational practice&lt;/li&gt;
&lt;li&gt;Roleplaying scenarios&lt;/li&gt;
&lt;li&gt;Engaging in debates&lt;/li&gt;
&lt;li&gt;Learning about country and culture&lt;/li&gt;
&lt;li&gt;Translate content&lt;/li&gt;
&lt;li&gt;Creative writing&lt;/li&gt;
&lt;li&gt;Generate words&lt;/li&gt;
&lt;li&gt;Generate phrases&lt;/li&gt;
&lt;li&gt;Translating across languages&lt;/li&gt;
&lt;li&gt;Phonetic pronunciation assistance&lt;/li&gt;
&lt;li&gt;
Ask for explanations

&lt;ul&gt;
&lt;li&gt;Slang&lt;/li&gt;
&lt;li&gt;Abbreviations&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Requesting course outlines&lt;/li&gt;
&lt;li&gt;Play a game&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Choose an AI tool&lt;/li&gt;
&lt;li&gt;Cover image&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why use AI?
&lt;/h2&gt;

&lt;p&gt;Here are some challenges I encountered learning a language which I overcame with AI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Duolingo, vocabulary acquisition for daily interactions happens very slow, the content often doesn't reflect casual usage or everyday purposes, and it only covers a single sentence at a time.&lt;/li&gt;
&lt;li&gt;Google Translate lacks context and is often too literal.&lt;/li&gt;
&lt;li&gt;Difficulty finding engaging content that is between beginner and intermediate levels.&lt;/li&gt;
&lt;li&gt;It was challenging to search online for language concepts when you observe grammar or informal speech but don't how to label it.&lt;/li&gt;
&lt;li&gt;A need for specific phrases beyond basics, like dentist appointments or describing your specific hobbies and your home country.&lt;/li&gt;
&lt;li&gt;Uncertainty about my learning path structure and identifying my weaknesses.&lt;/li&gt;
&lt;li&gt;A desire for having someone to practice with over text or voice, any time of day, for as long as a want. Especially on a train commute.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ways to use AI as a language tutor
&lt;/h2&gt;

&lt;p&gt;Using AI, we can overcome the problems discussed above in a  Below are some approaches I recommend. The responses shown here are all from ChatGPT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conversational practice
&lt;/h3&gt;

&lt;p&gt;The simplest is just to start to talking to the AI in the language you want to learn and see the response in the same language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hoi, ik ben Michael. Hoe heet jij?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Hoi Michael! Ik ben ChatGPT. Hoe gaat het met je vandaag?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask it at the start to correct your grammar and spelling if you make mistakes.&lt;/p&gt;

&lt;p&gt;If you don't understand messages you get, ask for a translation of what was just said. Or ask the AI to give your answers in the target language and English in brackets for every message to you.&lt;/p&gt;

&lt;p&gt;Give a topic or ask for topic suggestions or to pick one for you.&lt;/p&gt;

&lt;p&gt;Get it to focus on asking you questions so keep you on your toes for responding to it. This might feel unnatural after a while though.&lt;/p&gt;

&lt;h3&gt;
  
  
  Roleplaying scenarios
&lt;/h3&gt;

&lt;p&gt;Ask to get the AI to get to know you, like as a best friend, acquaintance, or date. Get it to ask you some icebreaker questions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ask me a icebreaker question in beginner level Dutch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Natuurlijk! Wat zou jouw superkracht zijn als je er één mocht kiezen?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unforunately this case is not actually beginner level as asked, so you can try emphasizing that you want "basic vocabularly and grammary only". Or try Bing if you first tried ChatGPT.&lt;/p&gt;

&lt;p&gt;If you have something more technical to prepare for, like a job interview or questions to expect for a presentation, get the AI to take on one of these roles. This will give more of a sense of interactivity and unpredictability of real life (unlike non-AI tools) while also giving relevant and knowledgable questions on your topic (it can be hard to find someone in-person who has this expertise).&lt;/p&gt;

&lt;p&gt;Get the AI to talk you through a situation you want to prepare for. e.g. Interactions with a waiter, booking a flight online, phoning to make a doctor's appointment, or giving directions to someone. If you are stuck for ideas, get the AI to come up with situations based on your intention for being in the country or speaking the language. Such as when you are abroad or a holiday, studying or relocating.&lt;/p&gt;

&lt;h3&gt;
  
  
  Engaging in debates
&lt;/h3&gt;

&lt;p&gt;Have a debate on a current topic. Such as the impact of social media, AI, animal testing, free education, or veganism. Ask the AI to generate some topics that are popular or even ones it can find in this month's news.&lt;/p&gt;

&lt;p&gt;I got this idea from &lt;a href="https://talkpal.ai"&gt;TalkPal.ai&lt;/a&gt;, which has Debate as a premium feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning about country and culture
&lt;/h3&gt;

&lt;p&gt;Are you interested in learning about the country you're in and how the culture? Ask the AI to give you some informative content about food, places, shopping, and so on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I moved to the Netherlands! Give me a sentence talking about must-see attractions, food, and culture. Write it in Dutch and make it easy for a beginner to understand. Give me the English in brackets afterwards.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Ik wil graag de molens in Kinderdijk zien, de stroopwafels proeven en de Nederlandse cultuur ervaren!" (I want to see the windmills in Kinderdijk, taste the stroopwafels, and experience Dutch culture!)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Translate content
&lt;/h3&gt;

&lt;p&gt;Ask for translations and explanations about them. Whether from the conversation already in progress, or from text that you copy and paste. Give it an entire page if you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;what does this mean in Dutch?

ter wereld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Ter wereld" in Dutch translates to "in the world" or "on Earth" in English. It's used to refer to something happening or existing within the scope of the entire world or on a global scale.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Google Translate can be very literal and does not always capture the way a native would express themselves. The AI will have a better understanding of the context and intent and multiple meanings of a word.&lt;/p&gt;

&lt;p&gt;If you have to submit a formal letter or you want to send a message to your neighbor on Whatsapp, ask the AI to check your content for errors or suggest improvements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creative writing
&lt;/h3&gt;

&lt;p&gt;Ask it to write a story at a level (e.g. absolute beginner, beginner, beginner-to-intermediate, or intermediate).&lt;/p&gt;

&lt;p&gt;Pick a theme or genre that is interesting for you.  Ask it to write a story one paragraph or one chapter at a time, and on subsequent prompts say "next" or "more".&lt;/p&gt;

&lt;p&gt;If the story gets boring you can ask for a plot twist or ask it to go in a certain direction.&lt;/p&gt;

&lt;p&gt;Ask for explanations of words if you get stuck (it is also smart enough to explain the word in the context of the sentence).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pitch me 3 bullet points of a kids story. In Dutch. Give me the English in brackets afterwards
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Tim, een nieuwsgierige jongen, vindt een betoverde schatkist in het bos. (Tim, a curious boy, discovers an enchanted treasure chest in the forest.)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;In de kist zit een kaart die leidt naar een magische wereld vol pratende dieren. (Inside the chest, there's a map leading to a magical world inhabited by talking animals.)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Samen met zijn nieuwe dierenvrienden gaat Tim op avontuur om een betovering te verbreken en de verdwenen koning terug te vinden. (With his newfound animal friends, Tim embarks on a quest to break a curse and find the missing king.)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over about a week, I worked with the AI to write kids adventure story in Dutch, where every day I asked for a new chapter (which ends up being a page long) and then I asked it questions on the words.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate words
&lt;/h3&gt;

&lt;p&gt;Ask for a table or list of words in a setting or theme.&lt;/p&gt;

&lt;p&gt;If the language you are learning has a gender, ask for that too. e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Give me a list as a table with columns for Dutch and English. Make sure to include the definite article in brackets before.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dutch&lt;/th&gt;
&lt;th&gt;English&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;(de) boom&lt;/td&gt;
&lt;td&gt;(the) tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(het) huis&lt;/td&gt;
&lt;td&gt;(the) house&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(de) auto&lt;/td&gt;
&lt;td&gt;(the) car&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(het) boek&lt;/td&gt;
&lt;td&gt;(the) book&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(de) kat&lt;/td&gt;
&lt;td&gt;(the) cat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(het) vliegtuig&lt;/td&gt;
&lt;td&gt;(the) airplane&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(de) tafel&lt;/td&gt;
&lt;td&gt;(the) table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(het) raam&lt;/td&gt;
&lt;td&gt;(the) window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(de) bloem&lt;/td&gt;
&lt;td&gt;(the) flower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(het) bed&lt;/td&gt;
&lt;td&gt;(the) bed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Then simply ask for "more". Or give the AI more direction, like simpler or more advanced words or a different theme.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate phrases
&lt;/h3&gt;

&lt;p&gt;Ask the AI for a table of phrases, with columns for English and your chosen language. The phrases could be random or you could ask them to be in a sequence so it makes sense a story with questions and responses.&lt;/p&gt;

&lt;p&gt;Do that for a particular situation like hobbies with a stranger, or in a restaurant or party or shop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Give 5 polite phrases I can use at a restaurant such as to greet, order a meal, change the order, and pay and leave. Format as a table with Dutch and English columns.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dutch&lt;/th&gt;
&lt;th&gt;English&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Goedemiddag, mag ik een tafel voor twee alstublieft?&lt;/td&gt;
&lt;td&gt;Good afternoon, may I have a table for two, please?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ik wil graag de kippensoep bestellen.&lt;/td&gt;
&lt;td&gt;I would like to order the chicken soup.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zou ik mijn bestelling kunnen wijzigen?&lt;/td&gt;
&lt;td&gt;Could I change my order, please?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mag ik de rekening alstublieft?&lt;/td&gt;
&lt;td&gt;Could I have the bill, please?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bedankt, tot ziens!&lt;/td&gt;
&lt;td&gt;Thank you, goodbye!&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a more personal experience, cou could give it more context first about your personality and hobbies or favorite foods, then get it to start a conversation.&lt;/p&gt;

&lt;p&gt;I am curious about learning a bit of a lot of languages. From my experience, I find this table-of-phrases approach way more effective and faster than using Duolingo (which is too slow and with a narrow structure) or finding an article online (which will have maybe 10 phrases and the next article will have mostly the same ones).&lt;/p&gt;

&lt;p&gt;This approach is also great for learning informal aspects that might be in articles but not formal courses. Like slang, dialects, common informal expressions, and jokes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Give me 3 slang phrases I can use with my friends. Format as a table in Dutch and English
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dutch&lt;/th&gt;
&lt;th&gt;English&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Dat is echt gaaf, man!"&lt;/td&gt;
&lt;td&gt;"That's really cool, man!"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Lekker bezig, gast!"&lt;/td&gt;
&lt;td&gt;"Nice going, dude!"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Effe chillen vanavond?"&lt;/td&gt;
&lt;td&gt;"Wanna hang out tonight?"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Translating across languages
&lt;/h3&gt;

&lt;p&gt;You can ask for a table of multiple languages in one table e.g. English, Dutch, Spanish.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I work in IT. Give me 2 sentences for how to greet someone and say what I do for a living. Format a table of Dutch, French, and English.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dutch&lt;/th&gt;
&lt;th&gt;French&lt;/th&gt;
&lt;th&gt;English&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Goedemorgen! Ik werk in IT als programmeur."&lt;/td&gt;
&lt;td&gt;"Bonjour! Je travaille dans l'informatique en tant que programmeur."&lt;/td&gt;
&lt;td&gt;"Good morning! I work in IT as a programmer."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Hallo! Ik ben een IT-beheerder."&lt;/td&gt;
&lt;td&gt;"Salut! Je suis administrateur en informatique."&lt;/td&gt;
&lt;td&gt;"Hello! I'm an IT administrator."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Phonetic pronunciation assistance
&lt;/h3&gt;

&lt;p&gt;You could ask for a column that is the phonetic pronunciation. Especially for languages like Japanese, Greek, or Polish with unfamiliar alphabets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Give me a table of greetings. Columns in English and Polish and pronunication in Polish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;English&lt;/th&gt;
&lt;th&gt;Polish&lt;/th&gt;
&lt;th&gt;Pronunciation (Polish)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hello&lt;/td&gt;
&lt;td&gt;Cześć&lt;/td&gt;
&lt;td&gt;cheshch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good morning&lt;/td&gt;
&lt;td&gt;Dzień dobry&lt;/td&gt;
&lt;td&gt;dzyen dob-ri&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good afternoon&lt;/td&gt;
&lt;td&gt;Dobry dzień&lt;/td&gt;
&lt;td&gt;dob-ri dzyen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good evening&lt;/td&gt;
&lt;td&gt;Dobry wieczór&lt;/td&gt;
&lt;td&gt;dob-ri vyeh-choor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Goodbye&lt;/td&gt;
&lt;td&gt;Do widzenia&lt;/td&gt;
&lt;td&gt;do veed-zen-ya&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Please&lt;/td&gt;
&lt;td&gt;Proszę&lt;/td&gt;
&lt;td&gt;proh-sheh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thank you&lt;/td&gt;
&lt;td&gt;Dziękuję&lt;/td&gt;
&lt;td&gt;jyen-koo-yeh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;td&gt;tahk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Nie&lt;/td&gt;
&lt;td&gt;nyeh&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Be careful of asking for "phonetic" pronunciation, as you get something more advanced phonetic standard. e.g. "Cześć" will appear as "'tʂɛɕt͡ɕ" rather than "cheshch".&lt;/p&gt;

&lt;h3&gt;
  
  
  Ask for explanations
&lt;/h3&gt;

&lt;p&gt;Sometimes I see something used a lot but it seems strange. And Google and Google Translate give bad results. So then I ask the AI.&lt;/p&gt;

&lt;h4&gt;
  
  
  Slang
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In Dutch, I see people saying "ie" when as in "hoe gaat ie" or when they talk about an inanimate object. can you explain?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Certainly! In Dutch, "ie" is a colloquial way of saying "hij" or "het" in informal speech. It's a shortened, more casual form used in spoken language, particularly in informal settings or among friends and family.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For instance:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"Hoe gaat ie?" means "How is he/it doing?" but used informally to inquire about someone's well-being.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"Die auto, hoeveel kost ie?" means "That car, how much does it cost?" using "ie" instead of "het" (it) in reference to an inanimate object.&lt;/em&gt;
&lt;em&gt;It's a bit like saying "he" or "it" instead of "he/she/it" in English, but in Dutch, it's a more informal and shortened version.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Abbreviations
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I see abbreviations, explain what they are

'k weet het.

't zusje.

's nachts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Certainly! These are abbreviations commonly used in Dutch:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;'k weet het&lt;/strong&gt;: This stands for "ik weet het," which translates to "I know it" in English. It's a shortened form where the "ik" (I) is abbreviated to just the letter 'k to make the phrase more casual or quicker to say.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;'t zusje&lt;/strong&gt;: This is an abbreviation for "het zusje" which means "the little sister" in English. The article "het" (the) is shortened to 't for ease of pronunciation or casual conversation.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;'s nachts&lt;/strong&gt;: This stands for "des nachts" or "in de nacht" in full, both of which mean "at night" in English. The abbreviation 's represents "des" (of the), and it's commonly used in written and spoken Dutch to refer to activities or events happening during the nighttime.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Requesting course outlines
&lt;/h3&gt;

&lt;p&gt;Generate a curriculum or practice exercises appropriate for your level.&lt;/p&gt;

&lt;p&gt;This can be high-level initially. Then you can ask to start one of the sections with content and questions. Or move on to another.&lt;/p&gt;

&lt;p&gt;You could ask it to quiz you occasionally, or when it thinks the current section is complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Play a game
&lt;/h3&gt;

&lt;p&gt;Ask the AI to play a game. Such a guessing game inspired by 30 Seconds or 20 Questions, where the AI gives you a few attempts to guess the person or place, then it's your turn to give the hints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose an AI tool
&lt;/h2&gt;

&lt;p&gt;Use your favorite AI chatbot for this. I found ChatGPT, Bing, and Google Bard all handle foreign languages well. I have an article on tradeoffs between them and with links to each, if you like - &lt;a href="https://michaelcurrin.github.io/coding-blog/2023/10/28/ai-tools.html"&gt;AI chatbot options in 2023&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To hear the speech spoken to you, you can use Bard with the speech icon. But I found it sounds artificial. &lt;/p&gt;

&lt;p&gt;Bing Chat can speak to you and is more realistic, but it only gives audio response if you recorded with the microphone.&lt;/p&gt;

&lt;p&gt;If you use the Edge browser, you can use a realistic text-to-speech service for any webpage, including any of the AI platforms you are using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cover image
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Banner made with NightCafe, originally posted &lt;a href="https://creator.nightcafe.studio/creation/tiZVO63u6DiQB0cZvS7d"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gpt3</category>
      <category>chatgpt</category>
      <category>learning</category>
    </item>
    <item>
      <title>AI art tools in 2023</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Sun, 24 Dec 2023 18:05:39 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/ai-art-tools-in-2023-1ela</link>
      <guid>https://forem.com/michaelcurrin/ai-art-tools-in-2023-1ela</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Free AI tools to try now for making art&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Banner image made with NightCafe, originally posted &lt;a href="https://creator.nightcafe.studio/creation/1hod8e4xUEqr4mcvziD2"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dall-E
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.dalle3.org/"&gt;dalle3.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dall-E is one of the famous models used at the moment for text-to-image AI.&lt;/p&gt;

&lt;p&gt;On the Dall-E 3 website itself, you can create art with the model. I do not recommended because of limited credits that don't top up automatically, and you get far superior quality using Dall-E 3 in Bing Image Creator (covered next).&lt;/p&gt;

&lt;h2&gt;
  
  
  Bing Image Creator
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bing.com/images/create"&gt;bing.com/images/create&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This uses Dall-E 3. This is the best beginner-friendly tool with low customization but impressive results. You can make an unlimited number of images. But after your quota after lightning/speed tokens is done for the day, your images are created much slower like every 30s or 5min, rather than within a 5 seconds.&lt;/p&gt;

&lt;p&gt;Images are only 1024x1024 pixels, cannot be upsized, and you can't see your history of images beyond your recent ones (unless you know the URL).&lt;/p&gt;

&lt;p&gt;On the homepage, you can see the popular creations by other users and use or tweak their prompts if you want, so that is great for learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  NightCafe Studio
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://creator.nightcafe.studio/"&gt;creator.nightcafe.studio/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives more control like output size, number of images, and negative keywords. &lt;/p&gt;

&lt;p&gt;There are many models to choose from including popular ones like Dall-E (2 is the latest) and Stable Diffusion (e.g. SDXL as a higher-resolution version).&lt;/p&gt;

&lt;p&gt;Your creations can be kept private or published so other uses can discover them.&lt;/p&gt;

&lt;p&gt;You get to interact with other users, like on Instagram. You can reuse the prompts other users if they are open.&lt;/p&gt;

&lt;p&gt;You can control whether your prompt is public or not. You can upsize your image up to 8000x8000 pixels, then download it, if you want to print or sell it, with no copyright restrictions.&lt;/p&gt;

&lt;p&gt;Images cost credits to make, and using more complex models and settings costs more credits. You get 5 credits a day just for logging in and 3 points everytime you share to Instagram (with a link back to your creation), though with a max allowed for the day. There is also an older Stable Diffusion model which costs zero credits if you want to experiment with that, until it gets deprecated.&lt;/p&gt;

&lt;p&gt;Here is my profile - &lt;a href="https://creator.nightcafe.studio/u/MyKale"&gt;@MyKale&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leonardo AI
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://leonardo.ai"&gt;leonardo.ai&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally for game development, this gives impressive quality and control. And you get enough free credits a day to create a couple of rounds of 4 images at a time. You can also use the prompts of other users if you like their images.&lt;/p&gt;

&lt;p&gt;And you can do advanced features like extending the background, background removal, upsizing, and masking. There's also a neat tool for creating longer text prompts based on a short prompt, though a tool like ChatGPT is already capable of doing this well if you know how.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bing Chat
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bing.com/search?q=Bing+AI&amp;amp;showconv=1&amp;amp;FORM=hpcodx"&gt;bing.com/search?q=Bing+AI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This just uses Bing Image Creator internally. But it is far more interactive using chat view or in the Edge sidebar. So the AI gives you some hints of things you can do to improve the image. You can even ask the AI to take a basic image prompt and generate more complex ones and generate the images immediately. You can even get it to create multiple creations at once with slightly different prompts, based on a single request you give it.&lt;/p&gt;

&lt;p&gt;Also, ChatGPT Plus just added image creation to text chat too, matching Bing. But that is only on the paid version.&lt;/p&gt;

</description>
      <category>art</category>
      <category>ai</category>
      <category>aiart</category>
      <category>dalle</category>
    </item>
    <item>
      <title>AI chatbot options in 2023</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Sun, 29 Oct 2023 17:36:40 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/ai-tools-in-2023-2i4g</link>
      <guid>https://forem.com/michaelcurrin/ai-tools-in-2023-2i4g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Understanding use-cases and functionality around tools such as ChatGPT&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have a lot of experience with AI tools over the last few months and now I want to help you pick AI tools based on your use-cases or the functionality you're looking for. Including text processing, document analysis, speech input/output, image processing, and coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI-powered tools
&lt;/h2&gt;

&lt;p&gt;An overview of the tools in this article, which are all free:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://chat.openai.com/"&gt;ChatGPT&lt;/a&gt; - the most famous one, by OpenAI. ChatGPT has limited speech and image functionality (at least on the free tier without plugins), and it cannot access the internet . So consider the other 3 options below to get access to these features. See OpenAI's overview page &lt;a href="https://openai.com/chatgpt"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.bing.com/search?q=Bing+AI&amp;amp;showconv=1&amp;amp;FORM=hpcodx"&gt;Bing Chat&lt;/a&gt; - Microsoft's AI chat built on a GPT model. Chats are limited to 30 prompts and input is limited (covered in a section below).&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bard.google.com"&gt;Google Bard&lt;/a&gt; - Google's AI chat built on Google's own model. See Google's post &lt;a href="https://blog.google/technology/ai/google-bard-updates-io-2023/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hashnode.com/rix/"&gt;Rix&lt;/a&gt; - an experimental AI by Hashnode, this is specialized for generating code answers and doing coding research. UPDATE: This is deprecated from 11 Dec 2023. They recommend GPT or &lt;a href="https://www.perplexity.ai/"&gt;Perplexity&lt;/a&gt; as alternatives.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparision
&lt;/h2&gt;

&lt;p&gt;They can all produce creative writing, code, translation, and research. However, here are the differences as a table. This is expanded on in the rest of this article.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Functionality&lt;/th&gt;
&lt;th&gt;ChatGPT (Free)&lt;/th&gt;
&lt;th&gt;Bing Chat&lt;/th&gt;
&lt;th&gt;Google Bard&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;GPT3&lt;/td&gt;
&lt;td&gt;GPT4&lt;/td&gt;
&lt;td&gt;Gemini (Dec 2023)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins/extensions&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text-to-speech&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (only if you record speech)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speech-to-text (microphone)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image generation&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read uploaded image or PDF&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access to the internet and provide references&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access to Google Drive&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API available&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Summarizing text
&lt;/h2&gt;

&lt;p&gt;The scenario is that you tell the AI to "summarize the following content", then you copy and paste an article into the chat.&lt;/p&gt;

&lt;p&gt;This works really well in ChatGPT, as it handles a very large amount of input.&lt;/p&gt;

&lt;p&gt;Bing Chat is considerably more limited in comparison. The entire chat is limited to 2000 tokens on Balanced (or 4000 on Creative or Precise modes). This is used up by pasting even a short article - this entire article of page or two didn't fit in when I asked to AI for tips on rewriting it. Also, on Bing Chat, the input &lt;em&gt;and&lt;/em&gt; the output of &lt;em&gt;each&lt;/em&gt; interaction in a chat counts towards the total, at least on previous releases I used.&lt;/p&gt;

&lt;p&gt;I haven't tested the content length limitations of Rix or Google Bard, but both appear to comfortably handle articles that ChatGPT cannot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documents and page context
&lt;/h2&gt;

&lt;p&gt;Having the AI aware of the current page or a given document means it can look at the whole content without having to copy and paste it into the chat (especially if that content is too large to paste in). And you can give it asks like to summarize or to give a list of key action items. This is especially useful for personal research tasks or working through academic reading.&lt;/p&gt;

&lt;p&gt;If you use the Bing Chat sidebar in the Edge browser (by clicking the Bing logo in the top right), you can talk to the AI with the context of the current page wherever you are.&lt;/p&gt;

&lt;p&gt;For Google Bard, if you use the Google Drive or Google Documents extension, you can give it the name of a Google Document or PDF and ask it questions about it like to summarize or explain things. It can also help you find a document.&lt;/p&gt;

&lt;p&gt;ChatGPT and Rix cannot be used with a sidebar or with documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Image processing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Image input
&lt;/h3&gt;

&lt;p&gt;Bing Chat and Google Bard both let you upload an image so you can ask questions about it. While ChatGPT does not support this.&lt;/p&gt;

&lt;p&gt;I don't really have a use-case for this. Sometimes I put in an AI art image and I see if it can give me appropriate words for the style to make a new image. Maybe this feature is useful for shopping for products or if you are outdoors and on your mobile phone and you want to get info on the sight or product you're looking at as a visual image search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Image generation
&lt;/h3&gt;

&lt;p&gt;Bing Chat is capable of generating images using &lt;a href="https://www.bing.com/images/create"&gt;Bing Image Creator&lt;/a&gt;, which you can also use as a standalone tool.&lt;/p&gt;

&lt;p&gt;The advantage of using it in the Bing Chat interface, is that it is more interactive - it has the context of your conversation and previous prompts and also it suggests things to do with the image as a next action like upsizing it or changing the details or style.&lt;/p&gt;

&lt;p&gt;What is really impressive is that you can ask Bing Chat to write as text-to-image prompt and then generate an image with it immediately. I have got impressive results where I give it 2 words as inspiration and it created a detailed and effective prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speech processing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Speech-to-text
&lt;/h3&gt;

&lt;p&gt;Bing Chat supports this with the microphone button. The other tools do not support this.&lt;/p&gt;

&lt;p&gt;If you use ChatGPT through the mobile app rather than the website, than this does work I've been told.&lt;/p&gt;

&lt;h3&gt;
  
  
  Text-to-Speech
&lt;/h3&gt;

&lt;p&gt;If you use the Edge Browser, then any webpage or AI chatbox conversation can have text-to-speech with realistic voices. hre is the breakdown though without that.&lt;/p&gt;

&lt;p&gt;For Bing Chat, if you use the microphone to input info, it will then read the response to you aloud. This voice is realistic.&lt;/p&gt;

&lt;p&gt;For more customization and to use text-to-speech always (and not just in the microphone mode), you can also click the Edge browser's read aloud button near the address bar. It has a lot of languages and accents to choose from. This is also flexible - this would actually work with any AI tool and article.&lt;/p&gt;

&lt;p&gt;Google Bard has the option to read responses aloud, but I found the speech somewhat robotic.&lt;/p&gt;

&lt;p&gt;ChatGPT does not have this feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding
&lt;/h2&gt;

&lt;p&gt;Rix is specialized for writing code responses. It has 3 modes when starting a new thread:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;web search&lt;/strong&gt; to get real-time info from the internet, with links to the articles it used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;quick mode&lt;/strong&gt; to use previously-stored knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code writer&lt;/strong&gt; to generate or modify code across multiple programming languages. It also gives explanations in between the code blocks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google Bard, ChatGPT, and Bing Chat also handle code well in my experience, but they are not specialists. So I tend to focus on my coding tasks on Rix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Research
&lt;/h2&gt;

&lt;p&gt;Rix, Bing Chat, and Google Bard have access to the internet. They can do browser searches for you, provide links to sources, and some can read content at a URl you provide. Some can also provide embedded images.&lt;/p&gt;

&lt;p&gt;This is great for coding problems as it they can search documentation and give links to articles and StackOverflow answers it used, so you can verify the answers.&lt;/p&gt;

&lt;p&gt;You can also use these tools as super search engines. Rather than using the tools to give you answers, use them to refine your search query, scan many websites, and then give you links to the page. This can be especially useful for a Google search that is hard to phrase or a topic you know little about. Or just to accelerate the search process while still remaining in control.&lt;/p&gt;

&lt;p&gt;If you use Google Bard with its extensions, it can integration with Google products for powerful searching. Including Google Maps, YouTube, and hotels. This makes it more powerful at getting accurate, recent information on the real world.&lt;/p&gt;

&lt;p&gt;Bing Chat has plugins for recipes, online shopping, restaurant bookings, and holiday booking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.bing.com/images/create"&gt;Bing Image Creator&lt;/a&gt; - this only generates AI art and has no interactive chat, but it does integrate well with Bing Chat.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.phind.com/"&gt;Phind&lt;/a&gt; - an AI search engine and "pair programmer" for debugging, with internet access and the option to use GPT-3 and GPT-4 models. A similar tool to Rix. Once I started using Rix, I haven't need the need to go back to Phind.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/features/copilot"&gt;GitHub Copilot&lt;/a&gt; - this is available as an extension like in VS Code. It is aware of your files and you don't have to leave your code editor and go to the browser. But, you have to pay $10 per month.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Now with some more info on the strengths and limitations of each tool, you can go and pick one suitable for you next AI-assisted task.&lt;/p&gt;

&lt;p&gt;Still not sure? Keep experimenting. I'd suggest putting the same prompt into multiple tools and seeing what results you get out of each. Sometimes one will need a lot of instruction to get good results. Or one will refuse to do something because it thinks the terms are violated (like if you ask for a "sarcastic" blog post).&lt;/p&gt;

&lt;h2&gt;
  
  
  Cover image
&lt;/h2&gt;

&lt;p&gt;Generated with &lt;a href="https://www.bing.com/images/create"&gt;Bing Image Creator&lt;/a&gt; and text added with &lt;a href="https://pixlr.com/x/#editor"&gt;Pixlr&lt;/a&gt;. Here is the &lt;a href="https://www.bing.com/images/create/horizontal-banner-for-blog-post-on-devto-about-ai/653e968c28fe4b7b87fc1c42bd8eda5a?id=QLslVZgVB4dBniYXnA%2b3Bw%3d%3d&amp;amp;view=detailv2&amp;amp;idpp=genimg&amp;amp;FORM=GCRIDP&amp;amp;ajaxhist=0&amp;amp;ajaxserp=0"&gt;original&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>productivity</category>
      <category>gpt3</category>
    </item>
    <item>
      <title>Tech predictions for the next decade</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Sun, 05 Jun 2022 13:50:26 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/tech-predictions-for-the-next-decade-1aa5</link>
      <guid>https://forem.com/michaelcurrin/tech-predictions-for-the-next-decade-1aa5</guid>
      <description>&lt;p&gt;I've been reflecting on trends in tech for the next few years and wanted to share that in a post to share what I've encountered and to start some discussions.&lt;/p&gt;

&lt;p&gt;Some of this is based on what I've come across in videos and articles, some is my opinion based on what I've seen happening in the last few years.&lt;/p&gt;

&lt;p&gt;Here we go...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More uses for robots in everyday lives and more complex, smarter, safer, faster robots.

&lt;ul&gt;
&lt;li&gt;Robot butlers like Tesla's &lt;a href="https://www.thenationalnews.com/business/technology/2022/06/03/tesla-optimus-what-we-know-so-far-about-the-robot/"&gt;Optimus&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Drones which deliver packages, watch over us, spy on us, fight wars... maybe controlled by AI. And more entertainment like to provide aerial displays like planes at airshows or be used to film videos such as this &lt;a href="https://www.dronethusiast.com/ok-go-music-video-filmed-using-drone/"&gt;music video&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Robot assistants like those from &lt;a href="https://www.bostondynamics.com/"&gt;BostonDynamics&lt;/a&gt; which perform boring or dangerous tasks in places like warehouses and oil refineries&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.online-sciences.com/robotics/robotic-cars-self-driving-cars-advantages-and-disadvantages/"&gt;Robot cars&lt;/a&gt; aka self-driving cars which are electric. Possibly controlled by a central brain like an air traffic controller sending and receiving messages with all - letting the cars act like a hive of ants with a queen.&lt;/li&gt;
&lt;li&gt;Then naturally more software engineers and mechatronic engineers to keep up with the demand. Likely more AI and robots available in schools and universities and in hobby "maker" spaces.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ethereum.org/en/dapps/"&gt;Dapps&lt;/a&gt; aka "distributed apps" are going to continue to rise as Web3 and blockchain technologies mature and get adopted. This may be a bubble waiting to burst but in the meantime you can get work and build projects around this.&lt;/li&gt;
&lt;li&gt;JavaScript

&lt;ul&gt;
&lt;li&gt;Data type annotations are coming to JS as a builtin feature I've read, which means you won't need TypeScript to compile your TS to plain JS (Python allows type annotations in this way). I don't know what you'll use for typechecking though.&lt;/li&gt;
&lt;li&gt;Using abstractions is going to continue. Next.js is on top of React, so maybe another layer on top of Next.js or a replacement. Next.js also does a &lt;em&gt;lot&lt;/em&gt; of stuff and may become too complex to use or maintain, so we might get some smaller specialist libraries to use instead.&lt;/li&gt;
&lt;li&gt;Alternatives to React like Vue and Svelte are going to continue to grow in popularity, especially for new projects or developers starting out.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Rust so far is a most-loved language with low adoption as it is unusual and low-level. As more developers get familiar with it and there are more packages available, Rust will get adopted more - it is already great for low-level code and where are speed and memory optimization are important (like for games, machinery, and micro-controllers). 

&lt;ul&gt;
&lt;li&gt;Go is more practical for general use-cases and web development. It's a lot easier to learn and generates a portable binary format. It gives arguably similar performance to Rust. So Go will continue to be adopted. It might overtake Rust and even Python in popularity. Especially as Python is a few decades old while Go is much younger and has a concurrency added from the start with "goroutines".&lt;/li&gt;
&lt;li&gt;More event-driven architecture for reliability in distributed systems. More queues. More serverless applications and platforms - which can scale instantly and you only pay for what you need. We've already seen Netlify provise easy-to-deploy Functions which wrap the AWS Lambda feature. And we have databases like AuroraDB from AWS which turns your DB into a managed serverless DB without changing your schema or queries.&lt;/li&gt;
&lt;li&gt;More code running in containers especially locally.&lt;/li&gt;
&lt;li&gt;NoSQL databases will continue to be mature and new ones will come up. SQL will still be around for a long time.&lt;/li&gt;
&lt;li&gt;Web developers will become more multi-skilled. Fullstack already tends to include DevOps and CyberSecurity aspects, which makes dev teams less reliant on other teams and more independent. &lt;/li&gt;
&lt;li&gt;Some developers like myself who have done fullstack for a few years will want to specialize in backend or frontend again. As having to keep up with new tech in the backend (around shell, databases, Python/Java/C#/C++) and the frontend (around HTML, CSS, JS) can lead to fatigue and always feeling behind with shallow knowledge.&lt;/li&gt;
&lt;li&gt;No-code platforms will continue to rise. People who can't code love to use WordPress or Wix and there are newer platforms which let you build websites and mobile apps in a similar way.&lt;/li&gt;
&lt;li&gt;More use-cases for AI and machine-learning in coding and in business. More engineers in this area. We may see a bubble burst in the tech if we reach a ceiling in the capabilities of AI or there are restrictions from politics or legal areas that restrict development. Elon Musk has also called general AI far more dangerous than nuclear weapons, so AI will hopefully become more regulated and countries will have to agree how to use AI and how far to take it. Some countries will do their own thing undercover to gain an advantage in war or economics though.&lt;/li&gt;
&lt;li&gt;We've already seen a rise in technologies which let you build mobile apps for Android and iOS using a single codebase. Such as using Flutter in Dart (which didn't catch on as much as some hoped) or using Node-based packages. So I think there will be improvements on those or newer alternatives. We'll still people writing Java/Kotlin and Swift code for native devices for a while and that may never disappear. At least until Google and Apple decide to use something else as their mobile operating system.&lt;/li&gt;
&lt;li&gt;More remote work - work in a different city or country to get your work done and still live where you want.&lt;/li&gt;
&lt;li&gt;Hybrid work with a mix of office and work-from-home has risen and been demanded by employees during Covid19, so it looks like this is hear to stay, for IT and other industries.&lt;/li&gt;
&lt;li&gt;We'll rely less on the computing power of our laptops for development - the computations will be moved to the cloud. We've already seen GitHub bring out &lt;a href="https://github.com/features/codespaces"&gt;CodeSpaces&lt;/a&gt; where you get an IDE and processing in the cloud. So you can easily switch between laptops and you can have a cheap laptop that offloads work to the GitHub servers. We might see the same trend for computers and phones offloading computations - especially with Moore's Law showing signs of slowing down as we reach a physical limit of how small we can make a components on a motherboard.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anything you want to add to the list? Disagree with any points? Comment below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/photos/0E_vhMVqL9g"&gt;Cover image&lt;/a&gt; courtesy of Unsplash.&lt;/p&gt;

</description>
      <category>predictions</category>
      <category>programming</category>
      <category>future</category>
      <category>trends</category>
    </item>
    <item>
      <title>Deploy a Vue/React app to GH Pages</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Fri, 03 Dec 2021 11:32:51 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/deploy-a-vuereact-app-to-gh-pages-3m93</link>
      <guid>https://forem.com/michaelcurrin/deploy-a-vuereact-app-to-gh-pages-3m93</guid>
      <description>&lt;p&gt;This guide takes you through how to deploy a Node app with GitHub Actions so that the static output can be served as GH Pages. This works well for Single-Page Applications, such as if using React or Vue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Submission category
&lt;/h2&gt;

&lt;p&gt;This is my submission to &lt;a href="https://dev.to/devteam/join-us-for-the-2021-github-actions-hackathon-on-dev-4hn4"&gt;GitHub Actions Hackathon&lt;/a&gt; under &lt;strong&gt;DIY Deployments&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;My workflow will be triggered by any pushes to &lt;code&gt;master&lt;/code&gt; and any Pull Requests against &lt;code&gt;master&lt;/code&gt;. Any changes to the &lt;code&gt;docs&lt;/code&gt; directory will not trigger the workflow, as there is no point in rebuilding the app in that case.&lt;/li&gt;
&lt;li&gt;The GitHub Actions environment already includes Node and Yarn, so if you don't care about the specific versions needed, you can leave out setup steps. For more control, see &lt;a href="https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/workflows/node/" rel="noopener noreferrer"&gt;Node workflows&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There are shell steps to install NPM dependencies, run checks (linting and formatting) and then build the app. You can use &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt; in the steps.&lt;/li&gt;
&lt;li&gt;The final step uses an Action which will take the unversioned output in the &lt;code&gt;dist&lt;/code&gt; directory and commit it to the root of the &lt;code&gt;gh-pages&lt;/code&gt; branch. For Vue, &lt;code&gt;dist&lt;/code&gt; is typical, while React projects use &lt;code&gt;build&lt;/code&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The repo should configured to serve the &lt;code&gt;gh-pages&lt;/code&gt; branch as a site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample YAML file
&lt;/h2&gt;

&lt;p&gt;Create a workflow as &lt;code&gt;.github/workflows/main.yml&lt;/code&gt; in your repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy GH Pages&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
    &lt;span class="na"&gt;paths-ignore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docs/**"&lt;/span&gt;

  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
    &lt;span class="na"&gt;paths-ignore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docs/**"&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout 🛎️&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;persist-credentials&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install 🔧&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn install&lt;/span&gt;    &lt;span class="c1"&gt;# OR npm install&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint 🧐&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn lint:check&lt;/span&gt; &lt;span class="c1"&gt;# OR npm run lint:check&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build 🏗️&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn build&lt;/span&gt;      &lt;span class="c1"&gt;# OR npm run build&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to GH Pages 🚀&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event_name != 'pull_request' }}&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peaceiris/actions-gh-pages@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;github_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;publish_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dist&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note that you don't have to generate or set a token - a &lt;a href="https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/tokens/" rel="noopener noreferrer"&gt;token&lt;/a&gt; will be generated for you by GH Actions. A token which only has access to the current repo and no human will need to interact with the token.&lt;/p&gt;

&lt;p&gt;After committing the above file, check your &lt;em&gt;Actions&lt;/em&gt; tab and wait for the workflow to run.&lt;/p&gt;

&lt;p&gt;After it is successful, go to repo settings and enable &lt;em&gt;Pages&lt;/em&gt; against the root of your &lt;code&gt;gh-pages&lt;/code&gt; branch, to serve that as a GH Pages site. &lt;/p&gt;

&lt;p&gt;Then check the &lt;em&gt;Environment&lt;/em&gt; section to see it deployed.&lt;/p&gt;

&lt;p&gt;Note also that the actual deploy step &lt;em&gt;only&lt;/em&gt; runs against &lt;code&gt;master&lt;/code&gt; commits directly and &lt;em&gt;not&lt;/em&gt; on a Pull Request. So you can safely have your test and build steps run against a feature branch on a Pull Request for quality control, &lt;em&gt;without&lt;/em&gt; actually deploying anything until the PR gets merged.&lt;/p&gt;
&lt;h2&gt;
  
  
  Workflows in use
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Vue
&lt;/h3&gt;

&lt;p&gt;I have a &lt;code&gt;vue-quickstart&lt;/code&gt; repo which was generated with Vue CLI and then extended with documentation, CI/CD, and demo site.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MichaelCurrin" rel="noopener noreferrer"&gt;
        MichaelCurrin
      &lt;/a&gt; / &lt;a href="https://github.com/MichaelCurrin/vue-quickstart" rel="noopener noreferrer"&gt;
        vue-quickstart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Starter template for a Vue 2 site - including docs and CI deploy to GH Pages
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Vue Quickstart&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Starter template for a Vue 3 site - including docs and CI deploy to GH Pages&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/vue-quickstart/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/MichaelCurrin/vue-quickstart/workflows/Deploy%20GH%20Pages/badge.svg" alt="Deploy GH Pages"&gt;&lt;/a&gt;
&lt;a href="https://github.com/MichaelCurrin/vue-js-quickstart/tags/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ca20657d81a8d240fc50527b0af177a4a901487630faa2f043eaecdf292a4470/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7461672f4d69636861656c43757272696e2f7675652d717569636b7374617274" alt="GitHub tag"&gt;&lt;/a&gt;
&lt;a href="https://github.com/MichaelCurrin/vue-quickstart#license" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/371a602912faf7afd95fb8d7c0d8846e048157c4f50ae5ede617f56320429998/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c7565" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://nodejs.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/69f457ec42b21307ad396d6afe07d5da14cb4df183d207b6a777c5d89173f733/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6f64652e6a732d2533453d31322d626c75653f6c6f676f3d6e6f64652e6a73266c6f676f436f6c6f723d7768697465" alt="Made with Node"&gt;&lt;/a&gt;
&lt;a href="https://classic.yarnpkg.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/60a5e3891d0e84c4072c8e6798e36dc63638cbd3ab25f446f9ade16e0eed53d8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5961726e2d2533453d312d626c75653f6c6f676f3d7961726e266c6f676f436f6c6f723d7768697465" alt="Made with Yarn"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9f07c309ed6f19ae86997b879aa066d0ef15a798ecd74671e510dbb378756ea8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7061636b6167652d6a736f6e2f646570656e64656e63792d76657273696f6e2f4d69636861656c43757272696e2f7675652d717569636b73746172742f7675653f6c6f676f3d7675652e6a73" alt="Made with Vue"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Preview&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
    &lt;a href="https://michaelcurrin.github.io/vue-quickstart/" rel="nofollow 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%2Fgithub.com%2FMichaelCurrin%2Fvue-quickstart%2Fsample.png" alt="Sample screenshot" title="Sample screenshot" width="600"&gt;
    &lt;/a&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Use this project&lt;/h2&gt;

&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://michaelcurrin.github.io/vue-quickstart/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/922f44ea67edeb1147d671c6141b9fe17eb258b559f1998382dedc657c4b0586/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566965772d44656d6f5f736974652d626c75653f7374796c653d666f722d7468652d6261646765" alt="View site GH Pages"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/vue-quickstart/generate" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3cb4a1d86d72fd99369f9dde838cf578e7477cf5c165f8a91c9e93ffea26d277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f47656e65726174652d5573655f746869735f74656d706c6174652d3265613434663f7374796c653d666f722d7468652d6261646765" alt="Use this template"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;After you've looked at the demo screenshot and site, you are welcome to create your own using the template button. This will copy this project and add it to your repos (no forking needed, but please star the original repo).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;How to install and run the app locally and deploy it to GH Pages&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/vue-quickstart/docs/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8367ad0800c028f980dd31bbad750c910be8889c0cad1da0dbd87b03622b2d64/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566965772d446f63756d656e746174696f6e2d626c75653f7374796c653d666f722d7468652d6261646765" alt="View - Documentation"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;About&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;What is Vue?&lt;/h3&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Why not React?&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Vue is intended to be more beginner-friendly (I agree it is) and the &lt;a href="https://github.com/vuejs/vue" rel="noopener noreferrer"&gt;vue&lt;/a&gt; repo has more GH stars than the &lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;react&lt;/a&gt; repo, if that is any indication of adoption by the community.&lt;/p&gt;
&lt;p&gt;Vue is open-source and was created by one person originally. React was created at Facebook.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Resources&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Need are some resources…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MichaelCurrin/vue-quickstart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;See &lt;a href="https://github.com/MichaelCurrin/vue-quickstart/blob/master/.github/workflows/main.yml" rel="noopener noreferrer"&gt;main.yml&lt;/a&gt; there.&lt;/p&gt;

&lt;h3&gt;
  
  
  React
&lt;/h3&gt;

&lt;p&gt;I did the same thing for React:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MichaelCurrin" rel="noopener noreferrer"&gt;
        MichaelCurrin
      &lt;/a&gt; / &lt;a href="https://github.com/MichaelCurrin/react-quickstart" rel="noopener noreferrer"&gt;
        react-quickstart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Starter template for a React app - including docs, CI, and hosting ⚛ 📦
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;React Quickstart ⚛️ 📦&lt;/h1&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Starter template for a React app - including docs, CI, and hosting&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/react-quickstart/actions?query=workflow:%22GH+Pages+Deploy%22" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/MichaelCurrin/react-quickstart/workflows/GH%20Pages%20Deploy/badge.svg" alt="GH Pages Deploy"&gt;&lt;/a&gt;
&lt;a href="https://github.com/MichaelCurrin/react-quickstart/tags/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5d0762819f1a0f7db1c0aae0d898112c2410555b5be649a91acbdaa189fd4ca8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7461672f4d69636861656c43757272696e2f72656163742d717569636b7374617274" alt="GitHub tag"&gt;&lt;/a&gt;
&lt;a href="https://github.com/MichaelCurrin/react-quickstart#license" title="Go to License section" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/371a602912faf7afd95fb8d7c0d8846e048157c4f50ae5ede617f56320429998/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c7565" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://nodejs.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1cd51db36e0b781c282031fd56525a711b07fe55ee5362a152ea97461d56c6ec/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6f64652e6a732d2533453d31302d626c75653f6c6f676f3d6e6f64652e6a73266c6f676f436f6c6f723d7768697465" alt="Made with Node"&gt;&lt;/a&gt;
&lt;a href="https://classic.yarnpkg.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/60a5e3891d0e84c4072c8e6798e36dc63638cbd3ab25f446f9ade16e0eed53d8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5961726e2d2533453d312d626c75653f6c6f676f3d7961726e266c6f676f436f6c6f723d7768697465" alt="Made with Yarn"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/react" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/24557c4ba2a10c254b5692095af5e06e93c5f4e735612a9fae07d0582a3dbd90/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7061636b6167652d6a736f6e2f646570656e64656e63792d76657273696f6e2f4d69636861656c43757272696e2f72656163742d717569636b73746172742f72656163743f6c6f676f3d7265616374" alt="Made with React"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;
    &lt;a href="https://michaelcurrin.github.io/react-quickstart/" title="Go to demo app" rel="nofollow 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%2Fraw.githubusercontent.com%2Fgithub%2Fexplore%2Fmaster%2Ftopics%2Freact%2Freact.png" alt="node icon" title="Node.js" width="80" height="80"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fexplore%2Fmaster%2Ftopics%2Fnodejs%2Fnodejs.png" alt="node icon" title="Node.js" width="80" height="80"&gt;
    &lt;/a&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Preview&lt;/h2&gt;

&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://michaelcurrin.github.io/react-quickstart/" rel="nofollow 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%2Fgithub.com%2FMichaelCurrin%2Freact-quickstart%2Fsample.png" alt="Sample screenshot of React site" title="Go to demo site" width="500"&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://michaelcurrin.github.io/react-quickstart/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0380b76ad1b8fafde14818d199cf0de9aa5dc3710e0c82def176d670c9fdc98e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566965775f64656d6f2d52656163745f4170705f517569636b73746172742d626c75653f7374796c653d666f722d7468652d6261646765" alt="View demo - React Quickstart"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Create a new React app&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Use this project as a template:&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/react-quickstart/generate" title="Use this template" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3cb4a1d86d72fd99369f9dde838cf578e7477cf5c165f8a91c9e93ffea26d277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f47656e65726174652d5573655f746869735f74656d706c6174652d3265613434663f7374796c653d666f722d7468652d6261646765" alt="Use this template"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If you need something more minimal, see this &lt;a href="https://michaelcurrin.github.io/code-cookbook/recipes/javascript/packages/react/minimal.html" rel="nofollow noopener noreferrer"&gt;Minimal&lt;/a&gt; app recipe.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;To install, run and deploy the app, see this project's docs:&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/react-quickstart/docs/README.md" title="Go to project docs" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8367ad0800c028f980dd31bbad750c910be8889c0cad1da0dbd87b03622b2d64/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566965772d446f63756d656e746174696f6e2d626c75653f7374796c653d666f722d7468652d6261646765" alt="Docs"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;To learn how to use this project and see how a React project works, see the &lt;a href="https://github.com/MichaelCurrin/react-quickstart/docs/template-notes/" rel="noopener noreferrer"&gt;Template notes&lt;/a&gt; section of the docs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;License&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Released under &lt;a href="https://github.com/MichaelCurrin/react-quickstart/LICENSE" rel="noopener noreferrer"&gt;MIT&lt;/a&gt; by &lt;a href="https://github.com/MichaelCurrin" rel="noopener noreferrer"&gt;@MichaelCurrin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This project is based on the template from the React CLI. I have added my own docs, the deploy flow, made minor changes to the app, plus some additions to components.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MichaelCurrin/react-quickstart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;See &lt;a href="https://github.com/MichaelCurrin/react-quickstart/blob/master/.github/workflows/main.yml" rel="noopener noreferrer"&gt;main.yml&lt;/a&gt; there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  On Code Cookbook
&lt;/h3&gt;

&lt;p&gt;I have a ton of GH Actions workflows you can browse here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/workflows/" rel="noopener noreferrer"&gt;Workflows | Code Cookbook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  On my Dev Resources site
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://michaelcurrin.github.io/dev-resources/resources/javascript/node-js/" rel="noopener noreferrer"&gt;Node&lt;/a&gt; resources&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://michaelcurrin.github.io/dev-resources/resources/ci-cd/github-actions/" rel="noopener noreferrer"&gt;GH Actions&lt;/a&gt; resources&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://michaelcurrin.github.io/dev-resources/resources/web/github-pages.html" rel="noopener noreferrer"&gt;GH Pages&lt;/a&gt; resources&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://michaelcurrin.github.io/dev-resources/resources/javascript/packages/vue/vue-3.html" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; resources&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://michaelcurrin.github.io/dev-resources/resources/javascript/packages/react/" rel="noopener noreferrer"&gt;React&lt;/a&gt; resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  More template repos
&lt;/h3&gt;

&lt;p&gt;No Node or CI needed here! These use CDN URLs to load React or Vue in the browser and that static HTML gets served directly on GH Pages without a build step.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MichaelCurrin/react-frontend-quickstart" rel="noopener noreferrer"&gt;react-frontend-quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MichaelCurrin/vue-frontend-quickstart" rel="noopener noreferrer"&gt;vue-frontend-quickstart&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@andriklangfield?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Andrik Langfield&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/build?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>actionshackathon21</category>
      <category>vue</category>
      <category>javascript</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Upgrade NPM packages with GH Actions</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Fri, 03 Dec 2021 10:46:15 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/upgrade-npm-packages-with-gh-actions-55md</link>
      <guid>https://forem.com/michaelcurrin/upgrade-npm-packages-with-gh-actions-55md</guid>
      <description>&lt;h2&gt;
  
  
  My workflow
&lt;/h2&gt;

&lt;p&gt;This post shows you how to use &lt;a href="https://michaelcurrin.github.io/dev-resources/resources/ci-cd/github-actions/" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; for automated NPM package upgrades. The workflow willupgrade your app's NPM packages described in &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; and then create an automated PR if any changes were committed.&lt;/p&gt;

&lt;p&gt;This flow can be scheduled (such as weekly) or triggered on a button press. All without having to touch your local CLI.&lt;/p&gt;

&lt;p&gt;This post is an entry into the DEV.to &lt;a href="https://dev.to/t/actionshackathon21"&gt;actionshackathon21&lt;/a&gt; competition. Read more and enter &lt;a href="https://dev.to/devteam/join-us-for-the-2021-github-actions-hackathon-on-dev-4hn4"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Submission Category
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Maintainer Must-Haves&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up workflow YAML file
&lt;/h2&gt;

&lt;p&gt;Here is what the workflow will do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checkout the codebase.&lt;/li&gt;
&lt;li&gt;Set up Node v16 in the environment.&lt;/li&gt;
&lt;li&gt;Upgrade packages with &lt;code&gt;npm update&lt;/code&gt; as a shell command. If there is anything that got upgraded, then &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; will be updated.&lt;/li&gt;
&lt;li&gt;The final step will create a commit and a Pull Request, acting as a GitHub Actions bot account. Or do nothing if there are no changes to commit.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To set up, create this file in your repo - &lt;code&gt;.github/workflows/upgrade-packages.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add contents:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upgrade NPM packages&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;0"&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;upgrade-packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upgrade packages&lt;/span&gt;

    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout 🛎️&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node.js ⚙️&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;16.x'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upgrade packages 🔀&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm update&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Commit and create PR 🔀&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peter-evans/create-pull-request@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;build(deps):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Upgrade&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NPM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;packages&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(automated)'&lt;/span&gt;
          &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;build-deps-upgrade-npm-packages-automated'&lt;/span&gt;
          &lt;span class="na"&gt;commit-message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;build(deps):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;upgrade&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NPM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;packages&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(automated)'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then commit it.&lt;/p&gt;

&lt;p&gt;Pro tip - if you go to the &lt;em&gt;Actions&lt;/em&gt; tab and create a new workflow from there using a template, then you'll get a neat editor view in GitHub which gives you hints and auto-complete specify for GH Actions.&lt;/p&gt;

&lt;p&gt;For the final step above, you can check out the &lt;a href="https://github.com/marketplace/actions/create-pull-request" rel="noopener noreferrer"&gt;Create Pull Request&lt;/a&gt; action on Actions Marketplace. Note that is used a workflow-scoped token internally, so you don't have to specify any token.&lt;/p&gt;

&lt;p&gt;If you are not using NPM, you can easily swap some steps. For Yarn, you will already get Yarn in your environment so just make the shell command &lt;code&gt;yarn upgrade&lt;/code&gt;. For Ruby, use &lt;code&gt;setup-ruby&lt;/code&gt; Action and &lt;code&gt;bundle update&lt;/code&gt; as the shell command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run your workflow
&lt;/h2&gt;

&lt;p&gt;You can wait until midnight on Sunday comes around. You'll get a notification in your GitHub account that the PR was created. &lt;/p&gt;

&lt;p&gt;Or trigger the workflow manually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;em&gt;Actions&lt;/em&gt; tab of your repo.&lt;/li&gt;
&lt;li&gt;Select your workflow name.
&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%2F9xewx0e8jbvjdf30tun1.png" alt="Workflows list"&gt;
&lt;/li&gt;
&lt;li&gt;Click the &lt;em&gt;Run Workflow&lt;/em&gt; button.
&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%2F14ofi6u1vr7o1bb9j48z.png" alt="Run workflow"&gt;
&lt;/li&gt;
&lt;li&gt;Then run with it with default settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check that the workflow runs fine and has no errors.&lt;/p&gt;

&lt;p&gt;Then go to the &lt;em&gt;Pull Request&lt;/em&gt; tab to find the PR. Check it looks good and then approve and merge it.&lt;/p&gt;

&lt;p&gt;For confidence in the stability of the app, you can also run CI checks in the upgrade workflow or your standard build-and-test workflow. More on that in the sections below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example of the workflow in use
&lt;/h2&gt;

&lt;p&gt;I use a workflow similar to the one above that is implemented in my &lt;a href="https://github.com/MichaelCurrin/badge-generator" rel="noopener noreferrer"&gt;Badge Generator&lt;/a&gt; web app, which is built in Vue and Yarn.&lt;/p&gt;

&lt;p&gt;Some relevant links around that repo for package upgrades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/MichaelCurrin/badge-generator/blob/master/.github/workflows/upgrade-%20packages.yml" rel="noopener noreferrer"&gt;upgrade-packages.yml&lt;/a&gt; workflow config.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MichaelCurrin/badge-generator/actions/workflows/upgrade-packages.yml" rel="noopener noreferrer"&gt;Upgrade NPM Packages runs&lt;/a&gt; - runs under &lt;em&gt;Actions&lt;/em&gt;, to see log output.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MichaelCurrin/badge-generator/pulls?q=is%3Apr+automated" rel="noopener noreferrer"&gt;Automated PRs&lt;/a&gt; that exist in the repo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared with the YAML snippet in this post, my linked workflow uses a more complex steps and GitHub Actions syntax.&lt;/p&gt;

&lt;p&gt;Here are some notable differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It &lt;em&gt;checks&lt;/em&gt; if packages are outdated, and if there is nothing to update, it skips other steps.&lt;/li&gt;
&lt;li&gt;The packages to upgrade are logged before any changes are made to the lockfile.&lt;/li&gt;
&lt;li&gt;The workflow runs lint, test, and build steps to ensure the app is working fine against the new set of packages. If a step fails, the workflow will give an error and the PR will &lt;strong&gt;not&lt;/strong&gt; be created.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CI against PRs
&lt;/h2&gt;

&lt;p&gt;For typical development (not upgrading packages), I recommend having some CI against your PRs for quality control. So that you test and build the app with GH Actions &lt;em&gt;before&lt;/em&gt; you merge a PR.&lt;/p&gt;

&lt;p&gt;Unfortunately, due to security limitations, the automated PR that your new upgrade workflow generates will &lt;em&gt;not&lt;/em&gt; have GH Actions checks run against it. See &lt;a href="https://github.com/peter-evans/create-pull-request/issues/48" rel="noopener noreferrer"&gt;issue&lt;/a&gt; on the Create PR action discussing this.&lt;/p&gt;

&lt;p&gt;I found workarounds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the generated PR's branch, I make a non-functional whitespace change in &lt;code&gt;package-lock.json&lt;/code&gt;. And because is change was made by a human and not a bot, that kicks off the workflow run. 😃 &lt;/li&gt;
&lt;li&gt;There's a suggestion comment on issue &lt;a href="https://github.com/peter-evans/create-pull-request/issues/48#issuecomment-536204092" rel="noopener noreferrer"&gt;#48&lt;/a&gt; of the &lt;code&gt;create-pull-request&lt;/code&gt; repo which involves creating a custom token.&lt;/li&gt;
&lt;li&gt;You can also delete and make a new PR with the existing branch, but I prefer not to do that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know if you have any other ideas. &lt;/p&gt;

&lt;p&gt;Maybe GitHub will add a feature to "Approve and Run" such a generated PR? This is already an option in the case of a PR created from a &lt;em&gt;fork&lt;/em&gt;, but doesn't help me here.&lt;/p&gt;

&lt;p&gt;Anyway, that limitation is okay I think. If you decide to add test and build steps in the actual upgrade workflow, the PR will only get created if everything passes, increasing confidence that the automated PR has good quality even if you don't check it directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  About
&lt;/h2&gt;

&lt;p&gt;Some more info and context about why I made this workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can I be confident nothing broke?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The upgrades will only be &lt;em&gt;within&lt;/em&gt; semantic versioning restrictions of your &lt;code&gt;package.json&lt;/code&gt; file. For example, a major upgrade from &lt;code&gt;v1.X.X&lt;/code&gt; to &lt;code&gt;v2.X.X&lt;/code&gt; won't happen if you specify your versions as &lt;code&gt;"^1.2.3"&lt;/code&gt; or similar in your &lt;code&gt;package.json&lt;/code&gt; file. If you want to &lt;em&gt;do&lt;/em&gt; that kind of upgrade, you should probably do that manually and locally, to avoid risk.&lt;/li&gt;
&lt;li&gt;I recommend adding &lt;em&gt;test&lt;/em&gt; and &lt;em&gt;build&lt;/em&gt; steps to your CI so you have confidence that the newer package versions don't break your app, and only merge the PR once you're happy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why automate this?
&lt;/h3&gt;

&lt;p&gt;For context and reasons for this flow. &lt;/p&gt;

&lt;p&gt;I have a couple of Node-based projects on GitHub. I'm using modern packages where possible when making a new project, but, the packages or sub-dependencies still become out of date easily as newer versions are released as minor or patch versions e.g. from &lt;code&gt;v2.3.X&lt;/code&gt; to &lt;code&gt;v2.4.X&lt;/code&gt;, or from &lt;code&gt;v2.3.4&lt;/code&gt; to &lt;code&gt;v2.3.5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I would like to get any bug fixes, performance enhancements, and security patches. But without having to remember to take the time to manually upgrade packages locally with the CLI, test, build, and commit and push. That can all be automated!&lt;/p&gt;

&lt;h3&gt;
  
  
  What about security scanning?
&lt;/h3&gt;

&lt;p&gt;GitHub already supports &lt;a href="https://docs.github.com/en/code-security/supply-chain-security/managing-vulnerabilities-in-your-projects-dependencies" rel="noopener noreferrer"&gt;code scanning for vulnerabilities&lt;/a&gt;. And I enjoy using &lt;a href="https://snyk.io/" rel="noopener noreferrer"&gt;snyk.io&lt;/a&gt; as a similar external tool. &lt;/p&gt;

&lt;p&gt;You should continue to use those tools to patch vulnerabilities with generated PRs. But, by using my workflow, you'll be upgrading your packages so frequently that sometimes you'll get your app upgraded to secure packages even &lt;em&gt;before&lt;/em&gt; the scans tell you the old version is insecure.&lt;/p&gt;

&lt;p&gt;If you have a bunch of vulnerabilities come up in GH or Snyk, you can try run your upgrade packages workflow manually and merge the PR. Maybe the vulnerabilities will be resolved like that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;I did a write-up here on a workflow, including how to use Yarn and upgrade major versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/workflows/node/upgrade-packages.html" rel="noopener noreferrer"&gt;Upgrade Packages&lt;/a&gt; workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have a popular post for if you are new to using Actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/michaelcurrin/beginner-s-guide-to-github-actions-49aa"&gt;Beginner's guide to GitHub Actions&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some specific GH Actions workflows to recommend on standard CI around building and testing a Node app.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/MichaelCurrin/node-project-template/blob/master/.github/workflows/main.yml" rel="noopener noreferrer"&gt;main.yml&lt;/a&gt; in my Node Project Template. This workflow tests and builds the app but does not deploy anything.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MichaelCurrin/react-quickstart/blob/main/.github/workflows/main.yml" rel="noopener noreferrer"&gt;main.yml&lt;/a&gt; in my React Quickstart to test and build the app and commit the build output to GitHub Actions, to be served as a GH Pages site.
&lt;a href="https://github.com/MichaelCurrin/badge-generator/blob/master/.github/workflows/main.yml" rel="noopener noreferrer"&gt;main.yml&lt;/a&gt; in my Badge Generator, using Yarn. This is a GH Pages site too.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a ton of GH Actions I've written and collected, covering Node, Python, GH Pages, Rust, and more. Including multiple ways to solve the same problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/workflows/" rel="noopener noreferrer"&gt;GH Actions workflows&lt;/a&gt; in Code Cookbook&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Image credits
&lt;/h2&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@kvtepov?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Vlad Kutepov&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/up?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Icons from &lt;a href="https://github.com/github/explore/tree/main/topics" rel="noopener noreferrer"&gt;github/explore&lt;/a&gt; repo.&lt;/p&gt;

</description>
      <category>actionshackathon21</category>
      <category>javascript</category>
      <category>npm</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>The History of the Computer</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Sun, 10 Oct 2021 16:42:33 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/the-history-of-the-computer-3e6p</link>
      <guid>https://forem.com/michaelcurrin/the-history-of-the-computer-3e6p</guid>
      <description>&lt;p&gt;Do you use a computer every day and wonder where it originated from? &lt;/p&gt;

&lt;p&gt;This article steps through the history of computers, covering some firsts in technology and products as well as discussing the creators behind them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a computer?
&lt;/h2&gt;

&lt;p&gt;A computer is a device that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accepts data as input.&lt;/li&gt;
&lt;li&gt;Performs programmed mathematical and logical operations at high speed.&lt;/li&gt;
&lt;li&gt;Returns some results, such as performing a physical action or displaying the results of the operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Definition according to &lt;a href="https://en.wikipedia.org/wiki/Computer"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A computer is a machine that can be programmed to carry out sequences of arithmetic or logical operations automatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where is the term "computer" from?
&lt;/h2&gt;

&lt;p&gt;A computer was originally a human clerk who completed calculations i.e. one who &lt;em&gt;computes&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;In the 1920s, the devices used to perform the tasks of the human computers were known as a "computing machine". &lt;/p&gt;

&lt;p&gt;In the 1940s, this was simply called a "computer" - usually called an "electronic computer" or "digital computer".&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did computers evolve?
&lt;/h2&gt;

&lt;p&gt;The invention of the computer in various forms introduced a lot of efficiencies, which made operations easier and sped up progress exponentially. &lt;/p&gt;

&lt;p&gt;This has continued to modern-day life.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Production, such as in factories.&lt;/li&gt;
&lt;li&gt;Instant data exchange, for business and social communication and interaction between machines.&lt;/li&gt;
&lt;li&gt;Administrative work, like booking flights and stock markets.&lt;/li&gt;
&lt;li&gt;Entertainment such as video and series.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Early computers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First computing device
&lt;/h3&gt;

&lt;p&gt;To start our view of the history of the computer, we'll go back to the first computing device - the &lt;a href="https://en.wikipedia.org/wiki/Abacus"&gt;abacus&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This was first used as a tool for calculations by the Egyptians about 3500 years ago.&lt;/p&gt;

&lt;p&gt;An abacus is a mechanical device, where the beads on the wires represent quantities and they slide on wires to show computations.&lt;/p&gt;

&lt;h3&gt;
  
  
  First mechanical calculator
&lt;/h3&gt;

&lt;p&gt;In the 1640s, &lt;a href="https://en.wikipedia.org/wiki/Blaise_Pascal"&gt;Blaise Pascal&lt;/a&gt; created the first &lt;a href="https://en.wikipedia.org/wiki/Mechanical_calculator"&gt;mechanical calculator&lt;/a&gt; or "calculating machine", at only age 19. This device is known as "Pascal's calculator" or "Pascalines". &lt;/p&gt;

&lt;p&gt;It is capable of adding and subtracting numbers. It was created to help his father, a tax collector, calculate taxes owed and paid.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Pascal_(programming_language)"&gt;Pascal&lt;/a&gt; programming language owes its name to Blaise Pascal.&lt;/p&gt;

&lt;h3&gt;
  
  
  First mechanical computer
&lt;/h3&gt;

&lt;p&gt;In the 1830s, a British mathematician named &lt;a href="https://en.wikipedia.org/wiki/Charles_Babbage"&gt;Charles Babbage&lt;/a&gt; conceptualized the first mechanical computer, and so he is regarded as the "father of computing".&lt;/p&gt;

&lt;p&gt;He wrote a detailed description of what we now call the &lt;em&gt;Analytical Engine&lt;/em&gt;. The machine's input was punch cards and its output was paper tape, but it had many similarities with modern computers.&lt;/p&gt;

&lt;p&gt;Babbage is also credited with the design of the first modern programming language, which he called 'Scheme'.&lt;/p&gt;

&lt;h3&gt;
  
  
  First concept of the modern computer
&lt;/h3&gt;

&lt;p&gt;In 1936, at Cambridge University, the mathematician and computer scientist &lt;a href="https://en.wikipedia.org/wiki/Alan_Turing"&gt;Alan Turing&lt;/a&gt; invented the principle of the modern computer.&lt;/p&gt;

&lt;p&gt;His "Turing machine" was an abstract computer, a conceptual model, and not a real physical machine. The machine was used to formally define what would now be called "effective calculability" or "computability". &lt;/p&gt;

&lt;p&gt;You may have heard of a concept named after Turing, called [Turing completeness][]. This is a way to express the power of a data manipulation rule set. Most programming languages of Turing Complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  First electronic computer
&lt;/h3&gt;

&lt;p&gt;In the 1940s, &lt;a href="https://en.wikipedia.org/wiki/Ada_Lovelace"&gt;Ada Lovelace&lt;/a&gt; created the first electronic computer. It consisted of a simple machine with electric circuits to perform mathematical calculations like addition and subtraction.&lt;/p&gt;

&lt;p&gt;Ada had the &lt;a href="https://en.wikipedia.org/wiki/Ada_(programming_language)"&gt;Ada&lt;/a&gt; programming language named after her.&lt;/p&gt;

&lt;h3&gt;
  
  
  First general-purpose computer
&lt;/h3&gt;

&lt;p&gt;In 1946, the &lt;em&gt;ENIAC&lt;/em&gt; was invented, abbreviated from "Electronic Numerical Integrator and Computer". It was the first general-purpose computer as it could be used for a variety of tasks. It was created to handle ballistic calculations for the military.&lt;/p&gt;

&lt;p&gt;It also increased performance - while other computers could only manage a few instructions per second, the ENIAC could do a billion instructions per second.&lt;/p&gt;

&lt;p&gt;It was the first &lt;em&gt;mainframe&lt;/em&gt; computer. A whole room was needed for one computer. It required about 200 feet of wiring to connect its 18,000 vacuum tubes.&lt;/p&gt;

&lt;p&gt;The ENIAC was programmed by wires and switches. Data was entered through perforated paper tapes and punched cards, like Babbage's original invention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modern computers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First commercial computer
&lt;/h3&gt;

&lt;p&gt;In the 1950s, IBM introduced the &lt;a href="https://en.wikipedia.org/wiki/IBM_704"&gt;IBM 704&lt;/a&gt; - the first mass-produced computer, with floating-point arithmetic hardware.&lt;/p&gt;

&lt;p&gt;It could execute instructions at one-third the speed of contemporary machines, but it outsold other models due to its cheaper price per kilobyte,&lt;/p&gt;

&lt;p&gt;A commercial computer in the early days cost $5,000 which is about $10,000 today.&lt;/p&gt;

&lt;p&gt;It was also significant for having the first magnetic core memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  First personal computer
&lt;/h2&gt;

&lt;p&gt;In 1966, IBM engineers designed a desktop computer small enough to place on a desk and call it the &lt;a href="https://en.wikipedia.org/wiki/IBM_Personal_Computer"&gt;IBM-PC&lt;/a&gt;. This computer changed computing and was popular with hobbyists because it could be customized with extra hardware and new software.&lt;/p&gt;

&lt;p&gt;Before personal computers for the average person, computers were used in banks, government offices, and big corporations.&lt;/p&gt;

&lt;p&gt;We could end our look at the history of the computer there, but let's go to some recent innovations in size and mobility.&lt;/p&gt;

&lt;h2&gt;
  
  
  First laptop
&lt;/h2&gt;

&lt;p&gt;In 1998, the first laptop was launched by IBM.&lt;/p&gt;

&lt;p&gt;In 2000, Apple followed with a competing device that is usually regarded as the first mass-market laptop, with a reduced size and weight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compact smart devices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First tablet
&lt;/h3&gt;

&lt;p&gt;In 2004, Apple created the first tablet, named the &lt;a href="https://en.wikipedia.org/wiki/IPad"&gt;iPad&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The iPad was a breakthrough in technology. It did not look like any computer before it. It did not work like any computer before it. However, the iPad had an impact on the development of computers because it popularized tablets and simplified our daily lives.&lt;/p&gt;

&lt;h3&gt;
  
  
  First smartphone
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Smartphone"&gt;smartphone&lt;/a&gt; is a portable device which can handle both mobile telephone and computing functions.&lt;/p&gt;

&lt;p&gt;In 1992, IBM released a smartphone prototype called "Angler".&lt;/p&gt;

&lt;p&gt;The device that is widely recognized as the first smartphone was Apple's &lt;a href="https://en.wikipedia.org/wiki/IPhone"&gt;iPhone&lt;/a&gt;. Released in 2007, it has has become the most successful smartphone in the world. The idea for "responsive" websites that could be easily viewed on mobile phones was greatly influenced by the iPhone.&lt;/p&gt;

&lt;h3&gt;
  
  
  First Smartwatch
&lt;/h3&gt;

&lt;p&gt;Around 2003, one of the first true smartwatches was released - the Microsoft SPOT (Smart Personal Object Technology). It was part of an initiative to improve the functionality of everyday objects like watches or keychains by embedding software.&lt;/p&gt;

&lt;p&gt;The SPOT was a watch that aimed to give a distraction-free presentation of digital information. It could receive info around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;weather&lt;/li&gt;
&lt;li&gt;news&lt;/li&gt;
&lt;li&gt;stock updates&lt;/li&gt;
&lt;li&gt;e-mail&lt;/li&gt;
&lt;li&gt;instant messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though there was no way to reply to messages and it required a $59/y subscription fee for updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Some research that this article was based on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/List_of_pioneers_in_computer_science"&gt;List of pioneers in computer science&lt;/a&gt; on Wikipedia.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://egov.uok.edu.in/elearningug/tutorials/7934_1_2016_161115135359.pdf"&gt;A Brief History of the Computer&lt;/a&gt; - 
University of Kashmir&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cs.uah.edu/~rcoleman/Common/History/History.html"&gt;A Brief History of Computers&lt;/a&gt; - University of Alabama&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://plato.stanford.edu/entries/computing-history/"&gt;The Modern History of Computing&lt;/a&gt; - Stanford Encyclopedia of Philosophy&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.historyofcomputer.org/"&gt;History of the Computer&lt;/a&gt; website&lt;/li&gt;
&lt;li&gt;&lt;a href="https://turbofuture.com/computers/A-Brief-History-of-the-Micro-Computer"&gt;A Brief History of the Microcomputer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.wareable.com/smartwatches/smartwatch-timeline-history-watches"&gt;Smartwatch timeline: The devices that paved the way for the Apple Watch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Related DEV.to posts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/jay_tillu/the-history-behind-the-word-computers-549l"&gt;The History behind the word “Computers”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/cher/women-s-history-month-computer-science-pioneers-71l"&gt;Women's History Month: Computer Science Pioneers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@glenncarstenspeters?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Glenn Carstens-Peters&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/old-computer?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Edited with &lt;a href="https://pixlr.com/e/"&gt;https://pixlr.com/e/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>computer</category>
      <category>history</category>
      <category>programming</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Rant on JS naming</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Tue, 17 Aug 2021 23:18:28 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/rant-on-js-naming-hnn</link>
      <guid>https://forem.com/michaelcurrin/rant-on-js-naming-hnn</guid>
      <description>&lt;p&gt;What bothers me about JS is the way packages and tools are named.&lt;/p&gt;

&lt;p&gt;This post is inspired by this &lt;a href="https://dev.to/pigozzifr/what-s-the-worst-part-about-the-js-ecosystem-42l0/comments"&gt;post&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;I don't like the naming with an extension.&lt;/p&gt;

&lt;p&gt;Like "Node.js".&lt;/p&gt;

&lt;p&gt;It is not the name of a file.&lt;/p&gt;

&lt;p&gt;Similally, react.js, vue.js, next.js... are not the names of files. Well maybe sometimes, as a compiled result, but not in the source code and it usually it is &lt;code&gt;vue-1.2.3-esm.js&lt;/code&gt; or whatever as a long name anyway.&lt;/p&gt;

&lt;p&gt;So why add extension? And not use it consistently?&lt;/p&gt;

&lt;p&gt;You don't have to tell people the name of your language in your runtime or package name. Who doesn't know what Node or React are in JS or might confuse them with something else of JS if ".js" was omitted?&lt;/p&gt;

&lt;p&gt;We don't call it "pandas.py", "requests.py", "grails.jar" or "jekyll.rb" or "rails.rb" in other languages. Yes, Python packages have Py names sometimes like Pygame or Numpy, but that is fun and artistic and doesn't go to extension level convention.&lt;/p&gt;

&lt;p&gt;And Node and Node.js and NodeJS are all (sort of) correct spellings. Things diverge in the JS community, rather than converge&lt;br&gt;
ECMAScript and ES. And ES6 and ES2015.&lt;/p&gt;

&lt;p&gt;And some say "Node dot JS" aloud,  which is annoying. It sounded so verbose on NextConf for the presenters to say Next dot JS all the time when it is clear from the context and "Next" would be fine.&lt;/p&gt;

&lt;p&gt;Typing "next.js" is the most common way for packages while "DocsifyJS" is the preferred way of some packages like in Docsify docs.&lt;/p&gt;

&lt;p&gt;Anyway, that has been bothering me a while and wanted to vent about inconsistencies in the language we love to hate but can't do without (yet).&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>rant</category>
    </item>
    <item>
      <title>Tools for designing a web project</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Wed, 23 Jun 2021 22:16:34 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/tools-for-designing-a-web-project-4b1c</link>
      <guid>https://forem.com/michaelcurrin/tools-for-designing-a-web-project-4b1c</guid>
      <description>&lt;p&gt;I have a bunch of projects I am working on for fun, mostly around web apps. Some of them are just concepts and some exist but need a revamp for a professional design.&lt;/p&gt;

&lt;p&gt;So I want to share some of the tools I am using in my process. From designing the layout of the page to choosing color schemes and images. So when I start coding, I have the design and artistic decisions mostly figured out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whimsical
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://whimsical.com/"&gt;https://whimsical.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A free, intuitive wireframing tool.&lt;/p&gt;

&lt;p&gt;Design your app for mobile or desktop. Create some webpage wireframes where you can see your whole website laid out on one giant page, with arrows and lines connecting them.&lt;/p&gt;

&lt;p&gt;The ability to add styling is limited, but this is fine as it keeps the emphasis on laying out pages and components on pages, rather than colors or fonts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wix
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wix.com"&gt;https://wix.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've used Wix before to prototype designs for a site, even though I end up coding the site myself after for more control. &lt;/p&gt;

&lt;p&gt;Being able to move around elements and add a gallery in a few clicks is amazing. Then code it yourself when you are ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  Webflow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webflow.com/"&gt;https://webflow.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://webflow.com/blog/best-webflow-templates"&gt;10 best templates of 2021&lt;/a&gt; on their blog.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a web design and hosting tool like Wix, but with finer control over styling like adding classes to elements. Wix is ideal for non-developers while Webflow is intended for developers.&lt;/p&gt;

&lt;p&gt;You can also add a CMS layer and ecommerce aspect to your site.&lt;/p&gt;

&lt;p&gt;I want to use this to prototype my designs.&lt;/p&gt;

&lt;p&gt;You need premium for Wix and Webflow if you want to remove ads and use a custom domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coolors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://coolors.co/image-picker"&gt;https://coolors.co/image-picker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I need to choose a color palette that is harmonious.&lt;/p&gt;

&lt;p&gt;On Coolors, I can find existing palettes by other users or make one myself.&lt;/p&gt;

&lt;p&gt;There are probably many similar sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unsplash
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://unsplash.com"&gt;https://unsplash.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a great stock images site. Search for high quality high resolution stock photos. Link to the image on their CDN at the appropriate resolution from your site, or download them and add them to your site.&lt;/p&gt;

&lt;p&gt;They are all free. You are encouraged to use a credit to the author but this is not required.&lt;/p&gt;

&lt;p&gt;You'll find dev.to and other blogs tend to have cover images found on Unsplash (which some images of laptops and code on screens being used annoyingly often but such is life).&lt;/p&gt;

&lt;h2&gt;
  
  
  Free SVG
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://freesvg.org/"&gt;https://freesvg.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similar to Unsplash for searching for SVG files. An SVG can be scaled to any time and is typically small in file size, so it great for small icons to a large logo on your site.&lt;/p&gt;

&lt;p&gt;Images are under the creative commons license.&lt;/p&gt;

&lt;p&gt;I used this tool to find a dragon image which I added to my one project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MichaelCurrin/search-dragon"&gt;https://github.com/MichaelCurrin/search-dragon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;I hope you learned about some new tools and feel inspired to go and design something. Let me know of other similar tools to recommend.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>design</category>
      <category>wireframing</category>
    </item>
    <item>
      <title>Search Dragon - my search engine web app 🔍🐲</title>
      <dc:creator>Michael Currin</dc:creator>
      <pubDate>Tue, 22 Jun 2021 13:51:58 +0000</pubDate>
      <link>https://forem.com/michaelcurrin/search-dragon-search-tool-3dm6</link>
      <guid>https://forem.com/michaelcurrin/search-dragon-search-tool-3dm6</guid>
      <description>&lt;p&gt;This post is about a simple and fun search engine aggregator tool I created recently. I'm going to talk about how I made it and discuss some of the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background 🐲
&lt;/h2&gt;

&lt;p&gt;Someone asked me to build a useful and fun search tool.&lt;/p&gt;

&lt;p&gt;We had just watched &lt;a href="https://www.netflix.com/title/81153694" rel="noopener noreferrer"&gt;Wish Dragon&lt;/a&gt; on Netflix. &lt;/p&gt;

&lt;p&gt;The Chinese dragon imagery inspired the name and design.&lt;/p&gt;

&lt;p&gt;I used this as a chance to learn an unfamiliar area of JavaScript - opening tabs. &lt;/p&gt;

&lt;p&gt;Vue seemed like a natural choice for handling events and data in JS. It would look similar if it was built in React instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web app 🐉
&lt;/h2&gt;

&lt;p&gt;I put it together in a few hours and I am pleased to announce Search Dragon as an online tool you can use. &lt;/p&gt;

&lt;h3&gt;
  
  
  Preview
&lt;/h3&gt;

&lt;p&gt;Do a search:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://michaelcurrin.github.io/search-dragon/" 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%2Fgithub.com%2FMichaelCurrin%2Fsearch-dragon%2Fraw%2Fv0.4.0%2Fsample-1.png" alt="Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the tabs opened:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://michaelcurrin.github.io/search-dragon/" 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%2Fgithub.com%2FMichaelCurrin%2Fsearch-dragon%2Fraw%2Fv0.4.0%2Fsample-2.png" alt="Screenshot 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Website
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://michaelcurrin.github.io/search-dragon/" rel="noopener noreferrer"&gt;https://michaelcurrin.github.io/search-dragon/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;It aggregates searches from popular search engines, including Google and Yahoo, Bing, DuckDuckGo, and Yandex. If for some reason you care about comparing results from each one or balancing your search without being biased by using just one tool.&lt;/p&gt;

&lt;p&gt;The app provides some automation to save you copy and pasting searches in multiple windows. You can enter your search query &lt;strong&gt;once&lt;/strong&gt; and then a tab will be opened for each search engine. &lt;/p&gt;

&lt;p&gt;Then you run a new search query, the existing tabs get &lt;em&gt;reused&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is it built on? ⛩
&lt;/h2&gt;

&lt;p&gt;I use GitHub and GitHub Pages to host most of my websites.&lt;/p&gt;

&lt;p&gt;This project was built on JavaScript and the &lt;a href="https://v3.vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; framework. But &lt;em&gt;without&lt;/em&gt; using Node or a build step. See my &lt;a href="https://github.com/MichaelCurrin/vue-frontend-quickstart" rel="noopener noreferrer"&gt;Vue Frontend Quickstart&lt;/a&gt; for a template and info on how that works.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work? 🔍
&lt;/h2&gt;

&lt;p&gt;The core of the app is 3 parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Capture user query in HTML &lt;code&gt;input&lt;/code&gt; element text box.&lt;/li&gt;
&lt;li&gt;Create the search URLs for each search engine, based on the user's query.&lt;/li&gt;
&lt;li&gt;When the user submits, use JavaScript to open each URL in a tab.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Build the URLs
&lt;/h3&gt;

&lt;p&gt;It was easy to build the query URLs in the web app. &lt;/p&gt;

&lt;p&gt;In &lt;a href="https://github.com/MichaelCurrin/search-dragon/blob/main/main.js" rel="noopener noreferrer"&gt;main.js&lt;/a&gt;, I set up a base URL and then append a URL-encoded query to it. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bingUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BING_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// https://www.bing.com/search?q=my+search+query&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note use of a plus sign for a space. A percent-encoding of &lt;code&gt;%20&lt;/code&gt; would also work but a plus sign is more readable and seems favored by some websites.&lt;/p&gt;

&lt;p&gt;Four of the search engines use &lt;code&gt;q&lt;/code&gt; as the query parameter. And one of them uses &lt;code&gt;text&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Open the tabs
&lt;/h3&gt;

&lt;p&gt;I used JavaScript's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/open" rel="noopener noreferrer"&gt;Window.open&lt;/a&gt; browser function to open multiple tabs for the user. The JS is around &lt;em&gt;windows&lt;/em&gt;, but fortunately, they do get opened as &lt;em&gt;tabs&lt;/em&gt; in the same browser window instead of as new windows.&lt;/p&gt;

&lt;p&gt;Here is an example of opening a URL with a given window name, then opening a different URL in the &lt;em&gt;same&lt;/em&gt; tab.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dev.to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devTo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dev.to/michaelcurrin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devTo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Listen to submission event
&lt;/h3&gt;

&lt;p&gt;When a visitor clicks the search button, a function is run to open multiple tabs for the user.&lt;/p&gt;

&lt;p&gt;When pressing Enter, then the search is also run.&lt;/p&gt;

&lt;p&gt;In Vue, this is set up with an Event Listener like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;keyup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;myFunction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I could have used a "form" approach in HTML and Vue, but the simpler approach I used ended up being fine, especially since there is only one input.&lt;/p&gt;
&lt;h2&gt;
  
  
  Repo 🔥
&lt;/h2&gt;

&lt;p&gt;Here is the repo on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MichaelCurrin" rel="noopener noreferrer"&gt;
        MichaelCurrin
      &lt;/a&gt; / &lt;a href="https://github.com/MichaelCurrin/search-dragon" rel="noopener noreferrer"&gt;
        search-dragon
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The meta search engine 🔍 🐲
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Search Dragon 🔍 🐲&lt;/h1&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The meta search engine&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/search-dragon/releases/" title="View GitHub releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/05aa5dcc2a3d7328fb08206f9060fd65ffd4901105bbace2cef592b615a35b34/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7461672f4d69636861656c43757272696e2f7365617263682d647261676f6e3f696e636c7564655f70726572656c65617365733d26736f72743d73656d766572" alt="GitHub tag"&gt;&lt;/a&gt;
&lt;a href="https://github.com/MichaelCurrin/search-dragon#license" title="Go to License section" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/371a602912faf7afd95fb8d7c0d8846e048157c4f50ae5ede617f56320429998/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c7565" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/vue" title="Go to Vue on NPM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/04268215bc4d0dd2197dadbc26c095b419a3d6f2a3796179434003e451563b2a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7675652d332d626c75653f6c6f676f3d7675652e6a73266c6f676f436f6c6f723d7768697465" alt="Dependency - vue"&gt;&lt;/a&gt;
&lt;a href="https://pages.github.com/" title="Go to GitHub Pages homepage" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f321cad40707bd47bd70ce0e81619f0820d44e82bbb19fc519447604b1efcf74/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f486f737465645f776974682d4769744875625f50616765732d626c75653f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Hosted with GH Pages"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Preview&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The web app:&lt;/p&gt;
&lt;div&gt;
    &lt;a href="https://michaelcurrin.github.io/search-dragon/" rel="nofollow 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%2Fgithub.com%2FMichaelCurrin%2Fsearch-dragon%2Fsample-1.png" alt="Sample screenshot" title="Go to Search Dragon website" width="350"&gt;
    &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;A view of new tabs opened, when searching all search engines.&lt;/p&gt;
&lt;div&gt;
    &lt;a href="https://michaelcurrin.github.io/search-dragon/" rel="nofollow 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%2Fgithub.com%2FMichaelCurrin%2Fsearch-dragon%2Fsample-2.png" alt="Sample screenshot of tabs" title="Go to Search Dragon website" width="900"&gt;
    &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Use the web app&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Enter a query once and search on multiple search engines at once. Reusing tabs for each site so you don't lose control of tabs.&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://michaelcurrin.github.io/search-dragon/" title="Go to Search Dragon website" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dcfb5c8102b066c3b237269d6f7f6c463f02095dfe4af1505c2dd03cd1da7c1a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566965775f736974652d47485f50616765732d3265613434663f7374796c653d666f722d7468652d6261646765" alt="View site - GH Pages"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Follow the instructions on the site.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;

&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://github.com/MichaelCurrin/search-dragon/docs/" title="View documentation" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8367ad0800c028f980dd31bbad750c910be8889c0cad1da0dbd87b03622b2d64/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566965772d446f63756d656e746174696f6e2d626c75653f7374796c653d666f722d7468652d6261646765" alt="View - Documentation"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;License&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Released under &lt;a href="https://github.com/MichaelCurrin/search-dragon/LICENSE" rel="noopener noreferrer"&gt;MIT&lt;/a&gt; by &lt;a href="https://github.com/MichaelCurrin" rel="noopener noreferrer"&gt;@MichaelCurrin&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MichaelCurrin/search-dragon" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The codebase is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;index.html&lt;/code&gt; - static content.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main.js&lt;/code&gt; - dynamic content based on user interaction and configured data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;styles.css&lt;/code&gt; - styling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;code&gt;package.json&lt;/code&gt; or &lt;code&gt;node_modules&lt;/code&gt;! I used the modern ES Modules approach so that I can do an import in my JS directly from a CDN.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://unpkg.com/vue@3.1.1/dist/vue.esm-browser.prod.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note on content - I didn't put &lt;em&gt;all&lt;/em&gt; the content in &lt;code&gt;main.js&lt;/code&gt;. If JS is disabled or a search engine crawls my site, it might appear a mostly blank. So the content that can be static HTML is left as static HTML - this improves the user's loading experience and SEO ranking (because crawlers can understand my site better).&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits 📷
&lt;/h2&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@shimikumi32?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Kumiko SHIMIZU&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
