<?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: Pelle Nilsen</title>
    <description>The latest articles on Forem by Pelle Nilsen (@pellenilsen).</description>
    <link>https://forem.com/pellenilsen</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%2F1435801%2Fd460aae9-8554-454c-89c9-db7ecf638d97.png</url>
      <title>Forem: Pelle Nilsen</title>
      <link>https://forem.com/pellenilsen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pellenilsen"/>
    <language>en</language>
    <item>
      <title>What does CORS really do? 🤔</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Wed, 30 Oct 2024 14:22:13 +0000</pubDate>
      <link>https://forem.com/pellenilsen/what-does-cors-really-do-53fi</link>
      <guid>https://forem.com/pellenilsen/what-does-cors-really-do-53fi</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Same-Origin Policy Problem 🔒&lt;/li&gt;
&lt;li&gt;Enter CORS: The Security Guard 💂&lt;/li&gt;
&lt;li&gt;Common CORS Headers Explained 📋&lt;/li&gt;
&lt;li&gt;Quick Node.js/Express Implementation 🛠️&lt;/li&gt;
&lt;li&gt;Common CORS Gotchas 🎯&lt;/li&gt;
&lt;li&gt;Best Practices 🌟&lt;/li&gt;
&lt;li&gt;Conclusion 🎬&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CORS (Cross-Origin Resource Sharing) is often misunderstood as just another security headache for developers. Let's break down what it actually does and why it's crucial for web security.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Same-Origin Policy Problem 🔒 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine you're at &lt;code&gt;app1.com&lt;/code&gt; and your JavaScript code tries to fetch data from &lt;code&gt;app2.com&lt;/code&gt;. Without CORS, this request would be blocked by the browser's same-origin policy. This policy prevents a malicious website from reading sensitive data from another website - like your banking details or private messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter CORS: The Security Guard 💂 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;CORS acts like a security guard that allows controlled access between different domains. Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Request:&lt;/strong&gt; Your frontend code makes a request to a different domain:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Frontend at app1.com&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://api.app2.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&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="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Preflight:&lt;/strong&gt; For certain requests, the browser first sends an OPTIONS request to check if the actual request is allowed:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;OPTIONS&lt;/span&gt; &lt;span class="nn"&gt;/data&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;api.app2.com&lt;/span&gt;
&lt;span class="na"&gt;Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://app1.com&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Request-Method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GET&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Request-Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Content-Type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Permission:&lt;/strong&gt; The server responds with what's allowed:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://app1.com&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GET, POST&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Content-Type&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Max-Age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;86400&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common CORS Headers Explained 📋 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;: Who can access the resource

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; means everyone (use cautiously‼️)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;https://app1.com&lt;/code&gt; means only that specific domain&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;Access-Control-Allow-Methods&lt;/code&gt;: Allowed HTTP methods

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;GET, POST, PUT, DELETE&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;Access-Control-Allow-Headers&lt;/code&gt;: Allowed request headers

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;Content-Type, Authorization&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;Access-Control-Max-Age&lt;/code&gt;: How long to cache preflight results

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;86400&lt;/code&gt; (24 hours)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Node.js/Express Implementation 🛠️ &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Here's how to implement CORS in a Node.js/Express server:&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access-Control-Allow-Origin&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="s1"&gt;https://app1.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access-Control-Allow-Methods&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="s1"&gt;GET, POST, PUT, DELETE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access-Control-Allow-Headers&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="s1"&gt;Content-Type, Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Handle preflight&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPTIONS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Or use the cors package&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://app1.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&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="s1"&gt;POST&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="s1"&gt;PUT&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="s1"&gt;DELETE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;allowedHeaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&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="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common CORS Gotchas 🎯 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Credentials:&lt;/strong&gt; If you're sending cookies or auth headers, you need:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Frontend&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Backend&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access-Control-Allow-Credentials&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="s1"&gt;true&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Wildcard Limitations:&lt;/strong&gt; You can't use &lt;code&gt;*&lt;/code&gt; with credentials
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This won't work with credentials&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access-Control-Allow-Origin&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="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Use specific origins instead&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access-Control-Allow-Origin&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="s1"&gt;https://app1.com&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;h2&gt;
  
  
  Best Practices 🌟 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Be Specific:&lt;/strong&gt; Avoid using &lt;code&gt;*&lt;/code&gt; for &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit Methods:&lt;/strong&gt; Only allow necessary HTTP methods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Preflights:&lt;/strong&gt; Set appropriate &lt;code&gt;Access-Control-Max-Age&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Credentials:&lt;/strong&gt; Be extra careful when allowing credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate Origins:&lt;/strong&gt; Maintain a whitelist of allowed domains&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion 🎬 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;CORS isn't just a barrier - it's a crucial security feature that protects users while enabling controlled cross-origin communication. Understanding how it works helps you implement it correctly and debug issues more effectively.&lt;/p&gt;

&lt;p&gt;Remember: CORS is enforced by browsers, not servers. Server-to-server communication doesn't use CORS, so make sure to implement proper security measures for those scenarios.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>security</category>
    </item>
    <item>
      <title>TrackFlix: From Idea to Reality - A Subscription Tracking Revolution</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Wed, 02 Oct 2024 12:02:15 +0000</pubDate>
      <link>https://forem.com/pellenilsen/trackflix-from-idea-to-reality-a-subscription-tracking-revolution-ken</link>
      <guid>https://forem.com/pellenilsen/trackflix-from-idea-to-reality-a-subscription-tracking-revolution-ken</guid>
      <description>&lt;p&gt;&lt;a href="https://budget.pellenilsen.no/" rel="noopener noreferrer"&gt;Try TrackFlix today and start optimizing your subscriptions!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's digital age, subscription-based services have become an integral part of our lives. From streaming platforms to productivity tools, managing multiple subscriptions can be a daunting task. Enter TrackFlix, a comprehensive subscription tracking application designed to help users stay on top of their recurring expenses. In this blog post, I'll take you through the journey of TrackFlix, from its inception to its current feature-rich state.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spark of an Idea
