<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kamran Khan</title>
    <description>The latest articles on DEV Community by Kamran Khan (@kamranxdev).</description>
    <link>https://dev.to/kamranxdev</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%2F898911%2Fec238396-ec9e-4f74-a1be-3e12f7047d4a.jpg</url>
      <title>DEV Community: Kamran Khan</title>
      <link>https://dev.to/kamranxdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kamranxdev"/>
    <language>en</language>
    <item>
      <title>From API Beginner to Architect: How to Design Scalable APIs (Without the Headache!)</title>
      <dc:creator>Kamran Khan</dc:creator>
      <pubDate>Sat, 20 Dec 2025 04:49:09 +0000</pubDate>
      <link>https://dev.to/kamranxdev/from-api-beginner-to-architect-how-to-design-scalable-apis-without-the-headache-4008</link>
      <guid>https://dev.to/kamranxdev/from-api-beginner-to-architect-how-to-design-scalable-apis-without-the-headache-4008</guid>
      <description>&lt;p&gt;So, you’ve mastered the &lt;a href="https://dev.to/kamranxdev/how-to-design-your-first-api-with-raml-without-losing-your-mind-4293"&gt;basics of API modeling&lt;/a&gt;. You know how to create resources like &lt;code&gt;/movies&lt;/code&gt; and add basic GET methods. But as your &lt;strong&gt;MovieHub&lt;/strong&gt; app grows—adding actors, directors, reviews, and video trailers—your API definition starts looking like a giant, messy ball of code. 😱&lt;/p&gt;

&lt;p&gt;Ready to stop "copy-pasting" and start designing like a pro? &lt;/p&gt;

&lt;p&gt;In this post, I’ll show you how to take a basic API design and refactor it into a clean, modular masterpiece using advanced RAML techniques. Let's dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Goal: The CineStream API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We are building a streaming platform API. It needs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Manage huge lists of Movies and Actors.&lt;/li&gt;
&lt;li&gt;  Filter movies by genre or release year.&lt;/li&gt;
&lt;li&gt;  Allow admins to upload movie posters (files).&lt;/li&gt;
&lt;li&gt;  Ensure every movie entry has a valid ID and Title.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1: Enforce Rules with Types (Schemas)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In a basic design, you just show a sample JSON. But what if a developer forgets the &lt;code&gt;releaseYear&lt;/code&gt;? &lt;strong&gt;Types&lt;/strong&gt; act as a contract: they define exactly what the data &lt;em&gt;must&lt;/em&gt; look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;types:
  Movie:
    properties:
      id: string
      title: string
      releaseYear: 
        type: integer
        minimum: 1888
      genre: string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Data Integrity:&lt;/strong&gt; It automatically rejects a movie if the &lt;code&gt;releaseYear&lt;/code&gt; is 1500 or if the &lt;code&gt;id&lt;/code&gt; is missing.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Consistency:&lt;/strong&gt; Use this &lt;code&gt;Movie&lt;/code&gt; type across your entire API.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2: Create Blueprints with Resource Types&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most APIs follow a pattern: a &lt;strong&gt;collection&lt;/strong&gt; (like &lt;code&gt;/movies&lt;/code&gt;) and an &lt;strong&gt;item&lt;/strong&gt; (like &lt;code&gt;/movies/{id}&lt;/code&gt;). Instead of typing out &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;post&lt;/code&gt; for every single category, we create a &lt;strong&gt;resourceType&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resourceTypes:
  collection:
    get:
      description: Get a list of &amp;lt;&amp;lt;resourcePathName&amp;gt;&amp;gt;
    post:
      description: Add a new &amp;lt;&amp;lt;resourcePathName | !singularize&amp;gt;&amp;gt;
      body:
        application/json:
          type: &amp;lt;&amp;lt;resourcePathName | !singularize&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Magic:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;&amp;lt;&amp;lt;resourcePathName&amp;gt;&amp;gt;&lt;/code&gt; automatically becomes "movies" or "actors" depending on the path.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;| !singularize&lt;/code&gt; is a built-in transformer that turns "movies" into "Movie" for your data type! &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3: Make Templates Dynamic with Parameters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes your blueprints need specific details, like a unique example for a Movie vs. an Actor. You can pass these as parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/movies:
  type:
    collection:
      exampleCollection: !include examples/movies-list.json
      exampleItem: !include examples/new-movie.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; You can now manage 50 different resources by editing just one &lt;code&gt;resourceType&lt;/code&gt; blueprint.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4: Tidy Up with !includes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Don't let your main API file become a 5,000-line monster. Use &lt;code&gt;!include&lt;/code&gt; to move long examples and schemas into their own files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/movies:
  type: collection
  get:
    responses:
      200:
        body:
          application/json:
            example: !include movies-display.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Your main file stays readable (the "blueprint"), while the data details stay in organized folders.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 5: Add "Plug-in" Features with Traits&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Need searching, sorting, or paging? These aren't resources; they are &lt;strong&gt;behaviors&lt;/strong&gt;. In RAML, we call these &lt;strong&gt;Traits&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;traits:
  searchable:
    queryParameters:
      query:
        description: Search the list by &amp;lt;&amp;lt;field&amp;gt;&amp;gt;
  pageable:
    queryParameters:
      limit: { type: integer, default: 20 }
      offset: { type: integer, default: 0 }

