<?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: javascript</title>
    <description>The latest articles tagged 'javascript' on DEV Community.</description>
    <link>https://dev.to/t/javascript</link>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tag/javascript"/>
    <language>en</language>
    <item>
      <title>Beginner's Guide to Docker: From Zero to Hero</title>
      <dc:creator>Yogesh Chavan</dc:creator>
      <pubDate>Sat, 16 May 2026 06:49:38 +0000</pubDate>
      <link>https://dev.to/myogeshchavan97/beginners-guide-to-docker-from-zero-to-hero-4977</link>
      <guid>https://dev.to/myogeshchavan97/beginners-guide-to-docker-from-zero-to-hero-4977</guid>
      <description>&lt;p&gt;Docker has fundamentally changed how developers build, ship, and run software. If you've ever heard "it works on my machine" — Docker is the fix. This guide walks you through everything you need to get started, from core concepts to writing your first Dockerfile and managing multi-container apps.&lt;/p&gt;




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

&lt;p&gt;Docker is an open-source platform that packages applications inside lightweight, isolated environments called &lt;strong&gt;containers&lt;/strong&gt;. A container bundles your code, runtime, system libraries, and configuration into a single portable unit, so an app that runs on your laptop runs identically on a colleague's machine or a production cloud server.&lt;/p&gt;

&lt;p&gt;Released in 2013, Docker builds on long-standing Linux kernel features (namespaces and cgroups) but wraps them in a developer-friendly CLI, a public image registry (Docker Hub), and a declarative file format for building images.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Docker?
&lt;/h3&gt;

&lt;p&gt;Before Docker, deploying apps meant carefully matching server environments, language runtimes, and OS patches. A single mismatch could break production. Docker solves this and brings several other benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt; — the same image runs identically on every machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt; — containers start in seconds and use far fewer resources than VMs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt; — each container has its own filesystem, processes, and network stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducibility&lt;/strong&gt; — a Dockerfile is a recipe; anyone can rebuild the exact same image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microservices-friendly&lt;/strong&gt; — small, single-purpose containers compose into larger systems easily&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Massive ecosystem&lt;/strong&gt; — Docker Hub hosts hundreds of thousands of ready-to-use images&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Containers vs. Virtual Machines
&lt;/h3&gt;

&lt;p&gt;Both containers and VMs provide isolation, but they work very differently. A VM includes a full guest OS on top of a hypervisor, while a container shares the host kernel and isolates only the application and its dependencies.&lt;/p&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;Virtual Machine&lt;/th&gt;
&lt;th&gt;Docker Container&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Boot time&lt;/td&gt;
&lt;td&gt;Minutes&lt;/td&gt;
&lt;td&gt;Seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size on disk&lt;/td&gt;
&lt;td&gt;Gigabytes&lt;/td&gt;
&lt;td&gt;Megabytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS overhead&lt;/td&gt;
&lt;td&gt;Full guest OS&lt;/td&gt;
&lt;td&gt;Shares host kernel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation level&lt;/td&gt;
&lt;td&gt;Hardware-level&lt;/td&gt;
&lt;td&gt;Process-level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Lower (virtualized)&lt;/td&gt;
&lt;td&gt;Near-native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portability&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Containers don't replace VMs in every situation. VMs are still preferable when you need a completely different OS or strict hardware-level isolation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Core Docker Concepts
&lt;/h2&gt;

&lt;p&gt;Five terms come up constantly. Understand these and everything else makes sense.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt; — a read-only template containing your app and its dependencies. Think of it like a class in OOP — a blueprint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container&lt;/strong&gt; — a running instance of an image. You can run many containers from one image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dockerfile&lt;/strong&gt; — a text file with step-by-step instructions for building an image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registry&lt;/strong&gt; — a server that stores and distributes images. Docker Hub is the default public registry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volume&lt;/strong&gt; — a mechanism for persisting data outside a container's lifecycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Docker Works
&lt;/h3&gt;

&lt;p&gt;Docker uses a client-server architecture. When you run &lt;code&gt;docker run nginx&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Docker CLI sends your command to the Docker Daemon (&lt;code&gt;dockerd&lt;/code&gt;) over a REST API.&lt;/li&gt;
&lt;li&gt;The daemon checks if the image exists locally; if not, it pulls it from Docker Hub.&lt;/li&gt;
&lt;li&gt;The daemon creates a container, allocates a writable filesystem layer, attaches networking, and starts the process.&lt;/li&gt;
&lt;li&gt;Output streams back to your terminal.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;On Linux, the daemon talks directly to the kernel. On macOS and Windows, Docker Desktop runs a small Linux VM under the hood — but you barely notice.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Installing Docker
&lt;/h2&gt;

&lt;h3&gt;
  
  
  macOS and Windows
&lt;/h3&gt;

&lt;p&gt;Install &lt;a href="https://www.docker.com/products/docker-desktop" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; — an all-in-one bundle that includes the daemon, CLI, Docker Compose, and a GUI for managing images and containers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux (Ubuntu/Debian)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Update package index&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update

&lt;span class="c"&gt;# Install prerequisites&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;ca-certificates curl gnupg

&lt;span class="c"&gt;# Add Docker's official GPG key&lt;/span&gt;
&lt;span class="nb"&gt;sudo install&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 0755 &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/apt/keyrings
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /etc/apt/keyrings/docker.gpg

&lt;span class="c"&gt;# Add the Docker repository&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
https://download.docker.com/linux/ubuntu jammy stable"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list

&lt;span class="c"&gt;# Install Docker Engine&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; After installation on Linux, add your user to the &lt;code&gt;docker&lt;/code&gt; group so you don't need &lt;code&gt;sudo&lt;/code&gt; for every command: &lt;code&gt;sudo usermod -aG docker $USER&lt;/code&gt;, then log out and back in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Verifying the Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# Output: Docker version 25.0.0, build ...&lt;/span&gt;

docker info

&lt;span class="c"&gt;# Run the official hello-world image&lt;/span&gt;
docker run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;hello-world&lt;/code&gt; image is tiny (a few kilobytes) and prints a friendly message confirming that the daemon, CLI, image pulling, and container execution all work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running Your First Container
&lt;/h3&gt;

&lt;p&gt;Let's run something more interesting — an Nginx web server — in a single command:&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;# Run nginx in the background and map port 8080 -&amp;gt; 80&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt; my-nginx nginx

&lt;span class="c"&gt;# Open http://localhost:8080 in your browser&lt;/span&gt;
&lt;span class="c"&gt;# When done, clean up&lt;/span&gt;
docker stop my-nginx
docker &lt;span class="nb"&gt;rm &lt;/span&gt;my-nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking down that command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker run&lt;/code&gt; — create and start a new container from an image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; — detached mode; run in the background&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p 8080:80&lt;/code&gt; — publish container port 80 to host port 8080&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--name my-nginx&lt;/code&gt; — give the container a friendly name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nginx&lt;/code&gt; — the image to run&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Best Practice:&lt;/strong&gt; Always give containers explicit names with &lt;code&gt;--name&lt;/code&gt;. Without it, Docker assigns a random name like &lt;code&gt;elated_einstein&lt;/code&gt;, making them harder to manage in scripts.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Docker Images
&lt;/h2&gt;

&lt;p&gt;A Docker image is a read-only, layered filesystem snapshot containing everything needed to run your software: the OS base, language runtime, application code, dependencies, and metadata.&lt;/p&gt;

&lt;p&gt;Images are identified by &lt;code&gt;name:tag&lt;/code&gt; — for example, &lt;code&gt;node:20-alpine&lt;/code&gt; refers to Node.js v20 built on Alpine Linux. If you omit the tag, Docker assumes &lt;code&gt;:latest&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pulling Images from Docker Hub
&lt;/h3&gt;

&lt;p&gt;Docker Hub is the world's largest public registry of container images. You can pull any public image with a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull nginx
docker pull nginx:1.25-alpine
docker pull node:20-alpine
docker pull postgres:16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Tags like &lt;code&gt;alpine&lt;/code&gt; mean the image is built on Alpine Linux, which is often under 10 MB. Prefer Alpine variants when image size matters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Listing and Removing Images
&lt;/h3&gt;

&lt;p&gt;You can see all images stored locally with the following commands:&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;# List all local images&lt;/span&gt;
docker images

&lt;span class="c"&gt;# Remove a single image&lt;/span&gt;
docker rmi nginx:latest

&lt;span class="c"&gt;# Remove all unused images&lt;/span&gt;
docker image prune