&lt;/h2&gt;

&lt;p&gt;The idea for TrackFlix was born out of a common frustration: the inability to keep track of numerous subscriptions. I was never able to keep track of my subscriptions. Never knew how much I wasted on un-used subscriptions, I just knew that I lost money. This realization sparked the desire to create a tool that would help people regain control over their subscription expenses and eliminate wasteful spending on unused services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Journey
&lt;/h2&gt;

&lt;p&gt;The journey from concept to a fully-functional application was surprisinly swift. It took just one week to develop the completed app, showcasing the power of modern web development tools and frameworks. However, this rapid development didn't come without its challenges.&lt;/p&gt;

&lt;p&gt;The primary hurdle was designing an intuitive user interface. As I explained, "The challenge was trying to figure out how to make it easy to navigate and keep track of your subscriptions, so it was easy for users to use." This focus on user experience drove many of the design decisions and features that make TrackFlix stand out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://budget.pellenilsen.no/" rel="noopener noreferrer"&gt;Try TrackFlix today and start optimizing your subscriptions!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features of TrackFlix
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Intuitive Calendar View
&lt;/h3&gt;

&lt;p&gt;At the heart of TrackFlix is a user-friendly calendar interface that provides a visual representation of all your subscriptions. This feature allows users to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quickly identify upcoming payments&lt;/li&gt;
&lt;li&gt;View subscription details at a glance&lt;/li&gt;
&lt;li&gt;Navigate through months and years effortlessly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Comprehensive Subscription Management
&lt;/h3&gt;

&lt;p&gt;TrackFlix offers a robust system for managing subscriptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add new subscriptions with detailed information&lt;/li&gt;
&lt;li&gt;Edit existing subscriptions&lt;/li&gt;
&lt;li&gt;Set reminders for upcoming payments&lt;/li&gt;
&lt;li&gt;Categorize subscriptions for better organization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Financial Insights
&lt;/h3&gt;

&lt;p&gt;To help users understand their spending habits, TrackFlix provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monthly spending overview&lt;/li&gt;
&lt;li&gt;Total paid amount over time&lt;/li&gt;
&lt;li&gt;Spending breakdown by category&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Multi-Currency Support
&lt;/h3&gt;

&lt;p&gt;Recognizing the global nature of subscriptions, TrackFlix supports multiple currencies, allowing users to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch between different currencies (EUR, USD, GBP, NOK, INR, JPY)&lt;/li&gt;
&lt;li&gt;View all financial data in their preferred currency&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Pre-implemented Subscription Logos
&lt;/h3&gt;

&lt;p&gt;To enhance user experience and speed up the subscription addition process, TrackFlix includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dropdown menu with pre-implemented logos for popular services&lt;/li&gt;
&lt;li&gt;Automatic population of subscription names when selecting a logo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://budget.pellenilsen.no/" rel="noopener noreferrer"&gt;Try TrackFlix today and start optimizing your subscriptions!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Implementation
&lt;/h2&gt;

&lt;p&gt;TrackFlix is built using modern web technologies to ensure a smooth and responsive user experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React.js with hooks for state management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling&lt;/strong&gt;: Tailwind CSS for a sleek, customizable UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Persistence:&lt;/strong&gt; Local storage for saving user data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Date Handling:&lt;/strong&gt; Native JavaScript Date object for managing subscription dates and reminders&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  User Feedback and Continuous Improvement
&lt;/h2&gt;

&lt;p&gt;After publishing TrackFlix on the JSM Discord server, I received valueable feedback from the community. Users appriciated the app but suggested some improvements, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pre-installed logos for popular subscription services&lt;/li&gt;
&lt;li&gt;A mobile-friendly view for on-the-go subscription management
These suggestions were quickly incorporated into the app, demonstrating TrackFlix's commitment to user-driven development and continuous improvement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://budget.pellenilsen.no/" rel="noopener noreferrer"&gt;Try TrackFlix today and start optimizing your subscriptions!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Roadmap
&lt;/h2&gt;

&lt;p&gt;While TrackFlix already offers a comprehensive set of features, I'm constantly looking to improve and expand. Some exciting future enhancements include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Family sharing as a paid plan, allowing multiple users to manage shared subscriptions&lt;/li&gt;
&lt;li&gt;Money-saving tips to help users optimize their subscription spending&lt;/li&gt;
&lt;li&gt;An advanced analyzer that evaluates your subscriptions and suggests cheaper alternatives&lt;/li&gt;
&lt;li&gt;Data visualization with charts and graphs&lt;/li&gt;
&lt;li&gt;Budget setting and alerts&lt;/li&gt;
&lt;li&gt;Payment method tracking&lt;/li&gt;
&lt;li&gt;Import/export functionality for data portability&lt;/li&gt;
&lt;li&gt;Dark/light mode toggle for user preference&lt;/li&gt;
&lt;li&gt;Integration with banking APIs for automatic subscription detection
These planned features aim to make TrackFlix not just a tracking tool, but a comprehensive subscription management and optimization platform.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;TrackFlix has evolved from a simple idea to a powerful tool for managing subscription expenses in just one week. By combining intuitive design with robust functionality, it addresses a common pain point in our ever increasing subscription-based world. The rapid development and incorporation of user feedback demonstrate the agility and user-centric approach behind TrackFlix.&lt;/p&gt;