/movies:
  get:
    is: [ searchable: {field: "title"}, pageable ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; You can "plug" paging into &lt;code&gt;/movies&lt;/code&gt;, &lt;code&gt;/actors&lt;/code&gt;, and &lt;code&gt;/reviews&lt;/code&gt; instantly without writing the code three times.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 6: Handling File Uploads&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For a movie app, we need to upload posters. You can define specific body types for binary data (the image file) and form data at the same time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/movies/{movieId}/poster:
  post:
    body:
      image/jpeg:
      multipart/form-data:
        properties:
          file:
            type: file
            description: The movie poster image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Memory Hack: The S.R.I.T. Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To design like an architect, remember &lt;strong&gt;S.R.I.T.&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;S&lt;/strong&gt;chemas/Types (Define the rules)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;R&lt;/strong&gt;esource Types (The blueprints for your URLs)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;I&lt;/strong&gt;ncludes (Keep it tiny and tidy)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;T&lt;/strong&gt;raits (Plug-in behaviors like paging)&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;You’ve just leveled up from "API Writer" to &lt;strong&gt;API Architect&lt;/strong&gt;. By using these advanced features, your &lt;strong&gt;MovieHub&lt;/strong&gt; API is now scalable, professional, and—most importantly—easy to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s your biggest challenge when designing APIs? Let's chat in the comments!&lt;/strong&gt; 🚀&lt;/p&gt;




</description>
      <category>api</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Design Your First API with RAML (Without Losing Your Mind!)</title>
      <dc:creator>Kamran Khan</dc:creator>
      <pubDate>Fri, 19 Dec 2025 14:01:55 +0000</pubDate>
      <link>https://dev.to/kamranxdev/how-to-design-your-first-api-with-raml-without-losing-your-mind-4293</link>
      <guid>https://dev.to/kamranxdev/how-to-design-your-first-api-with-raml-without-losing-your-mind-4293</guid>
      <description>&lt;p&gt;Ever wondered how developers design APIs that look clean, work smoothly, and scale like magic?&lt;br&gt;&lt;br&gt;
In this post, I’ll show you how to use &lt;strong&gt;RAML (RESTful API Modeling Language)&lt;/strong&gt; to design a simple API for a MovieHub app.&lt;/p&gt;

&lt;p&gt;And the best part? You’ll learn the essentials in &lt;strong&gt;6 easy steps&lt;/strong&gt;—with examples that stick in your mind.&lt;br&gt;&lt;br&gt;
Ready? Let’s dive in!&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Why RAML?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;RAML helps you &lt;strong&gt;model RESTful APIs&lt;/strong&gt; in a structured, human-readable way.&lt;br&gt;&lt;br&gt;
Instead of messy docs and scattered notes, you get a &lt;strong&gt;single source of truth&lt;/strong&gt; for your API design.&lt;br&gt;&lt;br&gt;
Think of it as the blueprint before you start building the house.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1: Start with the Root&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every RAML file begins with a root section.&lt;br&gt;&lt;br&gt;
This is your &lt;strong&gt;foundation&lt;/strong&gt;—everything here applies globally.&lt;/p&gt;

&lt;p&gt;Here’s the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#%RAML 1.0
title: MovieHub API
baseUri: http://api.moviehub.com/{version}
version: v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;title&lt;/code&gt; → API name&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;baseUri&lt;/code&gt; → starting point for all calls&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;version&lt;/code&gt; → keeps things organized&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2: Add Resources&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Resources are &lt;strong&gt;collections&lt;/strong&gt; like &lt;code&gt;/movies&lt;/code&gt;, &lt;code&gt;/actors&lt;/code&gt;, &lt;code&gt;/directors&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Here’s how they look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/movies:
/actors:
/directors:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to get details of a specific actor? Use &lt;strong&gt;nested resources&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/actors/{actorName}:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3: Define Methods&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Methods tell your API what to do. The big four:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GET&lt;/strong&gt; → Fetch data&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;POST&lt;/strong&gt; → Add new data&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;PUT&lt;/strong&gt; → Update data&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;DELETE&lt;/strong&gt; → Remove data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example for &lt;code&gt;/books&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/movies:
 get:
 post:
 put:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4: URI Parameters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Need to fetch a specific book? Add a URI parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/movies/{movieTitle}:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example call:&lt;br&gt;&lt;br&gt;
&lt;code&gt;http://api.moviehub.com/v1/movies/Inception&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Step 5: Query Parameters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Want filtering? Use query parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/movies:
 get:
  queryParameters:
    genre:
    releaseYear:
    rating:
    director:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pro tip: Always document attributes like &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;example&lt;/code&gt;, and &lt;code&gt;required&lt;/code&gt;.&lt;br&gt;&lt;br&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;genre:
 displayName: Genre
 type: string
 example: Sci-Fi
 required: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Step 6: Responses&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Show what the API returns. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;responses:
  200:
    body:
      application/json:
        example:
          {
            "title": "Inception",
            "director": "Christopher Nolan",
            "rating": 8.8,
            "status": 200
          }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Memory Hack&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Think of the flow as:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Root → Resources → Methods → URI Params → Query Params → Responses&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
(R → R → M → U → Q → R)&lt;br&gt;&lt;br&gt;
Say it twice and you’ll never forget it.&lt;/p&gt;




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

&lt;p&gt;And that’s it! You’ve just built your first API spec in RAML.&lt;/p&gt;

&lt;p&gt;Ready to take it to the next level? 🚀&lt;br&gt;
Check out my follow-up post: &lt;a href="https://dev.to/kamranxdev/from-api-beginner-to-architect-how-to-design-scalable-apis-without-the-headache-4008"&gt;From API Beginner to Architect: How to Design Scalable APIs (Without the Headache!)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In that post, we’ll dive into the advanced features like Resource Types and Traits to help you stop copy-pasting and start designing like a pro.&lt;/p&gt;

&lt;p&gt;Give yourself a pat on the back—you’re officially an API designer now! 🎉&lt;/p&gt;




</description>
      <category>beginners</category>
      <category>design</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🔧 How to Auto-Mount Partitions Without Password in Fedora and Access Them in File Manager</title>
      <dc:creator>Kamran Khan</dc:creator>
      <pubDate>Sat, 19 Jul 2025 18:16:11 +0000</pubDate>
      <link>https://dev.to/kamranxdev/how-to-auto-mount-partitions-without-password-in-fedora-and-access-them-in-file-manager-31p0</link>
      <guid>https://dev.to/kamranxdev/how-to-auto-mount-partitions-without-password-in-fedora-and-access-them-in-file-manager-31p0</guid>
      <description>&lt;p&gt;On Fedora, accessing additional disk partitions (like a separate storage or workspace) often requires entering your password. This guide explains how to &lt;strong&gt;auto-mount partitions at boot without a password&lt;/strong&gt;, and have them &lt;strong&gt;appear in the GNOME Files app&lt;/strong&gt;, similar to how drives show in Windows.&lt;/p&gt;

&lt;p&gt;We’ll cover two methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mounting under &lt;code&gt;/mnt&lt;/code&gt; (clean layout, requires shortcut for GUI visibility)&lt;/li&gt;
&lt;li&gt;Mounting under &lt;code&gt;/media&lt;/code&gt; (auto-visible in GNOME Files sidebar)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧭 Step 1: Identify Your Partition
&lt;/h2&gt;

&lt;p&gt;In a terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsblk &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;blkid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for entries like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/dev/sdXn: LABEL="YourLabel" UUID="XXXX-XXXX" TYPE="ext4"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take note of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UUID&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LABEL&lt;/code&gt; (optional)&lt;/li&gt;
&lt;li&gt;Filesystem type (e.g. &lt;code&gt;ext4&lt;/code&gt;, &lt;code&gt;ntfs&lt;/code&gt;, &lt;code&gt;btrfs&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Step 2: Choose Your Mount Method
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Option 1: Mount Under &lt;code&gt;/mnt&lt;/code&gt; (Clean System Layout)
&lt;/h3&gt;

&lt;p&gt;This method is clean and system-friendly but requires a shortcut to access from the GUI.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create Mount Point
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/YourMountPoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;YourMountPoint&lt;/code&gt; with a name like &lt;code&gt;workspace&lt;/code&gt; or &lt;code&gt;storage&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Edit &lt;code&gt;/etc/fstab&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Open the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/fstab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a line like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UUID=XXXX-XXXX  /mnt/YourMountPoint  ext4  defaults  0  2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;UUID=XXXX-XXXX&lt;/code&gt; with your actual UUID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ext4&lt;/code&gt; with your actual filesystem type&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;YourMountPoint&lt;/code&gt; with your chosen name&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Mount Immediately
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Add GUI Shortcut (Optional)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /mnt/YourMountPoint ~/YourMountPoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a visible folder shortcut in your home directory.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Option 2: Mount Under &lt;code&gt;/media&lt;/code&gt; (Visible in GNOME Files Sidebar)
&lt;/h3&gt;

&lt;p&gt;This method makes partitions show up automatically in the Files app.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create Mount Point
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /media/YourMountPoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Edit &lt;code&gt;/etc/fstab&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/fstab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a line like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UUID=XXXX-XXXX  /media/YourMountPoint  ext4  defaults  0  2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Mount:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open Files app — you’ll now see the partition in the left sidebar.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔑 Step 3: Set Permissions (Optional)
&lt;/h2&gt;

&lt;p&gt;To ensure you have read/write access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt;:&lt;span class="nv"&gt;$USER&lt;/span&gt; /mnt/YourMountPoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or if using &lt;code&gt;/media&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt;:&lt;span class="nv"&gt;$USER&lt;/span&gt; /media/YourMountPoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✨ Optional: Change Partition Label
&lt;/h2&gt;

&lt;p&gt;To customize the name that appears in the GUI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;e2label /dev/sdXn NewLabel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;sdXn&lt;/code&gt; with your device (like &lt;code&gt;sda3&lt;/code&gt;) and &lt;code&gt;NewLabel&lt;/code&gt; with your desired label.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧹 To Undo or Remove
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Delete or comment the corresponding line in &lt;code&gt;/etc/fstab&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Unmount the partition:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;umount /mnt/YourMountPoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remove mount point or symlink as needed&lt;/li&gt;
&lt;/ul&gt;




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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;/mnt&lt;/code&gt; Method&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;/media&lt;/code&gt; Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Auto-mount on boot&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;GUI (Files) visibility&lt;/td&gt;
&lt;td&gt;❌ Needs symlink&lt;/td&gt;
&lt;td&gt;✅ Sidebar visibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password prompt&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use case&lt;/td&gt;
&lt;td&gt;Clean setup, scripting&lt;/td&gt;
&lt;td&gt;Windows-style file access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  💡 Pro Tip
&lt;/h2&gt;

&lt;p&gt;Always back up your &lt;code&gt;/etc/fstab&lt;/code&gt; before editing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /etc/fstab /etc/fstab.bak
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>😴 Get Deeper Sleep on Fedora: Optimizing Suspend-to-RAM</title>
      <dc:creator>Kamran Khan</dc:creator>
      <pubDate>Wed, 16 Jul 2025 11:11:07 +0000</pubDate>
      <link>https://dev.to/kamranxdev/get-deeper-sleep-on-fedora-optimizing-suspend-to-ram-41bo</link>
      <guid>https://dev.to/kamranxdev/get-deeper-sleep-on-fedora-optimizing-suspend-to-ram-41bo</guid>
      <description>&lt;p&gt;If you're running &lt;strong&gt;Fedora&lt;/strong&gt; on a laptop or desktop, you might have noticed your system defaulting to a lighter sleep state (&lt;code&gt;s2idle&lt;/code&gt;) instead of the power-saving &lt;strong&gt;"deep sleep" (S3 Suspend-to-RAM)&lt;/strong&gt;. This can lead to faster battery drain and more warmth when suspended.&lt;/p&gt;

&lt;p&gt;In this guide, you'll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Verify if your system supports "deep" suspend&lt;/li&gt;
&lt;li&gt;⚙️ Configure Fedora to use "deep" suspend by default&lt;/li&gt;
&lt;li&gt;🛠️ Add NVIDIA suspend/resume fix (optional)&lt;/li&gt;
&lt;li&gt;🛠️ Apply MSI/ASUS-specific ACPI tweak (optional)&lt;/li&gt;
&lt;li&gt;🔍 Understand the difference between sleep states&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 What is "Deep Sleep" (S3 Suspend)?
&lt;/h2&gt;

&lt;p&gt;In the world of ACPI (Advanced Configuration and Power Interface), "deep sleep" typically refers to the &lt;strong&gt;S3 suspend state (Suspend-to-RAM)&lt;/strong&gt;. In this state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CPU, chipset, and most other components are powered down.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;RAM (Random Access Memory)&lt;/strong&gt; remains powered to retain your session data.&lt;/li&gt;
&lt;li&gt;The system consumes minimal power, making it ideal for battery life.&lt;/li&gt;
&lt;li&gt;Resuming from S3 is fast, usually taking only a few seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fedora, by default, often uses &lt;code&gt;s2idle&lt;/code&gt; (Suspend-to-Idle), which keeps more components powered on, consuming more energy, especially in modern hardware. While it's slightly faster to resume, S3 offers better power savings for true "deep sleep."&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Step 1: Verify "Deep Sleep" Support
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /sys/power/mem_sleep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;deep&lt;/code&gt; is present, your system supports S3 suspend.&lt;/li&gt;
&lt;li&gt;If it’s missing, check your BIOS/UEFI for power settings (sometimes called &lt;em&gt;ACPI S3&lt;/em&gt; or &lt;em&gt;Legacy Sleep&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Step 2: Configure Fedora for "Deep Sleep"
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Edit the sleep config:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/sleep.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add the lines:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;   &lt;span class="nn"&gt;[Sleep]&lt;/span&gt;
   &lt;span class="py"&gt;SuspendState&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;mem&lt;/span&gt;
   &lt;span class="py"&gt;MemorySleepMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;deep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Save &amp;amp; exit&lt;/strong&gt;, then reboot:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, suspend should now default to &lt;strong&gt;deep sleep (S3)&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🟢 Step 3 (Optional, NVIDIA users): Add GPU Resume Fix
&lt;/h2&gt;

&lt;p&gt;On systems with NVIDIA GPUs, you may experience &lt;strong&gt;black screens after resume&lt;/strong&gt;. NVIDIA provides a kernel option to preserve VRAM allocations across suspend.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open GRUB config:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/default/grub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Find the line starting with &lt;code&gt;GRUB_CMDLINE_LINUX=&lt;/code&gt; and add this at the end (inside the quotes):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   nvidia.NVreg_PreserveVideoMemoryAllocations=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;   GRUB_CMDLINE_LINUX="rhgb quiet mem_sleep_default=deep nvidia.NVreg_PreserveVideoMemoryAllocations=1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Rebuild GRUB and reboot:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;grub2-mkconfig &lt;span class="nt"&gt;-o&lt;/span&gt; /boot/grub2/grub.cfg
   &lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps the NVIDIA driver restore graphics properly after suspend.&lt;/p&gt;




&lt;h2&gt;
  
  
  🟠 Step 4 (Optional, MSI/ASUS laptops): ACPI Compatibility Tweak
&lt;/h2&gt;

&lt;p&gt;Some MSI and ASUS laptops expose &lt;strong&gt;different suspend/resume behaviors&lt;/strong&gt; depending on which OS they think is running. By default, Linux identifies itself as “Linux”, which may not unlock all ACPI features.&lt;/p&gt;

&lt;p&gt;You can trick the firmware into using the same code paths as Windows 10/11 by adding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;acpi_osi=! acpi_osi="Windows 2020"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to your kernel command line.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open GRUB config:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/default/grub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update &lt;code&gt;GRUB_CMDLINE_LINUX&lt;/code&gt;, for example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   GRUB_CMDLINE_LINUX="rhgb quiet mem_sleep_default=deep nvidia.NVreg_PreserveVideoMemoryAllocations=1 acpi_osi=! acpi_osi=\"Windows 2020\""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Rebuild GRUB and reboot:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;grub2-mkconfig &lt;span class="nt"&gt;-o&lt;/span&gt; /boot/efi/EFI/fedora/grub.cfg
   &lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Note:&lt;br&gt;
This tweak is &lt;strong&gt;most useful on MSI and ASUS laptops&lt;/strong&gt; that have issues resuming from suspend. If it causes problems (rare), just remove it again.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔒 Understanding Sleep States (Briefly)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S0 (Working):&lt;/strong&gt; Fully on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S0ix (Modern Standby / s2idle):&lt;/strong&gt; Low-power idle; fast resume but higher drain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3 (Suspend-to-RAM):&lt;/strong&gt; Only RAM stays powered; lowest power, fast resume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S4 (Hibernate):&lt;/strong&gt; Saves memory to disk; no power use, slower resume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S5 (Soft Off):&lt;/strong&gt; Full shutdown.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📌 TL;DR Cheatsheet
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Check deep sleep support&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /sys/power/mem_sleep&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shows if &lt;code&gt;deep&lt;/code&gt; is available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configure deep sleep&lt;/td&gt;
&lt;td&gt;Edit &lt;code&gt;/etc/systemd/sleep.conf&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Sets S3 as the default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA resume fix&lt;/td&gt;
&lt;td&gt;Add &lt;code&gt;nvidia.NVreg_PreserveVideoMemoryAllocations=1&lt;/code&gt; in GRUB&lt;/td&gt;
&lt;td&gt;Prevents black screen after resume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MSI/ASUS ACPI tweak&lt;/td&gt;
&lt;td&gt;Add &lt;code&gt;acpi_osi=! acpi_osi="Windows 2020"&lt;/code&gt; in GRUB&lt;/td&gt;
&lt;td&gt;Improves suspend/resume on some laptops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo reboot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reboot to apply settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test suspend&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl suspend&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Puts the system into configured suspend state&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🚀 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;By enabling &lt;strong&gt;deep sleep&lt;/strong&gt;, you ensure your Fedora system consumes less power when suspended. If you’re on NVIDIA hardware, the extra kernel option makes suspend/resume more reliable. On MSI/ASUS laptops, the &lt;code&gt;acpi_osi="Windows 2020"&lt;/code&gt; tweak can further stabilize wake-up.&lt;/p&gt;

&lt;p&gt;Together, these tweaks give you cooler standby, longer battery life, and a more stable wake-up experience.&lt;/p&gt;

</description>
      <category>linux</category>
    </item>
    <item>
      <title>⚙️ Dual GPU Setup on Fedora: NVIDIA + Intel (Optimus) with Offloading</title>
      <dc:creator>Kamran Khan</dc:creator>
      <pubDate>Wed, 16 Jul 2025 01:17:47 +0000</pubDate>
      <link>https://dev.to/kamranxdev/dual-gpu-setup-on-fedora-nvidia-intel-optimus-with-offloading-2o06</link>
      <guid>https://dev.to/kamranxdev/dual-gpu-setup-on-fedora-nvidia-intel-optimus-with-offloading-2o06</guid>
      <description>&lt;p&gt;If you're running &lt;strong&gt;Fedora&lt;/strong&gt; on a laptop with &lt;strong&gt;NVIDIA + Intel hybrid graphics&lt;/strong&gt; (like most modern laptops with Optimus), you're in luck — Fedora makes it easy to use &lt;strong&gt;GPU offloading&lt;/strong&gt;, giving you the best of both worlds: &lt;strong&gt;power efficiency&lt;/strong&gt; with Intel and &lt;strong&gt;performance&lt;/strong&gt; with NVIDIA when needed.&lt;/p&gt;

&lt;p&gt;In this guide, you'll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Install NVIDIA drivers with offloading support on Fedora&lt;/li&gt;
&lt;li&gt;⚙️ Run any app using the NVIDIA GPU on demand&lt;/li&gt;
&lt;li&gt;🛠️ Create a helper script and launcher to make offloading seamless&lt;/li&gt;
&lt;li&gt;🔁 (Optional) Switch to full-time NVIDIA mode for gaming laptops&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 What is NVIDIA Offloading?
&lt;/h2&gt;

&lt;p&gt;NVIDIA Offloading allows you to use the &lt;strong&gt;Intel GPU as the default&lt;/strong&gt; (great for battery life), but launch specific apps — like &lt;strong&gt;Steam, Blender, or Firefox&lt;/strong&gt; — on the &lt;strong&gt;NVIDIA GPU&lt;/strong&gt; for better performance.&lt;/p&gt;

&lt;p&gt;Unlike Windows' automatic switching with Optimus, Linux uses explicit offloading — but it’s easy and powerful when configured right.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Step 1: Enable RPM Fusion
&lt;/h2&gt;

&lt;p&gt;First, enable RPM Fusion repositories (Free + Non-Free) to get access to proprietary NVIDIA drivers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-&lt;span class="si"&gt;$(&lt;/span&gt;rpm &lt;span class="nt"&gt;-E&lt;/span&gt; %fedora&lt;span class="si"&gt;)&lt;/span&gt;.noarch.rpm &lt;span class="se"&gt;\&lt;/span&gt;
  https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-&lt;span class="si"&gt;$(&lt;/span&gt;rpm &lt;span class="nt"&gt;-E&lt;/span&gt; %fedora&lt;span class="si"&gt;)&lt;/span&gt;.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Step 2: Install NVIDIA Drivers with Optimus Support
&lt;/h2&gt;

&lt;p&gt;Update your system and install the required NVIDIA driver packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf update &lt;span class="nt"&gt;--refresh&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;akmod-nvidia xorg-x11-drv-nvidia-cuda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need 32-bit support (for Steam, Wine, etc.):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;xorg-x11-drv-nvidia-libs.i686
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Step 3: Verify Intel is the Default GPU
&lt;/h2&gt;

&lt;p&gt;Fedora (with X11) uses Intel as the default renderer automatically.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;glxinfo | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OpenGL renderer"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenGL renderer string: Mesa Intel(R) UHD Graphics ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Step 4: Run Apps with NVIDIA Offloading
&lt;/h2&gt;

&lt;p&gt;You can offload any app to the NVIDIA GPU using this command format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;__NV_PRIME_RENDER_OFFLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;__GLX_VENDOR_LIBRARY_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nvidia &amp;lt;your-app&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;__NV_PRIME_RENDER_OFFLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;__GLX_VENDOR_LIBRARY_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nvidia firefox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;glxinfo | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OpenGL renderer"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should now say something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenGL renderer string: NVIDIA GeForce RTX 3050 ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Step 5: Confirm with &lt;code&gt;nvidia-smi&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Want to make sure the NVIDIA GPU is active?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see the process listed if it’s using the GPU.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 Bonus: Make It Seamless with a Helper Script
&lt;/h2&gt;

&lt;p&gt;Let’s make offloading as easy as typing &lt;code&gt;nvidia-run &amp;lt;app&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Create the Script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.local/bin
nano ~/.local/bin/nvidia-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;__NV_PRIME_RENDER_OFFLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;__GLX_VENDOR_LIBRARY_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nvidia &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make it executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ~/.local/bin/nvidia-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to PATH (if not already):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export PATH="$HOME/.local/bin:$PATH"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔹 Use It Like This:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvidia-run blender
nvidia-run code
nvidia-run steam
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🖥️ Optional: Create App Launchers
&lt;/h2&gt;

&lt;p&gt;Want to launch apps from GNOME or KDE menu using NVIDIA?&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;.desktop&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Desktop Entry]&lt;/span&gt;
&lt;span class="py"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Blender (NVIDIA)&lt;/span&gt;
&lt;span class="py"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;nvidia-run blender&lt;/span&gt;
&lt;span class="py"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Application&lt;/span&gt;
&lt;span class="py"&gt;Categories&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Graphics;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save it to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/.local/share/applications/blender-nvidia.desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will now appear in your app launcher.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔒 Secure Boot Note
&lt;/h2&gt;

&lt;p&gt;NVIDIA kernel modules are unsigned, so Secure Boot will &lt;strong&gt;block them&lt;/strong&gt; by default.&lt;/p&gt;

&lt;p&gt;You can either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disable Secure Boot&lt;/strong&gt; in your BIOS, &lt;strong&gt;or&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;MOK (Machine Owner Key)&lt;/strong&gt; to sign and enroll the NVIDIA module (more complex).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔋 Want Full-Time NVIDIA Mode?
&lt;/h2&gt;

&lt;p&gt;You &lt;em&gt;can&lt;/em&gt; switch your system to always use NVIDIA for everything (great for gaming, not so much for battery life), but it requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting NVIDIA as the primary GPU&lt;/li&gt;
&lt;li&gt;Using Xorg configs or kernel parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know in the comments if you want a full guide on that!&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 TL;DR Cheatsheet
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command Example&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Run app on NVIDIA GPU&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nvidia-run &amp;lt;app&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Offloads app to NVIDIA GPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check GPU used&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;glxinfo &amp;gt; temp &amp;amp;&amp;amp; grep "OpenGL renderer" temp&lt;/code&gt; &lt;br&gt;or &lt;code&gt;nvidia-smi&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Shows whether Intel or NVIDIA is being used&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confirm Intel is default&lt;/td&gt;
&lt;td&gt;&lt;code&gt;glxinfo &amp;gt; temp &amp;amp;&amp;amp; grep "OpenGL renderer" temp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Should show "Mesa Intel..." as the renderer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create launcher&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.desktop&lt;/code&gt; file with &lt;code&gt;Exec=nvidia-run your-app&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Launch app with NVIDIA from desktop environment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🚀 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Fedora makes hybrid GPU support smooth and developer-friendly. With just a few commands and a tiny helper script, you can run games, Blender, Steam, or CUDA tools using the power of NVIDIA — while keeping Intel as the default for efficiency.&lt;/p&gt;

&lt;p&gt;Have questions or want help creating &lt;code&gt;.desktop&lt;/code&gt; entries for your apps? Drop a comment!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>nvidia</category>
      <category>fedora</category>
    </item>
    <item>
      <title>How to create a responsive image gallery without using media queries</title>
      <dc:creator>Kamran Khan</dc:creator>
      <pubDate>Fri, 28 Oct 2022 19:23:38 +0000</pubDate>
      <link>https://dev.to/kamranxdev/how-to-create-a-responsive-image-gallery-without-using-media-queries-3lgd</link>
      <guid>https://dev.to/kamranxdev/how-to-create-a-responsive-image-gallery-without-using-media-queries-3lgd</guid>
      <description>&lt;p&gt;In this article I'll teach you how to use CSS Grid to create a super cool image grid, which varies the amount of columns with the width of the screen.&lt;br&gt;
And the most beautiful part: the responsiveness will be added with a single line of CSS.&lt;br&gt;
This means we don't have to clutter up the HTML with ugly class names (i.e. &lt;code&gt;col-sm-4&lt;/code&gt;, &lt;code&gt;col-md-8&lt;/code&gt;) Or create media queries for every single screen size.&lt;br&gt;
Now let's jump into it!&lt;/p&gt;
&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;For this article, we'll add the images at the end of the article. Here's how our initial grid looks:&lt;/p&gt;

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

&lt;p&gt;Here's the HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="container"&amp;gt;
  &amp;lt;div&amp;gt;1&amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;2&amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;3&amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;4&amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;5&amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;6&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 50px 50px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: the example also has a little bit of basic styling, which I won't go into here, as it's got nothing to do with CSS Grid.&lt;br&gt;
Let's start by making the columns responsive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Basic responsiveness with the fraction unit
&lt;/h2&gt;

&lt;p&gt;CSS Grid brings with it a whole new value called a fraction unit. The fraction unit is written like &lt;code&gt;fr&lt;/code&gt;, and it allows you to split the container into as many fractions as you want.&lt;br&gt;
Let's change each of the columns to be one fraction unit wide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 50px 50px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens here is that the grid splits the entire width into three fractions and each of the columns take up one unit each. Here is the result:&lt;/p&gt;

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

&lt;p&gt;If we change the grid-template-columns value to1fr &lt;code&gt;2fr&lt;/code&gt; &lt;code&gt;1fr&lt;/code&gt;, the second column will now be twice as wide as the two other columns. The total width is now four fraction units, and the second one takes up two of them, while the others take up one each. Here's how that looks:&lt;/p&gt;

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

&lt;p&gt;In other words, the fraction unit value makes it super easy for you to change the width of the columns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced responsiveness
&lt;/h2&gt;

&lt;p&gt;However, the example above doesn't give us the responsiveness we want, as this grid will always be three columns wide. We want our grid to vary the amount of columns with the width of the container. To achieve that, you'll have to learn three new concepts.&lt;/p&gt;

&lt;h3&gt;
  
  
  repeat()
&lt;/h3&gt;

&lt;p&gt;We'll start with the &lt;code&gt;repeat()&lt;/code&gt; function. This is a more powerful way of specifying your columns and rows. Let's take our original grid and change it to using &lt;code&gt;repeat()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container {
    display: grid;
    grid-template-columns: repeat(3, 100px);
    grid-template-rows: repeat(2, 50px);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, &lt;code&gt;repeat(3, 100px)&lt;/code&gt; is identical to &lt;code&gt;100px 100px 100px&lt;/code&gt;. The first parameter specified how many columns or rows you want, and the second specifies their width, so this will just give us the exact same layout as we started out with:&lt;/p&gt;

&lt;h3&gt;
  
  
  auto-fit
&lt;/h3&gt;

&lt;p&gt;Then there's &lt;code&gt;auto-fit&lt;/code&gt;. Let's skip having a fixed amount of columns, and rather replace 3 with auto-fit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container {
    display: grid;
    grid-gap: 5px;
    grid-template-columns: repeat(auto-fit, 100px);
    grid-template-rows: repeat(2, 100px);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This results in the following behaviour:&lt;/p&gt;

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

&lt;p&gt;The grid now varies the amount of columns with the width of the container.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It simply tries to fit as many &lt;code&gt;100px&lt;/code&gt; wide columns into the container as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, if we hard code all columns to be exactly &lt;code&gt;100px&lt;/code&gt;, we'll never get the flexibility we want, as they'll rarely add up to the full width. As you can see on the gif above, the grid often leaves white space on the right hand side.&lt;/p&gt;

&lt;h3&gt;
  
  
  minmax()
&lt;/h3&gt;

&lt;p&gt;The final ingredient we need in order to fix this is called minmax(). We'll simply replace &lt;code&gt;100px&lt;/code&gt; with &lt;code&gt;minmax(100px, 1fr)&lt;/code&gt;. Here's the final CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container {
    display: grid;
    grid-gap: 5px;
    grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
    grid-template-rows: repeat(2, 100px);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that all the responsiveness happens in a single line of CSS.&lt;br&gt;
This results in the following behavior:&lt;/p&gt;

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

&lt;p&gt;And as you can see that works perfectly. The &lt;code&gt;minmax()&lt;/code&gt; function defines a size range greater than or equal to min and less than or equal to max.&lt;br&gt;
So the columns will now always be at least 100px. However if there are more available space, the grid will simply distribute this equally to each of the columns, as the columns turn into a fraction unit instead of &lt;code&gt;100 px&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding the images
&lt;/h2&gt;

&lt;p&gt;Now the final step is to add the images. This has nothing to do with CSS Grid, but let's still look at the code.&lt;br&gt;
We'll start off by adding an image tag inside of each of the grid items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;img src="img/forest.jpg"/&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make the image fit into the item, we'll set the it to be as wide and tall as the item itself, and then use &lt;code&gt;object-fit: cover;&lt;/code&gt;. This will make the image cover its entire container, and the browser will crop it if it's needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container &amp;gt; div &amp;gt; img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which ends up like the following:&lt;/p&gt;

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

&lt;p&gt;And that's it! You now know one of the most complex concepts in CSS Grid, so give yourself a pat on the back.&lt;br&gt;
Thanks for reading! My name is Kamran Khan. Follow me on Twitter and Instagram if you want to keep in touch.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