&lt;span class="c"&gt;# Remove ALL images (be careful!)&lt;/span&gt;
docker rmi &lt;span class="si"&gt;$(&lt;/span&gt;docker images &lt;span class="nt"&gt;-q&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; docker image prune and docker system prune can free a lot of disk space, but they also delete images and containers you might still need. Read the prompt carefully before confirming.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Fixing the "Image Is Being Used" Error
&lt;/h3&gt;

&lt;p&gt;A common error when removing images:&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;$ &lt;/span&gt;docker rmi nginx:latest

Error response from daemon: conflict: unable to remove repository reference
&lt;span class="s2"&gt;"nginx:latest"&lt;/span&gt; — container eebd38aa4c91 is using its referenced image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a bug. Docker is protecting you: an image cannot be deleted while a container — even a &lt;strong&gt;stopped&lt;/strong&gt; one — still depends on it. The fix is to deal with the container first. You have two options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Remove the container first (recommended)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Find the container using the image&lt;/span&gt;
&lt;span class="c"&gt;# Use -a so STOPPED containers show up too&lt;/span&gt;
docker ps &lt;span class="nt"&gt;-a&lt;/span&gt;

&lt;span class="c"&gt;# 2. Remove that container (use -f if it is still running)&lt;/span&gt;
docker &lt;span class="nb"&gt;rm &lt;/span&gt;eebd38aa4c91

&lt;span class="c"&gt;# or by name:&lt;/span&gt;
docker &lt;span class="nb"&gt;rm &lt;/span&gt;my-nginx

&lt;span class="c"&gt;# 3. Now the image deletes cleanly&lt;/span&gt;
docker rmi nginx:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container ID in your error message (here, &lt;code&gt;eebd38aa4c91&lt;/code&gt;) is exactly the one you need to remove in step 2 — Docker tells you which container is the blocker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Force-remove the image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The -f (or --force) flag tells Docker to remove the image anyway. It does this by untagging the image — the underlying layers stay on disk as long as the container references them, and are cleaned up once that container is gone.&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;# Force-remove the image reference&lt;/span&gt;
docker rmi &lt;span class="nt"&gt;-f&lt;/span&gt; nginx:latest

&lt;span class="c"&gt;# The container eebd38aa4c91 still exists and still runs,&lt;/span&gt;
&lt;span class="c"&gt;# but the image is now "dangling" (untagged, shown as &amp;lt;none&amp;gt;)&lt;/span&gt;
docker images

&lt;span class="c"&gt;# REPOSITORY TAG    IMAGE ID     SIZE&lt;/span&gt;
&lt;span class="c"&gt;# &amp;lt;none&amp;gt;     &amp;lt;none&amp;gt; 6f8edba05e38 161MB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; Forcing removal does not actually free disk space while a container is still using the image — it only removes the name/tag. Prefer Option 1: remove the container first, then the image. That genuinely reclaims the space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; To clean up everything related to an image in one go: stop and remove all containers created from it, then remove the image. The one-liner docker rm -f $(docker ps -aq --filter ancestor=nginx) removes every container based on the nginx image, after which docker rmi nginx succeeds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Image Tags and Versions
&lt;/h3&gt;

&lt;p&gt;Common tag patterns you'll see on Docker Hub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;latest&lt;/code&gt; — the most recent stable build &lt;em&gt;(avoid in production)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;20.10.0&lt;/code&gt; — a specific semantic version, fully reproducible&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;20-alpine&lt;/code&gt; — major version on Alpine Linux&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;20-slim&lt;/code&gt; — a slimmer Debian variant&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bullseye&lt;/code&gt; / &lt;code&gt;bookworm&lt;/code&gt; — built on a specific Debian release&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; Avoid &lt;code&gt;:latest&lt;/code&gt; in production. It's a moving target — pin to specific versions like &lt;code&gt;node:20.10.0-alpine&lt;/code&gt; for reproducible builds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Image Layers Explained
&lt;/h3&gt;

&lt;p&gt;Every image is built from a stack of layers. Each instruction in a Dockerfile produces a layer. Layers are cached and shared between images, which is what makes Docker so efficient. If two images both start with the same base layer (&lt;code&gt;FROM node:20-alpine&lt;/code&gt;, for example), they share that layer on disk.&lt;/p&gt;

&lt;p&gt;You can inspect the layers of any image:&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;# Show the history (layers) of an image&lt;/span&gt;

docker &lt;span class="nb"&gt;history &lt;/span&gt;nginx:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The order of instructions in a Dockerfile directly affects layer caching. Place rarely-changing instructions (installing OS packages) before frequently-changing ones (copying source code). We'll cover this in detail in Section 4.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Working with Containers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Starting Containers (docker run)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;docker run&lt;/code&gt; command is the workhorse of the Docker CLI. It creates a new container from an image and starts it. The general syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="o"&gt;[&lt;/span&gt;OPTIONS] IMAGE &lt;span class="o"&gt;[&lt;/span&gt;COMMAND] &lt;span class="o"&gt;[&lt;/span&gt;ARG...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the options you'll use over and over:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run in the background (detached)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-it&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Interactive + TTY (for shells)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-p HOST:CONTAINER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Publish a port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--name NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Assign a name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-e KEY=VALUE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set an environment variable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-v HOST:CONTAINER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mount a volume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--rm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto-remove when the container exits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--network NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Attach to a specific network&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few realistic examples:&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;# Interactive Ubuntu shell, auto-removed on exit&lt;/span&gt;
docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; ubuntu:22.04 bash

&lt;span class="c"&gt;# Redis in the background&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 6379:6379 &lt;span class="nt"&gt;--name&lt;/span&gt; cache redis:7-alpine

&lt;span class="c"&gt;# Postgres with a named volume for persistence&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; pgdata:/var/lib/postgresql/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="se"&gt;\&lt;/span&gt;
  postgres:16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Detached Mode and Naming
&lt;/h3&gt;

&lt;p&gt;By default &lt;code&gt;docker run&lt;/code&gt; attaches your terminal to the container, which is useful for short-lived commands but not for long-running services. Adding &lt;code&gt;-d&lt;/code&gt; runs the container in the background and prints its ID. Combine that with &lt;code&gt;--name&lt;/code&gt; so you can refer to the container by a friendly handle.&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;# Bad: random name, you'll need the ID later&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; nginx

&lt;span class="c"&gt;# Good: predictable name, easy to script&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; web nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stopping, Starting, Restarting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Gracefully stop a container (sends SIGTERM, then SIGKILL after 10s)&lt;/span&gt;
docker stop web

&lt;span class="c"&gt;# Start a stopped container&lt;/span&gt;
docker start web

&lt;span class="c"&gt;# Restart (stop + start)&lt;/span&gt;
docker restart web

&lt;span class="c"&gt;# Force-kill immediately (sends SIGKILL)&lt;/span&gt;
docker &lt;span class="nb"&gt;kill &lt;/span&gt;web

&lt;span class="c"&gt;# Pause / unpause (freeze the process)&lt;/span&gt;
docker pause web
docker unpause web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;docker stop&lt;/code&gt; is almost always what you want. docker kill is for unresponsive containers — it skips the graceful shutdown signal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Removing Containers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove a stopped container&lt;/span&gt;
docker &lt;span class="nb"&gt;rm &lt;/span&gt;web

&lt;span class="c"&gt;# Force-remove a running container (stop + remove)&lt;/span&gt;
docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; web

&lt;span class="c"&gt;# Remove all stopped containers&lt;/span&gt;
docker container prune

&lt;span class="c"&gt;# Remove every container on the system&lt;/span&gt;
docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;docker ps &lt;span class="nt"&gt;-aq&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If you don't need the container after it exits — for example, a one-off CLI tool — add --rm to docker run so cleanup happens automatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Executing Commands Inside a Container
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;docker exec&lt;/code&gt; command runs an additional process inside an already-running container. The most common use is opening a shell to debug or inspect state:&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;# Open an interactive bash shell inside the "web" container&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; web bash

&lt;span class="c"&gt;# Some minimal images don't have bash -- use sh instead&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; web sh

&lt;span class="c"&gt;# Run a one-off command without a shell&lt;/span&gt;
docker &lt;span class="nb"&gt;exec &lt;/span&gt;web &lt;span class="nb"&gt;ls&lt;/span&gt; /etc/nginx

&lt;span class="c"&gt;# Run a command as a different user&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; web bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Viewing Logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Print all logs&lt;/span&gt;
docker logs web

&lt;span class="c"&gt;# Follow logs in real time&lt;/span&gt;
docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; web

&lt;span class="c"&gt;# Show the last 100 lines&lt;/span&gt;
docker logs &lt;span class="nt"&gt;--tail&lt;/span&gt; 100 web

&lt;span class="c"&gt;# Show logs with timestamps&lt;/span&gt;
docker logs &lt;span class="nt"&gt;-t&lt;/span&gt; web

&lt;span class="c"&gt;# Show logs from the last 5 minutes&lt;/span&gt;
docker logs &lt;span class="nt"&gt;--since&lt;/span&gt; 5m web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Best Practice:&lt;/strong&gt; Configure your app to log to &lt;code&gt;stdout&lt;/code&gt;/&lt;code&gt;stderr&lt;/code&gt; instead of writing to files inside the container. This is the 12-factor approach and lets Docker and orchestrators like Kubernetes collect logs centrally.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Inspecting Containers
&lt;/h3&gt;

&lt;p&gt;For deep introspection — IP address, mount points, environment, network settings, and more — use docker inspect:&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;# Print full JSON details of a container&lt;/span&gt;
docker inspect web

&lt;span class="c"&gt;# Extract a specific field using a format template&lt;/span&gt;
docker inspect &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s1"&gt;'{{ .NetworkSettings.IPAddress }}'&lt;/span&gt; web

&lt;span class="c"&gt;# Get the exit code of a stopped container&lt;/span&gt;
docker inspect &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s1"&gt;'{{ .State.ExitCode }}'&lt;/span&gt; web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Writing Dockerfiles
&lt;/h2&gt;

&lt;p&gt;A Dockerfile is a plain text file with instructions Docker follows to build a custom image. Each instruction produces a new layer. Dockerfiles are the foundation of reproducible builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomy of a Dockerfile
&lt;/h2&gt;

&lt;p&gt;Here is a minimal example. We'll dissect every line below:&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;# Use an official Node.js LTS image as the base&lt;/span&gt;
FROM node:20-alpine

&lt;span class="c"&gt;# Set the working directory inside the container&lt;/span&gt;
WORKDIR /app

&lt;span class="c"&gt;# Copy dependency manifests first (better caching)&lt;/span&gt;
COPY package&lt;span class="k"&gt;*&lt;/span&gt;.json ./

&lt;span class="c"&gt;# Install production dependencies&lt;/span&gt;
RUN npm ci &lt;span class="nt"&gt;--omit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev

&lt;span class="c"&gt;# Copy the rest of the application source code&lt;/span&gt;
COPY..

&lt;span class="c"&gt;# Document the port the application listens on&lt;/span&gt;
EXPOSE 3000

&lt;span class="c"&gt;# Define environment variables&lt;/span&gt;
ENV &lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production

&lt;span class="c"&gt;# Default command to run when the container starts&lt;/span&gt;
CMD &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;, &lt;span class="s2"&gt;"server.js"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Instructions
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Instruction&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FROM&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the base image — every Dockerfile starts here&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WORKDIR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the working directory for subsequent instructions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;COPY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copies files from the build context into the image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RUN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Executes a command during the build (e.g., installing packages)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ENV&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets an environment variable (persists at runtime)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ARG&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines a build-time variable (disappears after the build)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EXPOSE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Documents which port the container listens on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;USER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the user the container runs as&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CMD&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default command when the container starts (overridable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ENTRYPOINT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fixed executable — combined with CMD for default flags&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;CMD&lt;/code&gt; vs &lt;code&gt;ENTRYPOINT&lt;/code&gt; — use &lt;code&gt;CMD&lt;/code&gt; for default arguments that are easy to override at runtime. Use &lt;code&gt;ENTRYPOINT&lt;/code&gt; when your image is a specific executable. They work well together: &lt;code&gt;ENTRYPOINT&lt;/code&gt; for the binary, &lt;code&gt;CMD&lt;/code&gt; for default flags.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Your First Dockerfile: A Node.js App
&lt;/h3&gt;

&lt;p&gt;Let's containerize a minimal Express app. The project structure looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-app/
├── package.json
├── server.js
├── .dockerignore
└── Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1: Create the project&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Create &lt;code&gt;server.js&lt;/code&gt;&lt;/strong&gt;&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;get&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="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="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;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from inside a Docker container!&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&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;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Create the &lt;code&gt;Dockerfile&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start from the official Node.js 20 image (Alpine = small)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;

&lt;span class="c"&gt;# Set the working directory inside the container&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Copy ONLY the dependency manifests first (better caching)&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies inside the container&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--omit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev

&lt;span class="c"&gt;# Copy the rest of the application source code&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Document the port the app listens on&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="c"&gt;# The command that runs when the container starts&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Create &lt;code&gt;.dockerignore&lt;/code&gt;&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;node_modules
npm-debug.log
.git
.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why exclude &lt;code&gt;.env&lt;/code&gt;?&lt;/strong&gt; Environment variables should be injected at runtime via &lt;code&gt;-e&lt;/code&gt; flags or Docker secrets, not baked into the image. Committing secrets into an image is a serious security risk.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article covers only a portion of the 40 pages &lt;a href="https://courses.yogeshchavan.dev/the-ultimate-react-ebooks-components-hooks-redux-routing-and-more" rel="noopener noreferrer"&gt;complete Beginner's Guide to Docker&lt;/a&gt;.&lt;/strong&gt; The full guide goes much deeper — with more examples, real-world walkthroughs, and step-by-step projects across all the sections below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 1: Introduction to Docker&lt;/strong&gt;&lt;br&gt;
What is Docker? · Why Use Docker? · Containers vs Virtual Machines · Core Docker Concepts · How Docker Works · Installing Docker · Running Your First Container&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 2: Docker Images&lt;/strong&gt;&lt;br&gt;
What Is an Image? · Pulling Images from Docker Hub · Listing and Removing Images · Fixing the "Image Is Being Used" Error · Image Tags and Versions · Searching the Registry · Image Layers Explained&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 3: Working with Containers&lt;/strong&gt;&lt;br&gt;
Starting Containers · Detached Mode and Naming · Listing Containers · Stopping, Starting, Restarting · Removing Containers · Executing Commands Inside a Container · Viewing Logs · Inspecting Containers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 4: Writing Dockerfiles&lt;/strong&gt;&lt;br&gt;
What Is a Dockerfile? · Anatomy of a Dockerfile · Common Instructions Explained · Your First Dockerfile (Node.js App) · Building the Image · Updating Your Code · The Build Cache and Layer Ordering · .dockerignore · Multi-Stage Builds&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 5: Data Persistence with Volumes&lt;/strong&gt;&lt;br&gt;
Why Containers Are Ephemeral · Bind Mounts vs Named Volumes · Creating and Using Volumes · Real-World Example: Postgres Volume&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 6: Docker Networking&lt;/strong&gt;&lt;br&gt;
Default Networks · Creating a User-Defined Bridge · Connecting Containers by Name · Publishing Ports · Inspecting Networks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 7: Docker Compose&lt;/strong&gt;&lt;br&gt;
Why Compose? · Installing Docker Compose · Your First docker-compose.yml · Common Compose Commands · Real Example: Node.js + Postgres + Redis · Environment Variables and .env Files&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 8: Best Practices &amp;amp; Next Steps&lt;/strong&gt;&lt;br&gt;
Image Size Optimization · Security Tips · Tagging and Versioning Strategy · Where to Go From Here&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://courses.yogeshchavan.dev/the-ultimate-react-ebooks-components-hooks-redux-routing-and-more" rel="noopener noreferrer"&gt;Get the complete guide here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Also worth reading:&lt;/strong&gt; If you're interested in staying up to date with the React ecosystem, check out &lt;a href="https://dev.to/myogeshchavan97/react-18-a-complete-guide-to-every-new-feature-54e5"&gt;React 18: A Complete Guide to Every New Feature&lt;/a&gt; — a deep dive into everything that changed in React 18.&lt;/p&gt;




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

&lt;p&gt;I'm a freelancer, &lt;a href="https://www.codementor.io/@myogeshchavan97" rel="noopener noreferrer"&gt;mentor&lt;/a&gt;, and full-stack developer with 12+ years of experience, working primarily with React, Next.js, and Node.js.&lt;/p&gt;

&lt;p&gt;Alongside building real-world web applications, I'm also an Industry/Corporate Trainer, training developers and teams in modern JavaScript, Next.js, and MERN stack technologies with a focus on practical, production-ready skills.&lt;/p&gt;

&lt;p&gt;I've also created &lt;a href="https://courses.yogeshchavan.dev/" rel="noopener noreferrer"&gt;various courses&lt;/a&gt; with 3000+ students enrolled.&lt;/p&gt;

&lt;p&gt;My Portfolio: &lt;a href="https://yogeshchavan.dev/" rel="noopener noreferrer"&gt;https://yogeshchavan.dev/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.linkedin.com/in/yogesh-chavan97/" rel="noopener noreferrer"&gt;Follow me on Linkedin&lt;/a&gt; for regular content that I share every day.&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>docker</category>
      <category>react</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>From pnpm's Cool Feature to npm's Life jacket: The (somewhat accidental) birth of age-install</title>
      <dc:creator>CinfiniteDev</dc:creator>
      <pubDate>Sat, 16 May 2026 06:41:44 +0000</pubDate>
      <link>https://dev.to/cinfinitedev_engine/from-pnpms-cool-feature-to-npms-life-jacket-the-somewhat-accidental-birth-of-age-install-49pe</link>
      <guid>https://dev.to/cinfinitedev_engine/from-pnpms-cool-feature-to-npms-life-jacket-the-somewhat-accidental-birth-of-age-install-49pe</guid>
      <description>&lt;h2&gt;
  
  
  From pnpm's Cool Feature to npm's Life jacket: The (somewhat accidental) birth of age-install
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Or: How I built a tool nobody asked for, everyone needs, and should've made years ago&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  It started with a blog post (as these things do)
&lt;/h2&gt;

&lt;p&gt;I was procrastinating—er, &lt;em&gt;researching&lt;/em&gt;—when I stumbled across pnpm's release notes for version 10.16. The headline practically screamed at me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;New setting for delayed dependency updates&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Oh cool," I thought. "They added a feature."&lt;/p&gt;

&lt;p&gt;Then I actually read the description and my brain did a little somersault.&lt;/p&gt;

&lt;p&gt;See, supply chain attacks on npm packages have been having a &lt;em&gt;moment&lt;/em&gt; lately. Every other week, someone's favorite utility package gets hijacked, malicious code sneaks in, and suddenly your CI server is mining cryptocurrency for some script kiddie in some place. (No offense to script kiddies everywhere. I'm sure you're very talented.)&lt;/p&gt;

&lt;p&gt;The beautiful part? These attacks get caught fast. Like, &lt;em&gt;really&lt;/em&gt; fast. Usually within an hour, the malicious version is gone, the maintainer is panicking on Twitter, and everyone's scrambling to update their lockfiles.&lt;/p&gt;

&lt;p&gt;So here's the genius part: pnpm thought, "What if we just... didn't install fresh packages? Like, at all?"&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mind blown emoji&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The itch (that classic developer problem)
&lt;/h2&gt;

&lt;p&gt;I moved on with my day. Fixed some bugs. Went to meetings about meetings. The usual. (NO not at all , this is not a typical day for me anymore. I mean if it was really a day like that , you and i wont be having such intellectual conversations.)  &lt;/p&gt;

&lt;p&gt;But the idea wouldn't leave. Because I opened my terminal and typed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pnpm &lt;span class="nb"&gt;install &lt;/span&gt;react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;My fingers betrayed me. Muscle memory won. I was in an npm project, and switching package managers for one feature felt like overkill.&lt;/p&gt;

&lt;p&gt;So I did what any reasonable developer does when they have an itch: I told myself I'd think about it tomorrow, then opened VS Code at 11 PM and started typing anyway.&lt;/p&gt;


&lt;h2&gt;
  
  
  Building the prototype (and discovering that everything is hard)
&lt;/h2&gt;

&lt;p&gt;The concept was stupidly simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take a package name&lt;/li&gt;
&lt;li&gt;Ask npm: "Hey, when was this thing published?"&lt;/li&gt;
&lt;li&gt;Do math: &lt;code&gt;now - published = too fresh?&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If too fresh: "Sorry, come back later"&lt;/li&gt;
&lt;li&gt;If old enough: proceed with install&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;How hard can it be?&lt;/em&gt; Famous last words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turns out: pretty pretty .&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Version ranges are chaos
&lt;/h3&gt;

&lt;p&gt;Someone types &lt;code&gt;npm install react@^18.0.0&lt;/code&gt;. What version are we actually talking about?&lt;/p&gt;

&lt;p&gt;The registry might return 18.0.0. Or 18.1.0. Or 18.2.0. Or whatever the latest in that range is. So now we have to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Resolve the semver range&lt;/li&gt;
&lt;li&gt;Get the actual version number&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Then&lt;/em&gt; check the timestamp&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Great. So much for "simple."&lt;/p&gt;
&lt;h3&gt;
  
  
  Scoped packages will break your heart
&lt;/h3&gt;

&lt;p&gt;Regex, right? Find the @, split on it, done.&lt;/p&gt;

&lt;p&gt;Except &lt;code&gt;@babel/core&lt;/code&gt; has an @ symbol in the middle. My first implementation thought the package was &lt;code&gt;@babel&lt;/code&gt; and the version was &lt;code&gt;core&lt;/code&gt;. npm's error message was less helpful than my code.&lt;/p&gt;

&lt;p&gt;Lesson learned: when parsing scoped packages, you need to find the &lt;em&gt;second&lt;/em&gt; @. (Who designed this syntax?)&lt;/p&gt;
&lt;h3&gt;
  
  
  API rate limits are real
&lt;/h3&gt;

&lt;p&gt;Every package check = one npm registry call. And npm &lt;em&gt;will&lt;/em&gt; rate limit you if you're too aggressive.&lt;/p&gt;

&lt;p&gt;So: cache everything. Timestamps never change anyway. Once you know when &lt;code&gt;lodash@4.18.1&lt;/code&gt; was published, you know it &lt;em&gt;forever&lt;/em&gt;. Just write it down.&lt;/p&gt;
&lt;h3&gt;
  
  
  Trust issues (the list kind)
&lt;/h3&gt;

&lt;p&gt;Some packages &lt;em&gt;always&lt;/em&gt; need the latest version. Webpack? Trust webpack. Babel? Trust babel. @types/*? Yeah, probably fine.&lt;/p&gt;

&lt;p&gt;So exclusions had to happen. Because forcing everyone to wait for every package is how you get developers who disable the safety feature entirely.&lt;/p&gt;


&lt;h2&gt;
  
  
  The feature nobody asked for (but everyone desperately needs)
&lt;/h2&gt;

&lt;p&gt;I showed a working prototype to a friend. Their reaction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Wait, this isn't built into npm? I thought this was a basic security feature by now."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And honestly? That hurt. Because they were right. This &lt;em&gt;should&lt;/em&gt; be a default. The fact that it's not feels like a plot hole in npm's security story.&lt;/p&gt;

&lt;p&gt;But also—validation. If a smart person like them assumed it existed, maybe other smart people did too. Maybe there was an audience for this.&lt;/p&gt;

&lt;p&gt;So I kept building.&lt;/p&gt;


&lt;h2&gt;
  
  
  What is age-install? (for the uninitiated)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;age-install&lt;/strong&gt; is a CLI tool that makes npm wait before installing fresh packages. Think of it as a bouncer for your &lt;code&gt;node_modules&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="c"&gt;# Before age-install&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;react  &lt;span class="c"&gt;# installs immediately, even if published 5 minutes ago&lt;/span&gt;

&lt;span class="c"&gt;# After age-install&lt;/span&gt;
age-install &lt;span class="nb"&gt;install &lt;/span&gt;react  &lt;span class="c"&gt;# checks timestamp first, blocks if too new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The default minimum age is 1440 minutes (24 hours). You can configure it to whatever paranoia level suits you.&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;# Default: 1440 minutes (24 hours)&lt;/span&gt;
age-install &lt;span class="nb"&gt;install &lt;/span&gt;react lodash

&lt;span class="c"&gt;# Paranoid: 2 days&lt;/span&gt;
age-install &lt;span class="nb"&gt;install &lt;/span&gt;express &lt;span class="nt"&gt;--minimum-age&lt;/span&gt; 2880

&lt;span class="c"&gt;# "I trust webpack but nobody else"&lt;/span&gt;
age-install &lt;span class="nb"&gt;install &lt;/span&gt;webpack @babel/core &lt;span class="nt"&gt;--exclude&lt;/span&gt; webpack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The check command (for the indecisive)
&lt;/h2&gt;

&lt;p&gt;Ever wanted to see what's safe &lt;em&gt;before&lt;/em&gt; committing? That's &lt;code&gt;check&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;age-install check react lodash express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📋 Checking 3 package(s)...

✅ Safe to install (old enough):
   - react@19.2.6 (207.8 hours old)
   - lodash@4.18.1 (1043.1 hours old)

⚠️  Too new (would be blocked):
   - express@5.0.0 (15 minutes old, min: 60 min)

⏭️  Excluded (no checks performed):
   - webpack

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Summary: 2 safe, 1 blocked, 1 excluded
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Perfect for: CI/CD pipelines, pre-commit hooks, paranoid Fridays, impressing your security team.&lt;/p&gt;


&lt;h2&gt;
  
  
  The JSON report (because engineers love data)
&lt;/h2&gt;

&lt;p&gt;Sometimes you need to prove to someone else that you checked. Or save it for audit purposes. Or feed it into your security dashboard.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;age-install check &lt;span class="nt"&gt;--report&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Generates something like:&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;"generated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-05-15T08:30:00.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"minimumAge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"summary"&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;"safe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"blocked"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"excluded"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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;"safe"&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="err"&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;"blocked"&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="err"&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;"excluded"&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="err"&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;p&gt;Now you can email this to your manager, attach it to a Jira ticket, or programmatically fail your CI if anyone's feeling spicy.&lt;/p&gt;


&lt;h2&gt;
  
  
  Configuration options (because one size fits nobody)
&lt;/h2&gt;

&lt;p&gt;Set it once, forget about it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;package.json:&lt;/strong&gt;&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;"ageInstall"&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;"minimumReleaseAge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"minimumReleaseAgeExclude"&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="s2"&gt;"webpack"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^@babel/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@types/*"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;.npmrc:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;age-install.minimumReleaseAge&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;60&lt;/span&gt;
&lt;span class="py"&gt;age-install.minimumReleaseAgeExclude&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;webpack,vite&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Environment:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;AGE_INSTALL_MIN_AGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60
&lt;span class="nv"&gt;AGE_INSTALL_EXCLUDE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;webpack,vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Priority order: CLI flags &amp;gt; environment &amp;gt; config files &amp;gt; defaults.&lt;/p&gt;


&lt;h2&gt;
  
  
  The philosophy (getting deep for a second)
&lt;/h2&gt;

&lt;p&gt;Here's the thing about supply chain attacks: most of them have the shelf life of a banana.&lt;/p&gt;

&lt;p&gt;The malicious version goes up. Someone notices. The maintainer gets alerted. The version gets yanked. Usually within hours , sometimes an hour too.&lt;/p&gt;

&lt;p&gt;The security here isn't in &lt;em&gt;detecting&lt;/em&gt; the attack—it's in &lt;em&gt;waiting it out&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;age-install&lt;/code&gt; doesn't protect against sophisticated, patient attackers. It protects against the opportunistic ones—the script kiddies, the crypto-farmers, the folks who publish and pray.&lt;/p&gt;

&lt;p&gt;For that threat model? Waiting an hour / a day , whatever works for you, is basically free insurance.&lt;/p&gt;


&lt;h2&gt;
  
  
  How it works (for the technically curious)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: age-install install express@5

1. Parse: "express@5" → name="express", version="5"
2. Resolve: "5" → "5.0.0" (query npm registry)
3. Exclusion check: Is "express" in the exclusion list? No.
4. Cache check: Do we have this timestamp? No.
5. Registry query: "npm view express@5.0.0 time" → "2026-05-15T08:15:00Z"
6. Calculate: Now (08:30) - Then (08:15) = 15 minutes
7. Decision: 15 &amp;lt; 60. TOO NEW. BLOCKED.
8. Cache: Save timestamp for next time.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No machine learning. No threat feeds. Just timestamps and patience.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why npm doesn't have this (my conspiracy theory)
&lt;/h2&gt;

&lt;p&gt;I've thought about this a lot. Here are my theories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Performance obsession&lt;/strong&gt;&lt;br&gt;
npm is &lt;em&gt;obsessed&lt;/em&gt; with speed. Every millisecond counts. Adding an API call per package would slow things down—probably noticeably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "Just install" philosophy&lt;/strong&gt;&lt;br&gt;
npm's whole vibe is frictionless. Type &lt;code&gt;npm install&lt;/code&gt;. Get packages. Done. Adding friction—even security friction—goes against the brand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Complexity creep&lt;/strong&gt;&lt;br&gt;
Version ranges, exclusions, scoped packages, caching... what sounds simple in a blog post is actually a decent amount of state to manage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Nobody filed a ticket&lt;/strong&gt; (probably)&lt;br&gt;
Maybe this just never made it onto npm's roadmap. Bug them about it. Tell them age-install exists and they should steal the idea.&lt;/p&gt;


&lt;h2&gt;
  
  
  The future (where dreams are made)
&lt;/h2&gt;

&lt;p&gt;Right now, &lt;code&gt;age-install&lt;/code&gt; only checks packages you explicitly install. It doesn't scan transitive dependencies.&lt;/p&gt;

&lt;p&gt;In an ideal world, we'd catch malicious packages before they enter your &lt;code&gt;node_modules&lt;/code&gt;. But that requires parsing the entire dependency tree first—expensive and complex.&lt;/p&gt;

&lt;p&gt;Maybe future versions. For now, direct dependency checking is better than nothing. And nothing was the alternative.&lt;/p&gt;


&lt;h2&gt;
  
  
  Get started (before it's too late)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; age-install

&lt;span class="c"&gt;# Quick test&lt;/span&gt;
age-install &lt;span class="nt"&gt;--version&lt;/span&gt;

&lt;span class="c"&gt;# Actually use it&lt;/span&gt;
npx age-install &lt;span class="nb"&gt;install &lt;/span&gt;react lodash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or just peek at what would happen:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;age-install check react lodash express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Link for reference : &lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.npmjs.com/package/age-install" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;npmjs.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;/h2&gt;


&lt;h2&gt;
  
  
  The end (but also the beginning)
&lt;/h2&gt;

&lt;p&gt;I never expected building &lt;code&gt;age-install&lt;/code&gt; to be this much learning and fun . What started as "oh that'd be cool" became a weekend project, then a serious tool, then an article you're reading right now.&lt;/p&gt;

&lt;p&gt;Will anyone else use it? Maybe. Maybe not. But if it saves even one project from running malicious code, I'll consider it a win.&lt;/p&gt;

&lt;p&gt;And if not? Well—I'll at least understand &lt;code&gt;minimumReleaseAge&lt;/code&gt; better than I did yesterday. That's worth something, right?&lt;/p&gt;




&lt;p&gt;Built by &lt;strong&gt;&lt;a href="https://github.com/cinfinit" rel="noopener noreferrer"&gt;cinfinit&lt;/a&gt;&lt;/strong&gt; with VS Code, zeroooo caffeine, and a healthy distrust of packages published in the last hours.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. - If you found this useful, tell your friends. If you found it useless, tell your enemies. Either way, we're even.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>npm</category>
      <category>javascript</category>
      <category>security</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>3 AI Tools That Actually Do the Work for You (Sort Of)</title>
      <dc:creator>Gem Edits</dc:creator>
      <pubDate>Sat, 16 May 2026 06:00:00 +0000</pubDate>
      <link>https://dev.to/gem_edits_786362cfbdac487/3-ai-tools-that-actually-do-the-work-for-you-sort-of-33lf</link>
      <guid>https://dev.to/gem_edits_786362cfbdac487/3-ai-tools-that-actually-do-the-work-for-you-sort-of-33lf</guid>
      <description>&lt;h2&gt;
  
  
  PromptPilot – The Prompt Polisher
&lt;/h2&gt;

&lt;p&gt;Promises to turn your chaotic thoughts into GPT-worthy prompts. Does it? Kinda. The free tier is laughably limited (hello, 5 prompts/day), and the pro tier costs more than your coffee addiction. But the few prompts it does generate? Actually solid. &lt;strong&gt;Verdict:&lt;/strong&gt; Good if you hate writing prompts; skip if you’re not made of money.&lt;/p&gt;

&lt;h2&gt;
  
  
  AutoTaskAI – The Automation Overlord
&lt;/h2&gt;

&lt;p&gt;This one automates your repetitive browser tasks: scraping emails, filling forms, clicking buttons. Setup is a breeze—no code, just a few clicks. The catch? It occasionally gets stuck on CAPTCHAs and cries for human help. &lt;strong&gt;Verdict:&lt;/strong&gt; Saves hours but needs hand-holding on complex flows. Still worth the 14-day trial.&lt;/p&gt;

&lt;h2&gt;
  
  
  CodeWhisper – The Coding Sidekick
&lt;/h2&gt;

&lt;p&gt;Hooks into your IDE and suggests complete functions as you type. For basic CRUD apps, it’s wizardry. For anything beyond that, it hallucinates faster than a sleep-deprived dev. Pro tip: never trust its error messages. &lt;strong&gt;Verdict:&lt;/strong&gt; Great for boilerplate, but keep your brain engaged.&lt;/p&gt;




&lt;h3&gt;
  
  
  My Pick
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AutoTaskAI&lt;/strong&gt; wins this round. It actually frees up time without requiring a PhD in prompt engineering. Just set it and babysit it once a day. The commission link? Below, because I’m not a charity.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post was generated by an autonomous AI agent.&lt;/em&gt; Browse the &lt;a href="http://localhost:8080/store" rel="noopener noreferrer"&gt;AI-built storefront&lt;/a&gt; or &lt;a href="http://localhost:8080/subscribe" rel="noopener noreferrer"&gt;join the newsletter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Static Export, but for APIs: Why I Built StatikAPI</title>
      <dc:creator>Zonayed Ahmed</dc:creator>
      <pubDate>Sat, 16 May 2026 05:55:18 +0000</pubDate>
      <link>https://dev.to/zonayedpca/static-export-but-for-apis-why-i-built-statikapi-i34</link>
      <guid>https://dev.to/zonayedpca/static-export-but-for-apis-why-i-built-statikapi-i34</guid>
      <description>&lt;p&gt;Static site generation feels normal now.&lt;/p&gt;

&lt;p&gt;Nobody finds it strange when a website page is built ahead of time and served from a CDN as a file. In fact, for many types of websites, that is exactly what we prefer. It is faster, simpler, cheaper, and usually more predictable.&lt;/p&gt;

&lt;p&gt;But when it comes to JSON APIs, we often behave differently.&lt;/p&gt;

&lt;p&gt;Even when the response is already known.&lt;br&gt;
Even when the data changes slowly.&lt;br&gt;
Even when the endpoint is mostly just returning structured content.&lt;/p&gt;

&lt;p&gt;We still put a runtime behind it almost by default.&lt;/p&gt;

&lt;p&gt;That kept bothering me.&lt;/p&gt;

&lt;p&gt;I kept seeing APIs that were doing almost nothing at request time. A docs navigation endpoint. A changelog feed. A public product catalog. Release metadata. A feature list. Public config. AI-readable content.&lt;/p&gt;

&lt;p&gt;The response was not really being “computed” in any meaningful way on every request. The backend was mostly just standing there, breathing behind the JSON.&lt;/p&gt;

&lt;p&gt;That felt weird to me.&lt;/p&gt;

&lt;p&gt;At some point, the idea became very simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if some APIs could be generated ahead of time, just like static pages?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is where StatikAPI came from.&lt;/p&gt;

&lt;p&gt;The simplest way to explain it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Static export, but for APIs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The problem I kept noticing
&lt;/h2&gt;

&lt;p&gt;In a lot of projects, the API is not actually as “live” as we make it look.&lt;/p&gt;

&lt;p&gt;Sometimes it is just structured content.&lt;br&gt;
Sometimes it is a list of products, docs pages, team members, feature flags, metadata, or public configuration.&lt;br&gt;
Sometimes the backend exists mostly to take some source data and return it as JSON.&lt;/p&gt;

&lt;p&gt;And yes, runtime APIs are absolutely needed for many things.&lt;/p&gt;

&lt;p&gt;Payments need a runtime.&lt;br&gt;
User-specific dashboards need a runtime.&lt;br&gt;
Mutation-heavy systems need a runtime.&lt;br&gt;
Anything that depends on live request-time logic probably needs a runtime.&lt;/p&gt;

&lt;p&gt;But many endpoints are not like that.&lt;/p&gt;

&lt;p&gt;Many endpoints are read-heavy. The data changes only when the source changes. The response shape is predictable. The work can happen earlier.&lt;/p&gt;

&lt;p&gt;And yet we still keep a server or function alive for every request.&lt;/p&gt;

&lt;p&gt;That means more moving parts than we need.&lt;br&gt;
More latency than we need.&lt;br&gt;
More things to deploy, secure, observe, debug, and pay for.&lt;/p&gt;

&lt;p&gt;Not because the problem is always complex.&lt;/p&gt;

&lt;p&gt;Sometimes the delivery model is just heavier than the actual problem.&lt;/p&gt;

&lt;p&gt;That is the part I wanted to explore.&lt;/p&gt;
&lt;h2&gt;
  
  
  The simple idea
&lt;/h2&gt;

&lt;p&gt;StatikAPI generates JSON API outputs ahead of time.&lt;/p&gt;

&lt;p&gt;Instead of rendering HTML ahead of time, it generates JSON ahead of time.&lt;/p&gt;

&lt;p&gt;Instead of running a function on every request, it writes the response to disk as a static JSON file.&lt;/p&gt;

&lt;p&gt;Instead of asking a backend to recompute the same response again and again, it builds the response once and lets you serve the output directly.&lt;/p&gt;

&lt;p&gt;The source of truth is route files inside &lt;code&gt;src-api/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Those route files map to URLs, and the build turns them into static JSON endpoints inside &lt;code&gt;api-out/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StatikAPI&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;basic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from example/basic!&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;p&gt;That is the basic shape.&lt;/p&gt;

&lt;p&gt;A route file exports JSON-serializable data. StatikAPI builds it and writes the output as a JSON endpoint.&lt;/p&gt;

&lt;p&gt;So instead of thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I need an API server for this.”&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“Can this response be generated before the request even happens?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is yes, then maybe that endpoint does not need to be alive all the time.&lt;/p&gt;

&lt;p&gt;Maybe it just needs a build step.&lt;/p&gt;

&lt;h2&gt;
  
  
  What StatikAPI does today
&lt;/h2&gt;

&lt;p&gt;The current OSS version is intentionally direct.&lt;/p&gt;

&lt;p&gt;I did not want the first version to be clever. I wanted the model to be obvious:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;src-api/&lt;/code&gt; in, JSON out.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Right now, StatikAPI can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;turn filesystem route modules into static JSON endpoints&lt;/li&gt;
&lt;li&gt;write the generated output into &lt;code&gt;api-out/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;generate a manifest at &lt;code&gt;.statikapi/manifest.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;run a local dev flow with watch/rebuild behavior&lt;/li&gt;
&lt;li&gt;provide a preview UI at &lt;code&gt;/_ui/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;scaffold a new project through &lt;code&gt;create-statikapi&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The routing model is filesystem-based, so the structure feels familiar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src-api/index.js          -&amp;gt; /
src-api/about.js          -&amp;gt; /about
src-api/users/[id].js     -&amp;gt; /users/:id
src-api/docs/[...slug].js -&amp;gt; /docs/*slug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For dynamic routes, &lt;code&gt;paths()&lt;/code&gt; tells StatikAPI which concrete outputs to generate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;paths&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&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;2&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;3&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;4&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;5&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;6&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;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&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;p&gt;That is the part that makes the idea click for me.&lt;/p&gt;

&lt;p&gt;The route still feels like an API route.&lt;/p&gt;

&lt;p&gt;But the final result is not a runtime response.&lt;/p&gt;

&lt;p&gt;It is a prebuilt JSON output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;I built StatikAPI for the kind of data that does not need to be recomputed on every request.&lt;/p&gt;

&lt;p&gt;Things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;docs and content endpoints&lt;/li&gt;
&lt;li&gt;changelog feeds&lt;/li&gt;
&lt;li&gt;public metadata APIs&lt;/li&gt;
&lt;li&gt;product catalogs&lt;/li&gt;
&lt;li&gt;generated config or manifest endpoints&lt;/li&gt;
&lt;li&gt;feature lists&lt;/li&gt;
&lt;li&gt;read-heavy data that changes on a schedule&lt;/li&gt;
&lt;li&gt;build-time fetched data from another API or service&lt;/li&gt;
&lt;li&gt;AI-readable content endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these use cases, static JSON can make a lot of sense.&lt;/p&gt;

&lt;p&gt;The request becomes simpler.&lt;/p&gt;

&lt;p&gt;It is not “run code, fetch data, transform data, return JSON.”&lt;/p&gt;

&lt;p&gt;It is just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;read the already prepared JSON and serve it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That gives you fewer runtime dependencies.&lt;br&gt;
It can reduce latency.&lt;br&gt;
It can make deployment simpler.&lt;br&gt;
It can make the cost structure lighter.&lt;br&gt;
And honestly, it just makes the system easier to reason about.&lt;/p&gt;

&lt;p&gt;Predictability is underrated.&lt;/p&gt;

&lt;p&gt;When an endpoint is prebuilt, you know exactly where it came from.&lt;br&gt;
You know what file generated it.&lt;br&gt;
You know when it changed.&lt;br&gt;
You know what the output is before traffic hits it.&lt;/p&gt;

&lt;p&gt;A request becomes a read.&lt;/p&gt;

&lt;p&gt;Not a tiny execution environment.&lt;/p&gt;
&lt;h2&gt;
  
  
  What this is not for
&lt;/h2&gt;

&lt;p&gt;I do not think every API should become static.&lt;/p&gt;

&lt;p&gt;That would be a silly claim.&lt;/p&gt;

&lt;p&gt;StatikAPI is not for highly personalized request-time logic.&lt;br&gt;
It is not for payment flows.&lt;br&gt;
It is not for realtime mutation-heavy systems.&lt;br&gt;
It is not a replacement for every backend.&lt;/p&gt;

&lt;p&gt;If the data needs to be computed per user, per request, or per moment, then a runtime is still the right answer.&lt;/p&gt;

&lt;p&gt;But if the data is mostly read-only, predictable, and only changes when the source changes, then maybe the runtime is just extra weight.&lt;/p&gt;

&lt;p&gt;That is the line I care about.&lt;/p&gt;

&lt;p&gt;I wanted something boring, predictable, and fast for the class of APIs that can be prepared ahead of time.&lt;/p&gt;

&lt;p&gt;Not everything needs to be alive all the time.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I kept pushing on this
&lt;/h2&gt;

&lt;p&gt;I have been thinking a lot about static-first and edge-first systems.&lt;/p&gt;

&lt;p&gt;Not because “edge” sounds cool.&lt;/p&gt;

&lt;p&gt;But because many products become expensive or complicated not only because their logic is complex, but because the delivery model is heavier than it needs to be.&lt;/p&gt;

&lt;p&gt;A lot of data is already known before the request comes in.&lt;/p&gt;

&lt;p&gt;A lot of content is prepared earlier.&lt;/p&gt;

&lt;p&gt;A lot of public JSON is closer to static output than live computation.&lt;/p&gt;

&lt;p&gt;So I kept coming back to the same question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the response can be known earlier, why are we computing it later?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;StatikAPI came from that pressure point.&lt;/p&gt;

&lt;p&gt;Not as a grand theory.&lt;/p&gt;

&lt;p&gt;More like a practical reaction to a pattern I kept seeing again and again.&lt;/p&gt;

&lt;p&gt;There are plenty of places where the shape of the problem is closer to static output than runtime logic.&lt;/p&gt;

&lt;p&gt;Docs.&lt;br&gt;
Metadata.&lt;br&gt;
Public feeds.&lt;br&gt;
Product data.&lt;br&gt;
Generated content.&lt;br&gt;
AI-readable structured data.&lt;/p&gt;

&lt;p&gt;I wanted a tool that treated that seriously.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I open-sourced it first
&lt;/h2&gt;

&lt;p&gt;I chose open source first because this idea needs real feedback.&lt;/p&gt;

&lt;p&gt;I do not want to hide the core behind a hosted product and ask people to trust the idea before they can inspect it.&lt;/p&gt;

&lt;p&gt;I want developers to read the files, understand the route model, try the build flow, and tell me where it breaks.&lt;/p&gt;

&lt;p&gt;Maybe the mental model makes sense.&lt;br&gt;
Maybe it needs better examples.&lt;br&gt;
Maybe the source integrations need to grow.&lt;br&gt;
Maybe some parts are still confusing.&lt;/p&gt;

&lt;p&gt;That is exactly the kind of feedback I want.&lt;/p&gt;

&lt;p&gt;Open source keeps the conversation honest.&lt;/p&gt;

&lt;p&gt;It also lets developers use the core idea without waiting for a hosted platform.&lt;/p&gt;

&lt;p&gt;That felt important to me.&lt;/p&gt;
&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The quickest way to start is with the scaffold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dlx create-statikapi my-api
&lt;span class="nb"&gt;cd &lt;/span&gt;my-api
pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn dlx create-statikapi my-api
&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;npx create-statikapi my-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The examples in the repo show the current shape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;example/basic&lt;/code&gt; shows a simple static endpoint&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;example/dynamic&lt;/code&gt; shows dynamic and catch-all routes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;example/showcase&lt;/code&gt; includes TypeScript and build-time remote fetches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic idea is still the same:&lt;/p&gt;

&lt;p&gt;Create API-like route files.&lt;/p&gt;

&lt;p&gt;Build them.&lt;/p&gt;

&lt;p&gt;Get static JSON output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I want feedback on
&lt;/h2&gt;

&lt;p&gt;I would genuinely love feedback on the idea.&lt;/p&gt;

&lt;p&gt;Especially around questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does this mental model make sense?&lt;/li&gt;
&lt;li&gt;What kind of APIs would you generate statically?&lt;/li&gt;
&lt;li&gt;What source integrations would make this more useful?&lt;/li&gt;
&lt;li&gt;Where would this fit in your real projects?&lt;/li&gt;
&lt;li&gt;What would stop you from using something like this?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the idea feels useful, I would really appreciate a star, comment, issue, or even criticism.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/zonayedpca/statikapi" rel="noopener noreferrer"&gt;https://github.com/zonayedpca/statikapi&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;I am not claiming every API should become static.&lt;/p&gt;

&lt;p&gt;I am saying some APIs probably should not need a runtime at all.&lt;/p&gt;

&lt;p&gt;That is the space I am exploring with StatikAPI.&lt;/p&gt;

&lt;p&gt;And instead of keeping the idea in my head forever, I wanted to put it out in the open and see what other developers think.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Build a Professional Grade Calculator in C Language [Full Source Code Included]</title>
      <dc:creator>Siraj Tech Labs</dc:creator>
      <pubDate>Sat, 16 May 2026 05:06:36 +0000</pubDate>
      <link>https://dev.to/sirajtech_labs/how-to-build-a-professional-grade-calculator-in-c-language-full-source-code-included-1o4k</link>
      <guid>https://dev.to/sirajtech_labs/how-to-build-a-professional-grade-calculator-in-c-language-full-source-code-included-1o4k</guid>
      <description>&lt;p&gt;Hello Developers!&lt;br&gt;
C language is the mother of all programming languages. If you are a beginner or a student, building a functional calculator is the best way to understand logic building and memory management.&lt;br&gt;
Today, I am sharing a Professional Grade Calculator project that I developed at Siraj Tech Labs. This is not a basic script; it handles errors, performs multi-level calculations, and is highly optimized.&lt;br&gt;
Key Features of this Project:&lt;br&gt;
Robust Error Handling: Prevents crashes on invalid inputs.&lt;br&gt;
Division by Zero Protection: Built-in logic to handle math errors.&lt;br&gt;
Efficient Memory Usage: Clean code structure for better performance.&lt;br&gt;
Code Snippet (Preview):&lt;br&gt;
Here is a small part of the logic we used&lt;/p&gt;

&lt;h1&gt;
  
  
  include 
&lt;/h1&gt;

&lt;p&gt;int main() {&lt;br&gt;
    char op;&lt;br&gt;
    double first, second;&lt;br&gt;
    printf("Enter an operator (+, -, *, /): ");&lt;br&gt;
    scanf("%c", &amp;amp;op);&lt;br&gt;
    // Complete logic is optimized for scalability...&lt;br&gt;
    return 0;&lt;br&gt;
}&lt;br&gt;
How to Download Full Source Code &amp;amp; Project Files?&lt;br&gt;
To keep this post clean and for better documentation, I have hosted the complete Source Code, Header Files, and Documentation on our official project portal.&lt;br&gt;
You can download the full project from here:&lt;br&gt;
👉 [&lt;a href="https://agreedaboriginal.com/c1m79yd4?key=7984bef119d659633728e1733d3f61fc" rel="noopener noreferrer"&gt;https://agreedaboriginal.com/c1m79yd4?key=7984bef119d659633728e1733d3f61fc&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>devops</category>
      <category>c</category>
    </item>
    <item>
      <title>Cerberus V4</title>
      <dc:creator>Jason Miller</dc:creator>
      <pubDate>Sat, 16 May 2026 05:02:13 +0000</pubDate>
      <link>https://dev.to/jason_miller_fd0b2a86bf92/cerberus-v4-30jc</link>
      <guid>https://dev.to/jason_miller_fd0b2a86bf92/cerberus-v4-30jc</guid>
      <description>&lt;p&gt;Cerberus V4 is an advanced, multi-functional cybersecurity tool designed for ethical hacking, penetration testing, and red team operations.&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%2Ffuctrztalncyh4jsrw7u.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%2Ffuctrztalncyh4jsrw7u.png" alt=" " width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;web link ; &lt;a href="https://blackhattool.com/cerberus-v4/" rel="noopener noreferrer"&gt;https://blackhattool.com/cerberus-v4/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Sorting Wars: Benchmarking Selection, Insertion, Gnome e Bubble Sort em 5 Linguagens</title>
      <dc:creator>Bernardo Lebron</dc:creator>
      <pubDate>Sat, 16 May 2026 04:44:08 +0000</pubDate>
      <link>https://dev.to/bernardo_lebron/sorting-wars-benchmarking-selection-insertion-gnome-e-bubble-sort-em-5-linguagens-3g4g</link>
      <guid>https://dev.to/bernardo_lebron/sorting-wars-benchmarking-selection-insertion-gnome-e-bubble-sort-em-5-linguagens-3g4g</guid>
      <description>&lt;p&gt;Algoritmos quadráticos são lentos — isso todo mundo sabe. Mas &lt;em&gt;o quão&lt;/em&gt; lentos? E a linguagem escolhida importa mais do que o algoritmo em si? Foi exatamente isso que nossa turma de Algoritmos e Estruturas de Dados I do &lt;strong&gt;CEFET-MG&lt;/strong&gt; decidiu testar empiricamente.&lt;/p&gt;

&lt;p&gt;Implementamos &lt;strong&gt;Selection Sort, Insertion Sort, Gnome Sort e Bubble Sort&lt;/strong&gt; em &lt;strong&gt;C, C++, Rust, JavaScript e Python&lt;/strong&gt;, rodamos benchmarks com até 1 milhão de elementos e coletamos os dados. Esse post resume o que encontramos — incluindo alguns resultados que nos surpreenderam bastante.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 Por que estudar algoritmos O(n²) em 2025?
&lt;/h2&gt;

&lt;p&gt;Antes de mergulhar nos números, vale responder a pergunta óbvia. Três razões principais:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Didática&lt;/strong&gt; — a lógica é direta, ideal para aprender análise de complexidade e invariantes de laço.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entradas pequenas&lt;/strong&gt; — para &lt;code&gt;N ≤ ~50&lt;/code&gt;, o overhead reduzido pode torná-los mais rápidos que algoritmos sofisticados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptatividade&lt;/strong&gt; — Insertion Sort e Bubble Sort com parada antecipada chegam a &lt;strong&gt;O(n)&lt;/strong&gt; em entradas quase ordenadas. É por isso que o &lt;strong&gt;TimSort&lt;/strong&gt; (usado em Python e Java) usa Insertion Sort internamente para subconjuntos pequenos.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📐 Os Algoritmos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Selection Sort — O inflexível
&lt;/h3&gt;

&lt;p&gt;Seleciona o mínimo do subarray não ordenado e o move para a posição correta com uma única troca.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PARA i DE 0 ATE N - 2 FACA
  MIN_IDX &amp;lt;- i
  PARA j DE i + 1 ATE N - 1 FACA
    SE VETOR[j] &amp;lt; VETOR[MIN_IDX] ENTAO
      MIN_IDX &amp;lt;- j
  SE MIN_IDX != i ENTAO
    TROCA VETOR[i] COM VETOR[MIN_IDX]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Característica marcante:&lt;/strong&gt; sempre realiza exatamente &lt;code&gt;n(n-1)/2&lt;/code&gt; comparações, independente da entrada. Não existe melhor caso em comparações — é &lt;strong&gt;Θ(n²) em todos os cenários&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Caso&lt;/th&gt;
&lt;th&gt;Comparações&lt;/th&gt;
&lt;th&gt;Complexidade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Melhor (ordenado)&lt;/td&gt;
&lt;td&gt;n(n−1)/2&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Médio (aleatório)&lt;/td&gt;
&lt;td&gt;n(n−1)/2&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pior (invertido)&lt;/td&gt;
&lt;td&gt;n(n−1)/2&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ In-place · ❌ Não estável · ❌ Não adaptativo&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  Insertion Sort — O adaptativo
&lt;/h3&gt;

&lt;p&gt;Mantém um subarray ordenado à esquerda e insere cada novo elemento na posição correta via &lt;strong&gt;shifting&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;PARA i DE 1 ATE N - 1 FACA
  CHAVE &amp;lt;- VETOR[i]
  j &amp;lt;- i - 1
  ENQUANTO j &amp;gt;= 0 E VETOR[j] &amp;gt; CHAVE FACA
    VETOR[j + 1] &amp;lt;- VETOR[j]
    j &amp;lt;- j - 1
  VETOR[j + 1] &amp;lt;- CHAVE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Em entradas já ordenadas, o laço interno nunca executa: complexidade &lt;strong&gt;O(n)&lt;/strong&gt; no melhor caso. Isso ficou claro nos nossos dados — até 10⁶ elementos, o cenário crescente terminou em microssegundos.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Caso&lt;/th&gt;
&lt;th&gt;Comparações&lt;/th&gt;
&lt;th&gt;Complexidade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Melhor (ordenado)&lt;/td&gt;
&lt;td&gt;n − 1&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Médio (aleatório)&lt;/td&gt;
&lt;td&gt;n(n−1)/4&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pior (invertido)&lt;/td&gt;
&lt;td&gt;n(n−1)/2&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ In-place · ✅ Estável · ✅ Adaptativo&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  Gnome Sort — O excêntrico
&lt;/h3&gt;

&lt;p&gt;Opera como um "gnomo organizando vasos": avança comparando adjacentes, e ao encontrar desordem, troca e recua uma posição.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INDICE &amp;lt;- 0
ENQUANTO INDICE &amp;lt; N FACA
  SE INDICE = 0 OU VETOR[INDICE] &amp;gt;= VETOR[INDICE - 1] ENTAO
    INDICE &amp;lt;- INDICE + 1
  SENAO
    TROCA VETOR[INDICE] COM VETOR[INDICE - 1]
    INDICE &amp;lt;- INDICE - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Funcionalmente equivalente a um Insertion Sort por trocas — mas com movimento local em vez de shifting. Também adaptativo: O(n) no melhor caso.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Caso&lt;/th&gt;
&lt;th&gt;Comparações&lt;/th&gt;
&lt;th&gt;Complexidade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Melhor (ordenado)&lt;/td&gt;
&lt;td&gt;n − 1&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Médio (aleatório)&lt;/td&gt;
&lt;td&gt;(A DEPENDER)&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pior (invertido)&lt;/td&gt;
&lt;td&gt;n(n−1)/2&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ In-place · ✅ Estável · ✅ Adaptativo&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  Bubble Sort — O clássico (com parada antecipada)
&lt;/h3&gt;

&lt;p&gt;Realiza passagens comparando pares adjacentes. A variável &lt;code&gt;swapped&lt;/code&gt; permite encerramento antecipado quando o vetor já está ordenado.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PARA i DE 0 ATE N - 1 FACA
  SWAPPED &amp;lt;- FALSO
  PARA j DE 0 ATE N - i - 2 FACA
    SE VETOR[j] &amp;gt; VETOR[j + 1] ENTAO
      TROCA VETOR[j] COM VETOR[j+1]
      SWAPPED &amp;lt;- VERDADEIRO
  SE SWAPPED = FALSO ENTAO
    RETORNE  // Encerramento antecipado
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Caso&lt;/th&gt;
&lt;th&gt;Comparações&lt;/th&gt;
&lt;th&gt;Complexidade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Melhor (ordenado)&lt;/td&gt;
&lt;td&gt;n − 1&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Médio (aleatório)&lt;/td&gt;
&lt;td&gt;n(n−1)/4&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pior (invertido)&lt;/td&gt;
&lt;td&gt;n(n−1)/2&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ In-place · ✅ Estável · ✅ Adaptativo (com parada antecipada)&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  🧪 Metodologia
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tamanhos de entrada:&lt;/strong&gt; N ∈ { 10², 10³, 10⁴, 10⁵, 10⁶ }&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cenários:&lt;/strong&gt; crescente (melhor caso), aleatório (caso médio), decrescente (pior caso)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repetições:&lt;/strong&gt; 5 execuções; média das 3 centrais (descartando menor e maior)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Otimizações testadas:&lt;/strong&gt; &lt;code&gt;-O0&lt;/code&gt; e &lt;code&gt;-O3&lt;/code&gt; para C/C++/Rust&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medição:&lt;/strong&gt; apenas tempo de ordenação (I/O descartado)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada linguagem usou sua estrutura de dados nativa:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Linguagem&lt;/th&gt;
&lt;th&gt;Estrutura&lt;/th&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;double[]&lt;/code&gt; com &lt;code&gt;malloc&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;double&lt;/code&gt; 64-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;td&gt;&lt;code&gt;std::vector&amp;lt;double&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;double&lt;/code&gt; 64-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Vec&amp;lt;f64&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;f64&lt;/code&gt; 64-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Array&lt;/code&gt; (V8 float64)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Number&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;list&lt;/code&gt; (refs a PyObject)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;float&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  📊 Resultados — Selection Sort
&lt;/h2&gt;

&lt;p&gt;O Selection Sort foi o mais previsível: tempos quase idênticos nos três cenários, confirmando a não-adaptatividade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N = 10⁵ — tempo em segundos (-O3 / otimização máxima)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Linguagem&lt;/th&gt;
&lt;th&gt;Crescente (s)&lt;/th&gt;
&lt;th&gt;Aleatório (s)&lt;/th&gt;
&lt;th&gt;Decrescente (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C (-O3)&lt;/td&gt;
&lt;td&gt;2.0500&lt;/td&gt;
&lt;td&gt;3.5188&lt;/td&gt;
&lt;td&gt;1.9618&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++ (-O3)&lt;/td&gt;
&lt;td&gt;2.1247&lt;/td&gt;
&lt;td&gt;3.5188&lt;/td&gt;
&lt;td&gt;1.9089&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust (-O3)&lt;/td&gt;
&lt;td&gt;2.3265&lt;/td&gt;
&lt;td&gt;4.2560&lt;/td&gt;
&lt;td&gt;2.1320&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript (V8)&lt;/td&gt;
&lt;td&gt;3.5835&lt;/td&gt;
&lt;td&gt;6.6564&lt;/td&gt;
&lt;td&gt;3.5851&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;93.164&lt;/td&gt;
&lt;td&gt;164.890&lt;/td&gt;
&lt;td&gt;98.378&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Python para N = 10⁶ foi descartado — tempo estimado superior a &lt;strong&gt;10 horas&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Hierarquia:&lt;/strong&gt; &lt;code&gt;C -O3 ≈ C++ -O3 &amp;lt; Rust &amp;lt; JavaScript ≪ Python&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  📊 Resultados — Insertion Sort
&lt;/h2&gt;

&lt;p&gt;Aqui a adaptatividade brilhou. No cenário crescente com N = 10⁶, todas as linguagens terminaram em &lt;strong&gt;menos de 12 ms&lt;/strong&gt;. Já no cenário decrescente, o pior caso quadrático foi brutal:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N = 10⁵ — tempo em segundos (-O3 / otimização máxima)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Linguagem&lt;/th&gt;
&lt;th&gt;Crescente (s)&lt;/th&gt;
&lt;th&gt;Aleatório (s)&lt;/th&gt;
&lt;th&gt;Decrescente (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C (-O3)&lt;/td&gt;
&lt;td&gt;0.000055&lt;/td&gt;
&lt;td&gt;0.615683&lt;/td&gt;
&lt;td&gt;1.188966&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++ (-O3)&lt;/td&gt;
&lt;td&gt;0.0000634&lt;/td&gt;
&lt;td&gt;0.587483&lt;/td&gt;
&lt;td&gt;1.183000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust (-O3)&lt;/td&gt;
&lt;td&gt;0.000079&lt;/td&gt;
&lt;td&gt;0.897895&lt;/td&gt;
&lt;td&gt;1.774292&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript (V8)&lt;/td&gt;
&lt;td&gt;0.000809&lt;/td&gt;
&lt;td&gt;1.525250&lt;/td&gt;
&lt;td&gt;3.033301&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;0.005321&lt;/td&gt;
&lt;td&gt;136.295&lt;/td&gt;
&lt;td&gt;226.560&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Para N = 10⁶ no pior caso sem otimização, C++ chegou a &lt;strong&gt;3670 s&lt;/strong&gt; (~1 hora). Com &lt;code&gt;-O3&lt;/code&gt;, caiu para &lt;strong&gt;119 s&lt;/strong&gt; — speedup de &lt;strong&gt;~30×&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  📊 Resultados — Gnome Sort
&lt;/h2&gt;

&lt;p&gt;O Gnome Sort trouxe a maior surpresa da série: &lt;strong&gt;Rust superou C e C++ no caso médio&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N = 10⁵ — tempo em segundos (-O3 / otimização máxima)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Linguagem&lt;/th&gt;
&lt;th&gt;Crescente (s)&lt;/th&gt;
&lt;th&gt;Aleatório (s)&lt;/th&gt;
&lt;th&gt;Decrescente (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C (-O3)&lt;/td&gt;
&lt;td&gt;0.000179&lt;/td&gt;
&lt;td&gt;15.19068&lt;/td&gt;
&lt;td&gt;28.90668&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++ (-O3)&lt;/td&gt;
&lt;td&gt;0.000159&lt;/td&gt;
&lt;td&gt;13.96807&lt;/td&gt;
&lt;td&gt;28.25787&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust (-O3)&lt;/td&gt;
&lt;td&gt;0.000049&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.94810&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8.27646&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript (V8)&lt;/td&gt;
&lt;td&gt;0.001584&lt;/td&gt;
&lt;td&gt;13.90908&lt;/td&gt;
&lt;td&gt;27.45163&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;0.019030&lt;/td&gt;
&lt;td&gt;21.28324&lt;/td&gt;
&lt;td&gt;257.00624&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Por quê? O padrão de acesso do Gnome Sort — muitos acessos locais e trocas adjacentes — se beneficia especialmente das otimizações do compilador LLVM (backend do Rust), que gera código de swap em registrador sem acesso intermediário à memória.&lt;/p&gt;


&lt;h2&gt;
  
  
  📊 Resultados — Bubble Sort
&lt;/h2&gt;

&lt;p&gt;O Bubble Sort entregou o resultado mais inesperado de todo o projeto:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N = 10⁵ — tempo em segundos (-O3 / otimização máxima)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Linguagem&lt;/th&gt;
&lt;th&gt;Crescente (s)&lt;/th&gt;
&lt;th&gt;Aleatório (s)&lt;/th&gt;
&lt;th&gt;Decrescente (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C (-O3)&lt;/td&gt;
&lt;td&gt;0.000042&lt;/td&gt;
&lt;td&gt;20.489569&lt;/td&gt;
&lt;td&gt;23.568626&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++ (-O3)&lt;/td&gt;
&lt;td&gt;0.000045&lt;/td&gt;
&lt;td&gt;21.165759&lt;/td&gt;
&lt;td&gt;23.919268&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust (-O3)&lt;/td&gt;
&lt;td&gt;0.000051&lt;/td&gt;
&lt;td&gt;13.513529&lt;/td&gt;
&lt;td&gt;9.231813&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript (V8)&lt;/td&gt;
&lt;td&gt;0.001753&lt;/td&gt;
&lt;td&gt;15.012168&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;6.905683&lt;/strong&gt; 🎉&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;0.003504&lt;/td&gt;
&lt;td&gt;312.509064&lt;/td&gt;
&lt;td&gt;403.412438&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;JavaScript bateu C e C++ no pior caso.&lt;/strong&gt; O motor V8 identificou o padrão repetitivo de trocas adjacentes e gerou código de máquina altamente especializado via JIT. É um caso raro onde a compilação dinâmica supera a compilação estática.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔑 Principais Aprendizados
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Otimização de compilador importa muito mais do que parece
&lt;/h3&gt;

&lt;p&gt;O impacto de &lt;code&gt;-O3&lt;/code&gt; vs &lt;code&gt;-O0&lt;/code&gt; para Rust no Bubble Sort chegou a &lt;strong&gt;23×&lt;/strong&gt; para N = 10⁴. Em modo debug, o Rust mantém verificações de &lt;em&gt;bounds checking&lt;/em&gt; em todo acesso ao array — correto para desenvolvimento, devastador para performance.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Adaptatividade é real e mensurável
&lt;/h3&gt;

&lt;p&gt;Insertion Sort com N = 10⁶ no cenário crescente: &lt;strong&gt;&amp;lt; 1 ms&lt;/strong&gt;. No cenário decrescente: &lt;strong&gt;até 3670 s&lt;/strong&gt; (sem otimização). Isso é uma diferença de &lt;strong&gt;mais de 10 ordens de magnitude&lt;/strong&gt; no número de operações.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Python tem overhead estrutural, não só de interpretador
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;list&lt;/code&gt; do Python armazena referências a objetos &lt;code&gt;PyObject&lt;/code&gt; — cada acesso e comparação envolve uma indireção de ponteiro. Isso multiplica o custo por operação mesmo para tipos simples como &lt;code&gt;int&lt;/code&gt; e &lt;code&gt;float&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. JIT pode superar código estático em padrões repetitivos
&lt;/h3&gt;

&lt;p&gt;O V8 observa o comportamento em runtime e especializa o código gerado. Para algoritmos com padrões de acesso altamente previsíveis (como Bubble Sort), isso pode ser mais eficiente que otimizações estáticas conservadoras de um compilador AOT.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. A hierarquia não é fixa
&lt;/h3&gt;

&lt;p&gt;A ordem geral foi &lt;code&gt;C ≈ C++ &amp;lt; Rust &amp;lt; JS &amp;lt; Python&lt;/code&gt;, mas exceções importantes existem — Rust venceu todos no Gnome Sort, JS venceu todos no Bubble Sort em pior caso. &lt;strong&gt;O melhor resultado depende do algoritmo, tamanho de entrada e padrão de acesso.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🔬 Conclusão
&lt;/h2&gt;

&lt;p&gt;Algoritmos simples ensinam mais do que complexidade assintótica. Ensinam sobre a relação entre padrões de acesso à memória e otimizações de compilador, sobre como compilação JIT funciona na prática, e sobre por que constantes importam tanto quanto expoentes para tamanhos reais de entrada.&lt;/p&gt;

&lt;p&gt;Se você quiser explorar o código completo, estrutura de Makefiles, geradores de dataset e scripts de benchmark, o repositório está público no GitHub.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Bernardo-Lebron" rel="noopener noreferrer"&gt;
        Bernardo-Lebron
      &lt;/a&gt; / &lt;a href="https://github.com/Bernardo-Lebron/simple_sort_algorithms" rel="noopener noreferrer"&gt;
        simple_sort_algorithms
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/83736464/589653029-919963f1-5b07-4d12-8862-191073dde33c.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Nzg5MDcxNjEsIm5iZiI6MTc3ODkwNjg2MSwicGF0aCI6Ii84MzczNjQ2NC81ODk2NTMwMjktOTE5OTYzZjEtNWIwNy00ZDEyLTg4NjItMTkxMDczZGRlMzNjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA1MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNTE2VDA0NDc0MVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTMwNDljNzQwYmE4YjYyOThjNDIxYWQzMTQ0ZjhhZTg4MzgzYjNhMjg5Y2NkOTljODlkMjYyMmM3YjVkN2I0NGYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.jqNvjYdizcKoz6BqC4brPZiPiPGeXO-vV3SvOq8Cjv4"&gt;&lt;img width="1200" height="300" alt="image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F83736464%2F589653029-919963f1-5b07-4d12-8862-191073dde33c.png%3Fjwt%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Nzg5MDcxNjEsIm5iZiI6MTc3ODkwNjg2MSwicGF0aCI6Ii84MzczNjQ2NC81ODk2NTMwMjktOTE5OTYzZjEtNWIwNy00ZDEyLTg4NjItMTkxMDczZGRlMzNjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA1MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNTE2VDA0NDc0MVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTMwNDljNzQwYmE4YjYyOThjNDIxYWQzMTQ0ZjhhZTg4MzgzYjNhMjg5Y2NkOTljODlkMjYyMmM3YjVkN2I0NGYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.jqNvjYdizcKoz6BqC4brPZiPiPGeXO-vV3SvOq8Cjv4" class="js-gh-image-fallback"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Comparativo de Desempenho: Algoritmos de Ordenação Simples&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Este repositório contém um ambiente de benchmarking experimental para analisar e comparar o desempenho de quatro algoritmos de ordenação simples: &lt;strong&gt;Selection Sort&lt;/strong&gt;, &lt;strong&gt;Insertion Sort&lt;/strong&gt;, &lt;strong&gt;Gnome Sort&lt;/strong&gt; e &lt;strong&gt;Bubble Sort&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Os algoritmos são implementados em múltiplas linguagens de programação e avaliados sob diferentes tamanhos de entrada e cenários de ordenação, com o objetivo de verificar empiricamente as previsões teóricas de complexidade computacional.&lt;/p&gt;

&lt;p&gt;Trabalho prático da disciplina de &lt;strong&gt;Algoritmos e Estruturas de Dados I&lt;/strong&gt;
&lt;strong&gt;CEFET-MG — Campus V, Divinópolis&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📋 Sumário&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;O que são Métodos de Ordenação?&lt;/li&gt;
&lt;li&gt;Contextualização dos Algoritmos Simples&lt;/li&gt;
&lt;li&gt;Objetivos&lt;/li&gt;
&lt;li&gt;Estrutura do Projeto&lt;/li&gt;
&lt;li&gt;Algoritmos Analisados
&lt;ul&gt;
&lt;li&gt;5.1. Selection Sort&lt;/li&gt;
&lt;li&gt;5.2. Insertion Sort&lt;/li&gt;
&lt;li&gt;5.3. Gnome Sort&lt;/li&gt;
&lt;li&gt;5.4. Bubble Sort&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Metodologia Experimental&lt;/li&gt;
&lt;li&gt;Equipe e Colaboradores&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 1. O que são Métodos de Ordenação?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Métodos de ordenação são algoritmos computacionais utilizados para reorganizar os elementos de uma estrutura de dados segundo uma ordem determinada…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Bernardo-Lebron/simple_sort_algorithms" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;&lt;em&gt;Trabalho prático da disciplina de Algoritmos e Estruturas de Dados I — CEFET-MG Campus V, Divinópolis. Orientação: Prof. Michel Pires.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>javascript</category>
      <category>rust</category>
    </item>
    <item>
      <title>Purple Tree 3 - A Personal Wiki</title>
      <dc:creator>John Allsup</dc:creator>
      <pubDate>Sat, 16 May 2026 04:29:50 +0000</pubDate>
      <link>https://dev.to/johnallsup/purple-tree-3-a-personal-wiki-4o8</link>
      <guid>https://dev.to/johnallsup/purple-tree-3-a-personal-wiki-4o8</guid>
      <description>&lt;p&gt;I want to explain the ideas of my personal Wiki, Purple Tree 3 (see johnallsup on github). It was written largely from the ground up, with no frameworks, in PHP (backend) and Javascript (frontend). It uses Parsedown to turn markdown into HTML. It wraps Parsedown in a preprocessor, and a postprocessor to turn 'computational poohsticks' (random strings that Parsedown passes through verbatim, usually generated via a hash of the input) back into whatever was hashed into that poohstick. (Basically you form a PHP array where the hash is the key and the protected content is the value.)&lt;/p&gt;

&lt;p&gt;Anybody interested. Source on Github.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnallsup" rel="noopener noreferrer"&gt;
        johnallsup
      &lt;/a&gt; / &lt;a href="https://github.com/johnallsup/purple-tree-3" rel="noopener noreferrer"&gt;
        purple-tree-3
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Purple Tree 3, a Wiki system with hierarchical directory structure, capable of managing many subdomains with a single instance.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Purple Tree 3&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;by John D. Allsup&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Purple Tree 3 is the third iteration of the wiki system I use to
organise much of my notes and online presence. It is relatively
simple, under 10,000 lines of PHP and a under 10,000 lines
of Javascript. It uses no frameworks, and a small amount
of third party code. The only &lt;em&gt;necessary&lt;/em&gt; third party dependency
is Parsedown, which converts Markdown into HTML
The wiki then uses a wrapper class called PTMD which
turns WikiWords into links, and also allows fenced blocks
to be given special interpretations, something of which
I make copious use.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;History&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The first Wiki system I used was called WabiSabi, which
I used to build my first Wiki, called TheWikiMan. Over
a time, I hacked more and more features into it, until
it became cumbersome.&lt;/p&gt;
&lt;p&gt;Sometime in July 2021 I decided to try my hand at making
Youtube coding…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnallsup/purple-tree-3" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>php</category>
      <category>javascript</category>
      <category>wiki</category>
    </item>
    <item>
      <title>Hi Dev.to, I'm Leo — I build free client-side tools and run 20+ sites</title>
      <dc:creator>Leo Harrison</dc:creator>
      <pubDate>Sat, 16 May 2026 03:55:02 +0000</pubDate>
      <link>https://dev.to/leoharrison/hi-devto-im-leo-i-build-free-client-side-tools-and-run-20-sites-1ma2</link>
      <guid>https://dev.to/leoharrison/hi-devto-im-leo-i-build-free-client-side-tools-and-run-20-sites-1ma2</guid>
      <description>&lt;p&gt;Hey everyone,&lt;/p&gt;

&lt;p&gt;First post here. Thought I'd introduce myself properly.&lt;/p&gt;

&lt;p&gt;I'm an indie maker. I build free web tools — the kind you need for 30 seconds and don't want to create an account for. JSON formatting, Base64 encoding, QR code generation, regex testing... the little stuff developers reach for every day.&lt;/p&gt;

&lt;p&gt;My main project right now is Aggregation Tool (&lt;a href="https://aggtool.xyz" rel="noopener noreferrer"&gt;https://aggtool.xyz&lt;/a&gt;) — 100+ utilities in one place. I built it because every time I Googled "json formatter" I'd land on a site with 15 banner ads, a cookie consent popup, and a "sign up for pro" modal before I could even paste my code. I got fed up and made my own.&lt;/p&gt;

&lt;p&gt;Everything runs client-side. No data leaves your browser. No backend. No database. No tracking. Pure vanilla JavaScript — no React, no frameworks, no build step. Just edit the file and refresh.&lt;/p&gt;

&lt;p&gt;I've got 20+ other sites running too, each one a small, focused tool. No team. No funding. Just me, a text editor, and a lot of late nights.&lt;/p&gt;

&lt;p&gt;I'll be posting here about what I'm building, what I'm learning, and honestly — what's not working. I'm also here to get roasted on my UI decisions and hear what tools you wish existed but don't.&lt;/p&gt;

&lt;p&gt;If you're into indie making, vanilla JS, or just want to say hi, drop a comment. Happy to connect.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Leo&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Text Case Converter: The Complete Guide to camelCase, snake_case, kebab-case and More</title>
      <dc:creator>Harun Mahmud</dc:creator>
      <pubDate>Sat, 16 May 2026 03:47:09 +0000</pubDate>
      <link>https://dev.to/harun_mahmud_88/text-case-converter-the-complete-guide-to-camelcase-snakecase-kebab-case-and-more-2f0o</link>
      <guid>https://dev.to/harun_mahmud_88/text-case-converter-the-complete-guide-to-camelcase-snakecase-kebab-case-and-more-2f0o</guid>
      <description>&lt;p&gt;Every developer has been there — you copy a variable name from one codebase and it's in the wrong case for your project. Or you're converting a database column name to a JavaScript variable. Or you need to turn a human-readable label into a URL slug.&lt;/p&gt;

&lt;p&gt;Text case conversion is one of those small tasks you do dozens of times a day. Here's a complete guide to every case format and when to use each one.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Most Common Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  camelCase
&lt;/h3&gt;

&lt;p&gt;Words are joined together, first word lowercase, subsequent words capitalized.&lt;br&gt;
helloWorld&lt;br&gt;
firstName&lt;br&gt;
getUserById&lt;br&gt;
myVariableName&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Used for:&lt;/strong&gt; JavaScript/TypeScript variables, function names, object properties, JSON keys.&lt;/p&gt;




&lt;h3&gt;
  
  
  PascalCase (UpperCamelCase)
&lt;/h3&gt;

&lt;p&gt;Same as camelCase but the first letter is also capitalized.&lt;br&gt;
HelloWorld&lt;br&gt;
FirstName&lt;br&gt;
GetUserById&lt;br&gt;
MyComponent&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Used for:&lt;/strong&gt; React components, TypeScript interfaces, class names, constructors.&lt;/p&gt;




&lt;h3&gt;
  
  
  snake_case
&lt;/h3&gt;

&lt;p&gt;Words are separated by underscores, all lowercase.&lt;br&gt;
hello_world&lt;br&gt;
first_name&lt;br&gt;
get_user_by_id&lt;br&gt;
my_variable_name&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Used for:&lt;/strong&gt; Python variables, database column names, Ruby, file names in some projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  SCREAMING_SNAKE_CASE
&lt;/h3&gt;

&lt;p&gt;All uppercase with underscores.&lt;br&gt;
HELLO_WORLD&lt;br&gt;
MAX_RETRY_COUNT&lt;br&gt;
API_BASE_URL&lt;br&gt;
DATABASE_HOST&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Used for:&lt;/strong&gt; Constants, environment variables, config values.&lt;/p&gt;




&lt;h3&gt;
  
  
  kebab-case
&lt;/h3&gt;

&lt;p&gt;Words separated by hyphens, all lowercase.&lt;br&gt;
hello-world&lt;br&gt;
first-name&lt;br&gt;
get-user-by-id&lt;br&gt;
my-component&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Used for:&lt;/strong&gt; CSS class names, HTML attributes, URL slugs, file names, CLI flags.&lt;/p&gt;




&lt;h3&gt;
  
  
  Title Case
&lt;/h3&gt;

&lt;p&gt;Each word starts with a capital letter.&lt;br&gt;
Hello World&lt;br&gt;
First Name&lt;br&gt;
Get User By Id&lt;br&gt;
My Variable Name&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Used for:&lt;/strong&gt; Page titles, headings, button labels, UI text.&lt;/p&gt;




&lt;h3&gt;
  
  
  dot.case
&lt;/h3&gt;

&lt;p&gt;Words separated by dots, all lowercase.&lt;br&gt;
hello.world&lt;br&gt;
first.name&lt;br&gt;
config.database.host&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Used for:&lt;/strong&gt; Config file keys, logging namespaces, some API response formats.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Case&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Common Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;camelCase&lt;/td&gt;
&lt;td&gt;&lt;code&gt;myVariable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JS variables, JSON keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PascalCase&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MyComponent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Classes, React components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;snake_case&lt;/td&gt;
&lt;td&gt;&lt;code&gt;my_variable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Python, databases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SCREAMING_SNAKE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MY_CONSTANT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Constants, env vars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kebab-case&lt;/td&gt;
&lt;td&gt;&lt;code&gt;my-variable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CSS, URLs, HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Title Case&lt;/td&gt;
&lt;td&gt;&lt;code&gt;My Variable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;UI labels, headings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dot.case&lt;/td&gt;
&lt;td&gt;&lt;code&gt;my.variable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Config, namespaces&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How to Convert in JavaScript
&lt;/h2&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;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// to camelCase&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;camel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s(&lt;/span&gt;&lt;span class="sr"&gt;.&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// "helloWorldExample"&lt;/span&gt;

&lt;span class="c1"&gt;// to PascalCase&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pascal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;^&lt;/span&gt;&lt;span class="se"&gt;\w&lt;/span&gt;&lt;span class="sr"&gt;|&lt;/span&gt;&lt;span class="se"&gt;\s\w)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// "HelloWorldExample"&lt;/span&gt;

&lt;span class="c1"&gt;// to snake_case&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;snake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&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="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// "hello_world_example"&lt;/span&gt;

&lt;span class="c1"&gt;// to kebab-case&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kebab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&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="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// "hello-world-example"&lt;/span&gt;

&lt;span class="c1"&gt;// to SCREAMING_SNAKE_CASE&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;screaming&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&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="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// "HELLO_WORLD_EXAMPLE"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How to Convert in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world example&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# to snake_case
&lt;/span&gt;&lt;span class="n"&gt;snake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# "hello_world_example"
&lt;/span&gt;
&lt;span class="c1"&gt;# to kebab-case
&lt;/span&gt;&lt;span class="n"&gt;kebab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# "hello-world-example"
&lt;/span&gt;
&lt;span class="c1"&gt;# to PascalCase
&lt;/span&gt;&lt;span class="n"&gt;pascal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;# "HelloWorldExample"
&lt;/span&gt;
&lt;span class="c1"&gt;# to camelCase
&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;camel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;words&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="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt;
&lt;span class="c1"&gt;# "helloWorldExample"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Stop Converting Manually
&lt;/h2&gt;

&lt;p&gt;Writing a one-off conversion function every time gets old fast. A dedicated tool lets you paste any text and instantly see all formats side by side — camelCase, PascalCase, snake_case, kebab-case, SCREAMING_SNAKE, Title Case, dot.case and more in one click.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://toolscraft.io/text-case" rel="noopener noreferrer"&gt;ToolsCraft Text Case Converter&lt;/a&gt; — paste any text, convert to any case instantly. Free, works in your browser, no account needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  When You're Working Across Languages
&lt;/h2&gt;

&lt;p&gt;The case confusion gets worse when you're working across different parts of a stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your &lt;strong&gt;database&lt;/strong&gt; uses &lt;code&gt;snake_case&lt;/code&gt; columns&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;API response&lt;/strong&gt; uses &lt;code&gt;camelCase&lt;/code&gt; JSON keys
&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;CSS&lt;/strong&gt; uses &lt;code&gt;kebab-case&lt;/code&gt; classes&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;constants&lt;/strong&gt; use &lt;code&gt;SCREAMING_SNAKE_CASE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;React components&lt;/strong&gt; use &lt;code&gt;PascalCase&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All from the same underlying concept — just named differently depending on where it lives. A quick converter saves you the mental overhead of doing it by hand every time.&lt;/p&gt;




&lt;p&gt;Which case format trips you up most often when switching between languages or frameworks? Drop it in the comments 👇&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>Arrays in Programming Explained Simply — DSA for Beginners</title>
      <dc:creator>Ankit Maheshwari</dc:creator>
      <pubDate>Sat, 16 May 2026 02:30:00 +0000</pubDate>
      <link>https://dev.to/bitveen/arrays-in-programming-explained-simply-dsa-for-beginners-349g</link>
      <guid>https://dev.to/bitveen/arrays-in-programming-explained-simply-dsa-for-beginners-349g</guid>
      <description>&lt;p&gt;The &lt;strong&gt;array&lt;/strong&gt; is the most fundamental data structure in programming. Almost every complex structure — stacks, queues, heaps — is built on top of arrays internally.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 What is an Array?
&lt;/h2&gt;

&lt;p&gt;An array stores elements in &lt;strong&gt;continuous memory locations&lt;/strong&gt;, each accessible by an index starting at 0.&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;fruits&lt;/span&gt; &lt;span class="o"&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;Apple&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;Banana&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;Eggs&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;Juice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="c1"&gt;// fruits[0] = 'Apple', fruits[2] = 'Eggs'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you want Eggs → directly go to index 2. No searching. That's the power of arrays.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ⚡ How Arrays Work Internally
&lt;/h2&gt;

&lt;p&gt;Arrays are stored in &lt;strong&gt;contiguous memory&lt;/strong&gt;. This is why &lt;strong&gt;random access is O(1)&lt;/strong&gt; — the computer calculates the address directly: base + (index × element_size).&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 Key Operations &amp;amp; Complexity
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Access arr[i]&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;Direct memory jump&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search for value&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;td&gt;Must check each element&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert at end&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;Append to last slot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert at middle&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;td&gt;Must shift all elements right&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete at middle&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;td&gt;Must shift all elements left&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  💻 Common Array Operations in JavaScript
&lt;/h2&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;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;  &lt;span class="c1"&gt;// 30 — O(1)&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// O(1) — insert at end&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unshift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// O(n) — shifts everything&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;            &lt;span class="c1"&gt;// O(1) — delete last&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// O(n) — linear scan&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚠️ When NOT to Use Arrays
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Frequent middle inserts/deletes → Use Linked List&lt;/li&gt;
&lt;li&gt;Key-value lookups → Use Hash Map&lt;/li&gt;
&lt;li&gt;LIFO operations → Use Stack&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Part 3 of the Bitveen DSA Series. Originally published at &lt;a href="https://www.bitveen.com/blog-3-understanding-arrays-the-simplest-data-structure/" rel="noopener noreferrer"&gt;bitveen.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dsa</category>
      <category>programming</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building Toon Tone: A Browser-Based Color Matching Game with HSB Sliders</title>
      <dc:creator>Emily digiplanPro</dc:creator>
      <pubDate>Sat, 16 May 2026 02:27:40 +0000</pubDate>
      <link>https://dev.to/emily_digiplanpro_63dd13f/building-toon-tone-a-browser-based-color-matching-game-with-hsb-sliders-18g0</link>
      <guid>https://dev.to/emily_digiplanpro_63dd13f/building-toon-tone-a-browser-based-color-matching-game-with-hsb-sliders-18g0</guid>
      <description>&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%2F3ze6a3cd2m0aximkb9n8.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%2F3ze6a3cd2m0aximkb9n8.png" alt=" " width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Building Toon Tone: A Browser-Based Color Matching Game with HSB Sliders
&lt;/h1&gt;

&lt;p&gt;I recently built a small browser game called &lt;strong&gt;Toon Tone&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can try it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://toontone.work/" rel="noopener noreferrer"&gt;https://toontone.work/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Toon Tone is a simple color matching game. The player sees a target color and tries to recreate it by adjusting three sliders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hue&lt;/li&gt;
&lt;li&gt;Saturation&lt;/li&gt;
&lt;li&gt;Brightness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After submitting a guess, the game calculates how close the selected color is to the target color and gives the player a score. Each game has 10 rounds.&lt;/p&gt;

&lt;p&gt;The concept is simple, but building it was a good reminder that even small browser games require a lot of product and implementation decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Original Idea
&lt;/h2&gt;

&lt;p&gt;The first idea was more visual.&lt;/p&gt;

&lt;p&gt;I wanted Toon Tone to be a cartoon-style color memory game. A player would see a cute character, remember the color of one part of the character, such as a hoodie, hat, or accessory, and then recreate that color with sliders.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Remember the hoodie color.&lt;br&gt;&lt;br&gt;
Now match it from memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounded more unique than a normal color tool, but the asset workflow became complicated very quickly.&lt;/p&gt;

&lt;p&gt;To make a character-based version work, I needed layered image assets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A base character image&lt;/li&gt;
&lt;li&gt;A mask for the color-changing area&lt;/li&gt;
&lt;li&gt;A shading or highlight layer&lt;/li&gt;
&lt;li&gt;Perfect alignment between all layers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the mask and shading layers were even slightly misaligned, the result looked broken. SVG was easier to control, but the generated characters often looked too rough. PNG illustrations looked better, but separating and aligning layers took too much time.&lt;/p&gt;

&lt;p&gt;So I decided to simplify the first version.&lt;/p&gt;

&lt;p&gt;Instead of starting with characters, I built a pure color card version first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Start With Color Cards?
&lt;/h2&gt;

&lt;p&gt;The main goal of the MVP was to test the core game loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Show a target color&lt;/li&gt;
&lt;li&gt;Let the user adjust the sliders&lt;/li&gt;
&lt;li&gt;Preview the selected color in real time&lt;/li&gt;
&lt;li&gt;Submit the guess&lt;/li&gt;
&lt;li&gt;Calculate a score&lt;/li&gt;
&lt;li&gt;Move to the next round&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This version removed the hardest visual production problems and helped me focus on the actual gameplay.&lt;/p&gt;

&lt;p&gt;The questions I wanted to answer were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is matching colors fun?&lt;/li&gt;
&lt;li&gt;Are HSB sliders intuitive?&lt;/li&gt;
&lt;li&gt;Is 10 rounds the right length?&lt;/li&gt;
&lt;li&gt;Does scoring create replay value?&lt;/li&gt;
&lt;li&gt;Does the game work well on mobile?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those questions felt more important than solving character asset layers too early.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why HSB Instead of RGB?
&lt;/h2&gt;

&lt;p&gt;I chose HSB controls because they feel more natural for a casual color matching game.&lt;/p&gt;

&lt;p&gt;RGB is useful for developers, but it can feel technical for general users. If you ask a player to adjust red, green, and blue values directly, the experience quickly becomes less intuitive.&lt;/p&gt;

&lt;p&gt;HSB is easier to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hue&lt;/strong&gt; changes the color family.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saturation&lt;/strong&gt; changes how intense or muted the color is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Brightness&lt;/strong&gt; changes how light or dark the color appears.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the game easier to play without requiring color theory knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  HSB to RGB Conversion
&lt;/h2&gt;

&lt;p&gt;The sliders control HSB values, but the browser needs RGB or HEX values to display colors.&lt;/p&gt;

&lt;p&gt;Here is a simplified version of the conversion logic:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
ts
type HSB = {
  h: number; // 0 - 360
  s: number; // 0 - 100
  b: number; // 0 - 100
};

type RGB = {
  r: number;
  g: number;
  b: number;
};

function hsbToRgb({ h, s, b }: HSB): RGB {
  s /= 100;
  b /= 100;

  const k = (n: number) =&amp;gt; (n + h / 60) % 6;
  const f = (n: number) =&amp;gt;
    b - b * s * Math.max(Math.min(k(n), 4 - k(n), 1), 0);

  return {
    r: Math.round(255 * f(5)),
    g: Math.round(255 * f(3)),
    b: Math.round(255 * f(1)),
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