&lt;p&gt;As I continue to refine and expand TrackFlix, I remain commited to my goal of helping users take control of their digital subscriptions and make informed financial decisions. The planned features, especially the family sharing option and money-saving analyzer, promise to take subscription management to the next level.&lt;/p&gt;

&lt;p&gt;I invite you to try TrackFlix and experience the ease of subscription management for yourself. Your feedback and suggestions are invalueable as I work to make TrackFlix even better.&lt;/p&gt;

&lt;p&gt;Thank you for joining me on this journey, and here's to a future of smarter subscription management!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://budget.pellenilsen.no/" rel="noopener noreferrer"&gt;Try TrackFlix today and start optimizing your subscriptions!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to Use CSS Properly: Best Practices for Clean and Efficient Styling</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Sun, 29 Sep 2024 14:43:31 +0000</pubDate>
      <link>https://forem.com/pellenilsen/how-to-use-css-properly-best-practices-for-clean-and-efficient-styling-1j5c</link>
      <guid>https://forem.com/pellenilsen/how-to-use-css-properly-best-practices-for-clean-and-efficient-styling-1j5c</guid>
      <description>&lt;p&gt;Cascading Style Sheets (CSS) is a fundamental technology in web development, allowing designers and developers to create visually appealing and responsive websites. However, without proper usage, CSS can quickly become unwieldy and difficult to maintain. In this article, we'll explore best practices for using CSS effectively, ensuring your stylesheets remain clean, efficient, and scalable.&lt;/p&gt;

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

&lt;p&gt;CSS (Cascading Style Sheets) is a styling language used to describe the presentation of a document written in HTML or XML. It defines how elements should be displayed on screen, on paper, or in other media.&lt;/p&gt;

&lt;h2&gt;
  
  
  Characteristics of Good CSS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Organized and Structured
&lt;/h3&gt;

&lt;p&gt;Good CSS is well-organized and follows a logical structure. This makes it easier to navigate, understand, and maintain.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Good CSS structure */&lt;/span&gt;
&lt;span class="c"&gt;/* Base styles */&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Layout */&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.main-content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Components */&lt;/span&gt;
&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Utilities */&lt;/span&gt;
&lt;span class="nc"&gt;.text-center&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.m-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Follows a Naming Convention
&lt;/h3&gt;

&lt;p&gt;Consistent naming conventions, such as BEM (Block Element Modifier) or SMACSS, help create more readable and maintainable CSS.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Using BEM naming convention */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card__title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card__content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card--featured&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Utilizes CSS Preprocessing
&lt;/h3&gt;

&lt;p&gt;CSS preprocessors like Sass or Less allow for more powerful and efficient styling through features like variables, nesting, and mixins.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;Sass&lt;/span&gt; &lt;span class="nt"&gt;variables&lt;/span&gt; &lt;span class="nt"&gt;and&lt;/span&gt; &lt;span class="nt"&gt;nesting&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;primary-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#3498&lt;/span&gt;&lt;span class="nt"&gt;db&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;primary-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;&amp;amp;:hover&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;darken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;primary-color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Responsive and Flexible
&lt;/h3&gt;

&lt;p&gt;Good CSS is designed to be responsive, adapting to different screen sizes and devices.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Responsive design using media queries */&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optimized for Performance
&lt;/h3&gt;

&lt;p&gt;Efficient CSS minimizes redundancy and prioritizes performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Optimized CSS */&lt;/span&gt;
&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Use shorthand properties */&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* Avoid expensive properties when possible */&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Characteristics of Bad CSS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overly Specific Selectors
&lt;/h3&gt;

&lt;p&gt;Highly specific selectors can lead to specificity issues and make your CSS harder to maintain.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Bad: Overly specific */&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.link&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Better: More general */&lt;/span&gt;
&lt;span class="nc"&gt;.nav-link&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Repetitive Code
&lt;/h3&gt;

&lt;p&gt;Repeating the same styles across multiple selectors leads to bloated stylesheets.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Bad: Repetitive */
.header { font-size: 16px; color: #333; }
.footer { font-size: 16px; color: #333; }

/* Better: Use a common class */
.text-default { font-size: 16px; color: #333; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inline Styles
&lt;/h3&gt;

&lt;p&gt;Overuse of inline styles makes it difficult to maintain consistency and override styles when needed.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;Bad&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;Inline&lt;/span&gt; &lt;span class="nt"&gt;styles&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"margin: 10px; padding: 5px; background-color: #f0f0f0;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;Better&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;Use&lt;/span&gt; &lt;span class="nt"&gt;classes&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"box"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  !important Overuse
&lt;/h3&gt;

&lt;p&gt;Relying on !important to solve specificity issues can lead to a cascade of overrides.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Bad: Overusing !important */&lt;/span&gt;
&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Better: Use more specific selectors or restructure your CSS */&lt;/span&gt;
&lt;span class="nc"&gt;.primary-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Lack of Comments
&lt;/h3&gt;

&lt;p&gt;CSS without comments can be difficult to understand, especially for large projects or when working in teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Using CSS Properly
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use a CSS Methodology:&lt;/strong&gt; Adopt a methodology like BEM, SMACSS, or OOCSS to organize your CSS and improve maintainability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leverage CSS Preprocessors:&lt;/strong&gt; Use Sass or Less to write more efficient and powerful CSS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement a Style Guide:&lt;/strong&gt; Create and maintain a style guide to ensure consistency across your project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimize for Performance:&lt;/strong&gt; Minimize CSS files, use shorthand properties, and avoid unnecessary selectors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write Mobile-First CSS:&lt;/strong&gt; Start with styles for mobile devices and use media queries to enhance for larger screens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use CSS Custom Properties:&lt;/strong&gt; Leverage CSS variables for more flexible and maintainable stylesheets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Deep Nesting:&lt;/strong&gt; Keep your CSS selectors shallow to improve performance and reduce specificity issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comment Your Code:&lt;/strong&gt; Add meaningful comments to explain complex selectors or hacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a CSS Linter:&lt;/strong&gt; Tools like StyleLint can help catch errors and enforce consistent coding styles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep Learning:&lt;/strong&gt; CSS is constantly evolving. Stay updated with new features and best practices.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Using CSS properly is crucial for creating maintainable, efficient, and scalable web applications. By following these best practices, you can write cleaner CSS that's easier to understand, modify, and scale. Remember, good CSS not only makes your websites look great but also contributes to better performance and developer experience. Happy styling!&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>beginners</category>
    </item>
    <item>
      <title>API Design and Development: Best practices for creating robust and scalable APIs.</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Fri, 20 Sep 2024 06:47:57 +0000</pubDate>
      <link>https://forem.com/pellenilsen/api-design-and-development-best-practices-for-creating-robust-and-scalable-apis-47mf</link>
      <guid>https://forem.com/pellenilsen/api-design-and-development-best-practices-for-creating-robust-and-scalable-apis-47mf</guid>
      <description>&lt;p&gt;In the ever-evolving landscape of software development, APIs (Application Programming Interfaces) have become the backbone of modern applications. They enable seamless communication between different systems, allowing developers to build complex, interconnected solutions. However, creating an API that is both robust and scalable requires careful planning and adherence to best practices. In this article, we'll explore the key principles and strategies for designing and developing APIs that stand the test of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an API?
&lt;/h2&gt;

&lt;p&gt;Before diving into best practices, let's quickly define what an API is. An API is a set of protocols, routines and tools for building software applications. It specifies how software components should interact, allowing different applications to communicate with each other effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Characteristics of a Good API
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Clear and Consistent Naming Conventions
&lt;/h3&gt;

&lt;p&gt;A good API uses clear, consistent and intuitive naming conventions for endpoints, parameters and responses.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Good API endpoint
GET /users/{id}

# Bad API endpoint
GET /get_user_data?user_id={id}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Proper Use of HTTP Methods
&lt;/h3&gt;

&lt;p&gt;Utilize HTTP methods correctly to represent the action being performed on the resource.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Good usage of HTTP methods
GET /articles (Retrieve all articles)
POST /articles (Create a new article)
PUT /articles/{id} (Update an entire article)
PATCH /articles/{id} (Partially update an article)
DELETE /articles/{id} (Delete an article)

# Bad usage
GET /create_article
POST /update_article
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Versioning
&lt;/h3&gt;

&lt;p&gt;Implement versioning to maintain backward compatibility while allowing for future improvements.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Good versioning
https://api.example.com/v1/users

# Alternative versioning (in header)
Accept: application/vnd.example.v2+json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Proper Error Handling
&lt;/h3&gt;

&lt;p&gt;Provide meaningful error messages and appropriate HTTP status codes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"User not found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"No user exists with the ID 12345"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pagination
&lt;/h3&gt;

&lt;p&gt;Implement pagination for endpoints that return large datasets to improve performance and usability.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /articles?page=2&amp;amp;limit=20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Characteristics of a Bad API
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Inconsistent Design
&lt;/h3&gt;

&lt;p&gt;An API with inconsistent naming conventions, response formats or error handling can be confusing and difficult to use.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Inconsistent naming (Bad practice)
GET /users
GET /fetch-articles
GET /products_list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Lack of Documentation
&lt;/h3&gt;

&lt;p&gt;Poor or missing documentation makes it challenging for developers to understand and integrate with the API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overexposing Internal Details
&lt;/h3&gt;

&lt;p&gt;Exposing too much of the internal system structure or implementation details can make the API brittle and hard to maintain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignoring Security Best Practices
&lt;/h3&gt;

&lt;p&gt;Failing to implement proper authentication, authorization and data validation can lead to security vulnerabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Poor Performance
&lt;/h3&gt;

&lt;p&gt;APIs that are slow, unoptimized or prone to rate limiting issues can frustrate users and limit adoption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for API Design and Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Design with the Consumer in Mind
&lt;/h3&gt;

&lt;p&gt;Always consider the needs and expectations of the API consumers when designing endpoints and response structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use RESTful Principles
&lt;/h3&gt;

&lt;p&gt;Follow RESTful principles for a standardized approach to API design, making your API intuitive and easy to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Proper Authentication and Authorization
&lt;/h3&gt;

&lt;p&gt;Secure your API using industry-standard authentication methods (e.g., OAuth 2.0, JWT) and implement fine-grained authorization.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Provide Comprehensive Documentation
&lt;/h3&gt;

&lt;p&gt;Create detailed, up-to-date documentation that includes examples, explanations of all endpoints, parameters and possible responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use HTTPS
&lt;/h3&gt;

&lt;p&gt;Always use HTTPS to ensure secure communication between clients and your API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Rate Limiting
&lt;/h3&gt;

&lt;p&gt;Protect your API from abuse and ensure fair usage by implementing rate limiting.&lt;/p&gt;

&lt;p&gt;Example response header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X-RateLimit-Limit: 100
X-RateLimit-Remaining: 75
X-RateLimit-Reset: 1623423896
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Design for Scalability
&lt;/h3&gt;

&lt;p&gt;Consider caching strategies, database optimizations and horizontal scaling capabilities from the outset.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Monitoring and Logging
&lt;/h3&gt;

&lt;p&gt;Set up comprehensive monitoring and logging to track API usage, performance metrics, and potential issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Content Negotiation
&lt;/h3&gt;

&lt;p&gt;Support multiple response formats (e.g., JSON, XML) through content negotiation.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Accept: application/json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Provide a Sandbox Environment
&lt;/h3&gt;

&lt;p&gt;Offer a sandbox or staging environment for developers to test integrations without affecting production data.&lt;/p&gt;

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

&lt;p&gt;Designing and developing a robust, scalable API requires careful planning and adherence to best practices. By following these guidelines, you can create APIs that are easy to use, maintain and scale. Remember that good API design is an iterative process – continually gather feedback from your users and be prepared to evolve your API over time.&lt;/p&gt;

&lt;p&gt;Whether you're building a public API for third-party developers or an internal API for your microservices architecture, these best practices will help ensure your API stands the test of time and meets the needs of its consumers. Happy API designing!&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>backend</category>
      <category>programming</category>
    </item>
    <item>
      <title>How I Won the JSM Programming Challenge</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Thu, 19 Sep 2024 15:18:14 +0000</pubDate>
      <link>https://forem.com/pellenilsen/how-i-won-the-jsm-programming-challenge-39oo</link>
      <guid>https://forem.com/pellenilsen/how-i-won-the-jsm-programming-challenge-39oo</guid>
      <description>&lt;p&gt;In the vast universe of programming challenges, the JSM Programming Challenge stands out as a stellar opportunity for developers to showcase their skills and creativity. Last month's theme, "Video Games", set the stage for an exciting competition that pushed participants to explore new frontiers in game development. In this blog post, I'll share my journey of how I created "Cosmic Explorer", the game that ultimately led me to victory in this interstellar coding adventure.&lt;/p&gt;

&lt;p&gt;Game: &lt;a href="https://cosmic-exporer.pellenilsen.no/" rel="noopener noreferrer"&gt;Cosmic Explorer&lt;/a&gt;&lt;br&gt;
Code: &lt;a href="https://github.com/PelleNIlsen/Cosmic-Explorer" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Challenge: A Universe of Possibilities
&lt;/h2&gt;

&lt;p&gt;The JSM Programming Challenge presented participants with a broad theme: "Video Games". We had the freedom to create a video game from scratch, utilize a game API, or even build a fan page for an existing game. The possibilities were as endless as the cosmos itself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Choosing My Path: The Birth of Cosmic Explorer
&lt;/h2&gt;

&lt;p&gt;After some brainstorming sessions with my girlfriend (who, spoiler alert, became my secret weapon in this challenge), we decided to embark on creating a space-based game. Thus, "Cosmic Explorer" was born - a game centered around space exploration, resource gathering from distant planets and battling enemy ships.&lt;/p&gt;
&lt;h2&gt;
  
  
  Preparing for the Journey: Learning Phaser
&lt;/h2&gt;

&lt;p&gt;One of the most crucial decisions I made was choosing Phaser as my game development library. Despite never having created a web game before, I was drawn to Phaser's capabilities and decided to take the plunge. This decision set the stage for both my greatest challenge and my most significant learning experience during the competition.&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="c1"&gt;// Example of initializing a Phaser game&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUTO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;game&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Toughest Asteroid Field: Mastering Phaser
&lt;/h2&gt;

&lt;p&gt;Learning Phaser while simultaneously developing a game was like navigating through an asteroid field at warp speed. The learning curve was steep, and at times, it felt like I was lost in space. However, as I progressed, things began to click into place. My code might have resembled spaghetti more than a neat star chart, but it got the job done.&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="c1"&gt;// Example of adding a sprite in Phaser&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCollideWorldBounds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Unexpected Nebulae: Fierce Competition
&lt;/h2&gt;

&lt;p&gt;The challenge lasted for 24 days, thought I embarked on my journey 5 days after the initial launch. Throughout this time, I approached the development of Cosmic Explorer with a relaxed attitude. I worked on it when I felt inspired and took breaks when I needed to. This approach kept the process enjoyable and prevented burnout.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Constellations: Learning and Growth
&lt;/h2&gt;

&lt;p&gt;Through this challenge, I discovered a new constellation in my programming toolkit - Phaser. Learning to use this library opened up a whole new galaxy of possibilities in game development that I hadn't explored before.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Winning Formula: Nostalgia and Smooth Gameplay
&lt;/h2&gt;

&lt;p&gt;I believe what set Cosmic Explorer apart was its blend of nostalgia-inducing pixel art (which my amazing girlfriend made all of, and sure made me win) and modern gameplay elements. The parallax star background created an immersive experience, while the movement system received praise from many players. The retro-inspired sound effects added another layer of charm that resonated with the judges and players alike.&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="c1"&gt;// Example of creating a parallax background&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bg1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tileSprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setOrigin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bg2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tileSprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setOrigin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bg1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tilePosition&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bg2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tilePosition&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// This was not my solution, but the same principle. Check out the GitHub repo for the solution :)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advice for Future Space Cadets
&lt;/h2&gt;

&lt;p&gt;For those looking to embark on similar coding odysseys, here's my advice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do it for fun, not as a job.&lt;/li&gt;
&lt;li&gt;Take breaks when you need them - the universe will still be there when you return.&lt;/li&gt;
&lt;li&gt;Embrace the learning experience.&lt;/li&gt;
&lt;li&gt;Don't be discouraged by fierce competition - use it as motivation.&lt;/li&gt;
&lt;li&gt;Remember, not winning doesn't mean your program isn't good. Every creation has value.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Winning the JSM Programming Challenge with Cosmic Explorer was an incredible journey through the vast expanse of game development. It taught me new skills, pushed my boundaries, and most importantly, reminded me of the joy of coding. Whether you're a seasoned space captain or a rookie cadet, I encourage you to take on similar challenges. You never know what new worlds you might discover.&lt;/p&gt;

&lt;p&gt;Happy coding, and may your compile times be short and your bugs few!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>javascript</category>
      <category>phaser</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Modern Web Development Frameworks: Comparing Popular Frameworks and Their Use Cases</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Thu, 19 Sep 2024 07:46:53 +0000</pubDate>
      <link>https://forem.com/pellenilsen/modern-web-development-frameworks-comparing-popular-frameworks-and-their-use-cases-3p60</link>
      <guid>https://forem.com/pellenilsen/modern-web-development-frameworks-comparing-popular-frameworks-and-their-use-cases-3p60</guid>
      <description>&lt;p&gt;In the rapidly evolving landscape of web development, choosing the right framework can significantly impact project success. This article delves into some of the most popular web development frameworks, comparing their strengths and ideal use cases to help developers make informed decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  React
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;React, developed and maintained by Facebook, is a JavaScript libriary for building user interfaces. It's known for its component-based architecture and virtual DOM for efficient rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Component-based architecture&lt;/li&gt;
&lt;li&gt;Virtual DOM&lt;/li&gt;
&lt;li&gt;JSX syntax&lt;/li&gt;
&lt;li&gt;Large ecosystem and community support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Single-page applications (SPAs)&lt;/li&gt;
&lt;li&gt;Large-scale web applications&lt;/li&gt;
&lt;li&gt;Projects requiring frequent UI updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vue.js
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Vue.js is a progressive JavaScript framework that's gained popularity due to its gentle learning curve and flexibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reactive data binding&lt;/li&gt;
&lt;li&gt;Component system&lt;/li&gt;
&lt;li&gt;Virtual DOM&lt;/li&gt;
&lt;li&gt;Lightweight and fast&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Small to medium-sized applications&lt;/li&gt;
&lt;li&gt;Projects requiring quick prototyping&lt;/li&gt;
&lt;li&gt;Applications with reactive interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Angular
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Angular, maintained by Google, is a comprehensive TypeScript-based framework known for its robustness and scalability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Two-way data binding&lt;/li&gt;
&lt;li&gt;Dependency injection&lt;/li&gt;
&lt;li&gt;TypeScript support&lt;/li&gt;
&lt;li&gt;Comprehensive tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Large-scale enterprise applications&lt;/li&gt;
&lt;li&gt;Complex single-page applications&lt;/li&gt;
&lt;li&gt;Projects requiring strong typing and scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next.js
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Next.js is a React-based framework that enables server-side rendering and static site generation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Server-side rendering&lt;/li&gt;
&lt;li&gt;Static site generation&lt;/li&gt;
&lt;li&gt;Automatic code splitting&lt;/li&gt;
&lt;li&gt;Built-in routing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;SEO-focused web applications&lt;/li&gt;
&lt;li&gt;E-commerce sites&lt;/li&gt;
&lt;li&gt;Content-heavy websites&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Svelte
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Svelte is a modern framework that compiles your code to vanilla JavaScript at build time, resulting in smaller bundle sizes and improved performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No virtual DOM&lt;/li&gt;
&lt;li&gt;True reactivity&lt;/li&gt;
&lt;li&gt;Less boilerplate code&lt;/li&gt;
&lt;li&gt;Built-in state management&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Performance-critical applications&lt;/li&gt;
&lt;li&gt;Small to medium-sized applications&lt;/li&gt;
&lt;li&gt;Applications with limited resources&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Choosing the right web development framework depends on various factors, including project requirements, team expertise and scalability needs. React and Vue.js offer flexibility and are great for a wide range of projects. Angular shines in large-scale enterprise applications. Next.js is ideas for SEO-focused and content-rich sites, while Svelte is perfect for performance-critical applications.&lt;/p&gt;

&lt;p&gt;Remember, the best framework is the one that aligns with your project goals and team capabilities. Keep exploring and experimenting to find the perfect fit for your next web development venture.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>performance</category>
    </item>
    <item>
      <title>Code Quality and Clean Code: Techniques for Maintainable, Readable and Efficient Code</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Wed, 18 Sep 2024 07:05:11 +0000</pubDate>
      <link>https://forem.com/pellenilsen/code-quality-and-clean-code-techniques-for-maintainable-readable-and-efficient-code-30oh</link>
      <guid>https://forem.com/pellenilsen/code-quality-and-clean-code-techniques-for-maintainable-readable-and-efficient-code-30oh</guid>
      <description>&lt;p&gt;In the ever-evolving landscape of software development, writing high-quality, clean code is a crucial skill that sets apart exceptional developers. Clean code not only enhances readability and maintainability but also contributes to the overall efficiency and longevity of a project. This article will delve into the techniques and best practices for crafting code that stands the test of time and collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Clean Code?
&lt;/h2&gt;

&lt;p&gt;Clean code refers to code that is easy to understand, modify and maintain. It's characterized by its simplicity, clarity and efficiency. The concept goes beyond just making code work; it's about making code that's easy for humans to read and reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Characteristics of Clean Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Readability
&lt;/h3&gt;

&lt;p&gt;Clean code should be easily readable by other developers (and your future self). It should tell a story and convey its purpose clearly.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Poor readability
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;

&lt;span class="c1"&gt;#  Good readability
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;second_number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;first_number&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;second_number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Simplicity
&lt;/h3&gt;

&lt;p&gt;Keep your code as simple as possible. Avoid unnecessary complexity and over-engineering.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Overly complex
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;TRUE&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="c1"&gt;# Simple and clean
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Modularity
&lt;/h3&gt;

&lt;p&gt;Break your code into smaller, reusable modules or functions. Each function should do one thing and do it well.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Poor modularity
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 100 lines of code doing multiple things
&lt;/span&gt;
&lt;span class="c1"&gt;# Good modularity
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Validation logic
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transform_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Transformation logic
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Saving logic
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;validate_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;transformed_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;transform_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;save_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Consistent Naming Conventions
&lt;/h3&gt;

&lt;p&gt;Use clear, consistent and meaningful names for variables, functions and classes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Poor naming
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="c1"&gt;# Good naming
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Proper Comments and Documentation
&lt;/h3&gt;

&lt;p&gt;Write self-documenting code, but use comments to explain complex logic or the "why" behind certain decisions.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Poor commenting
# This function does stuff
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Do things here
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Good commenting
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Processes the input data by validating, transforming and saving it.

    Args:
        data (dict): The input data to be processed.

    Returns:
        bool: True if processing was successful, False otherwise.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Implementation here
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Techniques for Writing Clean Code
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Follow the DRY (Don't Repeat Yourself) Principle: Avoid code duplication by extracting common functionality into reusable functions or classes.&lt;/li&gt;
&lt;li&gt;SOLID Principles: Apply SOLID principles (Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation and Dependency Inversion) to create more maintainable and flexible code.&lt;/li&gt;
&lt;li&gt;Use Version Control: Utilize Git or other version control systems to track changes and collaborate effectively.&lt;/li&gt;
&lt;li&gt;Implement Error Handling: Handle exceptions gracefully and provide meaningful error messages.&lt;/li&gt;
&lt;li&gt;Write Unit Tests: Create comprehensive unit tests to ensure your code works as expected and to catch regressions early.&lt;/li&gt;
&lt;li&gt;Code Reviews: Regularly participate in code reviews to get feedback and learn from others.&lt;/li&gt;
&lt;li&gt;Continuous Refactoring: Continuously improve your code by refactoring when you see opportunities for enhancement.&lt;/li&gt;
&lt;li&gt;Use Static Code Analysis Tools: Employ tools like linters to catch potential issues and enforce coding standards automamtically.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Benefits of Clean Code
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Improved Maintailability: Clean code is easier to maintain and update, reducing technical debt over time.&lt;/li&gt;
&lt;li&gt;Enhanced Collaboration: Well-structured code allows team members to understand and contribute to the project more effectively.&lt;/li&gt;
&lt;li&gt;Reduced Bugs: Clean code tends to have fewer bugs and its easier to debug when issues do arise.&lt;/li&gt;
&lt;li&gt;Faster Development: While it may take more time initially, clean code speeds up development in the long run by making it easier to add new features and make changes.&lt;/li&gt;
&lt;li&gt;Better Scalability: Clean, modular code is more scalable and adaptable to changing requirements.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Writing clean, high-quality code is an essential skill for any developer. It's not just about making your code work; it's about creating code that's easy to understand, maintain and extend. By following the techniques and best practices outlines in this article, you can significantly improve the quality of your code, leading to more successful and sustainable projects.&lt;/p&gt;

&lt;p&gt;Remember, clean code is a continuous practice, not a one-time effort. Always strive to leave the code better than you found it, and your future self (and your teammates) will thank you. Make sure to leave your questions in the comments! Happy coding!&lt;/p&gt;

</description>
      <category>code</category>
      <category>bestpratices</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Version Control Best Practices - Mastering Git, Branching Strategies and Collaborative Workflows</title>
      <dc:creator>Pelle Nilsen</dc:creator>
      <pubDate>Tue, 17 Sep 2024 08:00:30 +0000</pubDate>
      <link>https://forem.com/pellenilsen/version-control-best-practices-mastering-git-branching-strategies-and-collaborative-workflows-5gal</link>
      <guid>https://forem.com/pellenilsen/version-control-best-practices-mastering-git-branching-strategies-and-collaborative-workflows-5gal</guid>
      <description>&lt;p&gt;In the ever-evolving landscape of software development, version control has become an indispensable tool for managing code, collaborating with team members, and maintaining project history. Among the various version control systems available, Git stands out as the most widely adopted. This article will delve into version control best practices, focusing on Git usage, effective branching strategies and collaborative workflows that can elevate your development process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Version Control and Git
&lt;/h2&gt;

&lt;p&gt;Version control is a system that helps track changes to files over time, allowing developers to review history, revert to previous states and manage different versions of their codebase. Git, a distributed version control system, has become the de facto standard in the industry due to its flexibility, speed and powerful branching capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Commit Early and Often
&lt;/h3&gt;

&lt;p&gt;Make small, frequent commits rather than large, infrequent ones. This approach makes it easer to track changes, find bugs and revert is necessary.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Good practice&lt;/span&gt;
git commit -m &lt;span class="s2"&gt;"Add user registration form"&lt;/span&gt;
git commit -m &lt;span class="s2"&gt;"Implement form validation"&lt;/span&gt;

&lt;span class="c1"&gt;# Avoid&lt;/span&gt;
git commit -m &lt;span class="s2"&gt;"Add user registration form and implement validation"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Write Meaningful Commit Messages
&lt;/h3&gt;

&lt;p&gt;Your commit messages should clearly explain what changes were made and why. Follow a consistent format, such as the conventional commit format.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Good commit message&lt;/span&gt;
git commit -m &lt;span class="s2"&gt;"feat(auth): implement two-factor authentication"&lt;/span&gt;

&lt;span class="c1"&gt;# Avoid&lt;/span&gt;
git commit -m &lt;span class="s2"&gt;"Update auth"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use .gitignore
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.gitignore&lt;/code&gt; file to exclude unnecessary files (like build artifacts or dependencies) from version control.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gitignore&lt;/span&gt;
node_modules/
.env
*.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Regularly Pull and Push
&lt;/h3&gt;

&lt;p&gt;Keep your local repository up-to-date by pulling changes frequently, and push your commits reguarly to share your work with the team.&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tcl"&gt;&lt;code&gt;git pull origin main
&lt;span class="c1"&gt;# Make your changes&lt;/span&gt;
git push origin feature-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Effective Branching Strategies
&lt;/h2&gt;

&lt;p&gt;A well-planned branching strategy can significantly improve collaboration and code quality. Here are some popular branching models:&lt;/p&gt;

&lt;h3&gt;
  
  
  Git Flow
&lt;/h3&gt;

&lt;p&gt;Git Flow is a branching model that uses multiple branches to manage development, releases and hotfixes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt;: Represents the production-ready state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;developer&lt;/code&gt;: Integration branch for features&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;feature/*&lt;/code&gt;: For developing new features&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;release/*&lt;/code&gt;: For preparing releases&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hotfix/*&lt;/code&gt;: For critical bug fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  GitHub Flow
&lt;/h3&gt;

&lt;p&gt;A simpler alternative to Git Flow, suitable for teams practicing continuous delivery.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt;: Always deployable&lt;/li&gt;
&lt;li&gt;Feature Branches: Created from &lt;code&gt;main&lt;/code&gt;, merged back via pull requests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Trunk-Based Development
&lt;/h3&gt;

&lt;p&gt;A branching strategy that involves making small, frequent changes directly to the main branch.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt;: Primary branch where all development happens&lt;/li&gt;
&lt;li&gt;Short-lived feature branches when necessary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Collaborative Workflows
&lt;/h2&gt;

&lt;p&gt;Effective collaboration is key to successful development. Here are some best practices:&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Pull Requests
&lt;/h3&gt;

&lt;p&gt;Pull requests (PRs) facilitate code review and discussion before merging changes.&lt;/p&gt;

&lt;p&gt;Best practices for PRs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep them small and focused&lt;/li&gt;
&lt;li&gt;Provide a clear description of changes&lt;/li&gt;
&lt;li&gt;Link related issues or tickets&lt;/li&gt;
&lt;li&gt;Respond promptly to feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Reviews
&lt;/h3&gt;

&lt;p&gt;Implement a code review process to improve code quality and share knowledge.&lt;/p&gt;

&lt;p&gt;Tips for effective code reviews:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be constructive and respectful&lt;/li&gt;
&lt;li&gt;Focus on code, not the person&lt;/li&gt;
&lt;li&gt;Use automated tools to catch style issues&lt;/li&gt;
&lt;li&gt;Explain the "why" behind suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Continuous Integration (CI)
&lt;/h3&gt;

&lt;p&gt;Implement CI to automatically build and test your code with each commit or PR.&lt;/p&gt;

&lt;p&gt;Example CI workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer pushes code to a feature branch&lt;/li&gt;
&lt;li&gt;CI system builds the project&lt;/li&gt;
&lt;li&gt;Automated tests run&lt;/li&gt;
&lt;li&gt;Code quality checks performed&lt;/li&gt;
&lt;li&gt;Results reported back to the PR&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use Tags for Releases
&lt;/h3&gt;

&lt;p&gt;Tag important commits, especially for releases, to easily reference and deploy specific versions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tcl"&gt;&lt;code&gt;git tag -a v1.0.0 -m &lt;span class="s2"&gt;"Release version 1.0.0"&lt;/span&gt;
git push origin v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Mastering version control, particularly Git, is crucial for efficient and collaborative software development. By following these best practices for Git usage, implementing effective branching strategies and adopting collaborative workflows, you can significantly improve your team's productivity and code quality.&lt;/p&gt;

&lt;p&gt;Remember, the key to successful version control is consistency and communication. Establish clear guidelines for your team, and reguarly review and refine your processes. With these practices in place, you'll be well-equipped to handle the complexities of modern software development and deliver high-quality code efficiently.&lt;/p&gt;

&lt;p&gt;Happy coding and collaborating!&lt;/p&gt;

</description>
      <category>git</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
