<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: David Fagbuyiro</title>
    <description>The latest articles on Forem by David Fagbuyiro (@davidking).</description>
    <link>https://forem.com/davidking</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F781505%2F90ca56d2-ec46-4726-bd99-760cd6039530.jpg</url>
      <title>Forem: David Fagbuyiro</title>
      <link>https://forem.com/davidking</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/davidking"/>
    <language>en</language>
    <item>
      <title>How AI Agents Are Changing the Future of Web Scraping</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Sun, 12 Oct 2025 13:53:57 +0000</pubDate>
      <link>https://forem.com/davidking/how-ai-agents-are-changing-the-future-of-web-scraping-21di</link>
      <guid>https://forem.com/davidking/how-ai-agents-are-changing-the-future-of-web-scraping-21di</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%2F0267n3kzgfe6wtue1diu.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%2F0267n3kzgfe6wtue1diu.png" alt="Future of Web Scraping" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In today’s world of data collection, smart AI agents are changing how web scraping works. Instead of using fixed scripts that stop working when a webpage changes, these agents can think, understand, and adjust, making data extraction stronger, more accurate, and smarter. &lt;/p&gt;

&lt;p&gt;In this article, we examine how these ing paradigms and solutions like &lt;a href="https://www.olostep.com/" rel="noopener noreferrer"&gt;OloStep&lt;/a&gt; are capitalizing on agents as they shift.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Static Scrapers to Adaptive Agents
&lt;/h2&gt;

&lt;p&gt;Traditional web scrapers are built on fixed rules and selectors. They expect pages to follow consistent HTML structures and often fail when sites update. Autonomous agents instead observe patterns, reason about structure, perform corrective actions, and recover from failures. They can decide when to click a “load more” button or when to scroll further. They can detect missing fields or empty responses and retry or choose an alternate path.&lt;br&gt;
Because these agents act based on high-level goals rather than brittle scripts, they can survive changes in page layout and dynamic content more gracefully. They are more robust to JavaScript rendering, infinite scroll, asynchronous loading, and unexpected content shifts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Web Scraping Matters for AI Agents
&lt;/h2&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%2F5tqvj0hl81v2i5m1pxb0.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%2F5tqvj0hl81v2i5m1pxb0.png" alt="Why Web Scraping Matters for AI Agents" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI agents need fresh data. They cannot operate solely on training data or outdated snapshots. Scraped web data gives them the real-time sight and sound of the internet. It enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sensing changing prices, new product listings, or shifts in sentiment&lt;/li&gt;
&lt;li&gt;Validating assumptions with live examples&lt;/li&gt;
&lt;li&gt;Triggering downstream workflows or actions based on updated facts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Autonomous agents transform web scraping from a background utility into a primary component. The faster the data the more intelligent the agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  How OloStep Enables Smarter Agents
&lt;/h2&gt;

&lt;p&gt;&lt;a href="//docs.olostep.com"&gt;OloStep&lt;/a&gt; presents itself as a unified web data API built for AI and research agents. It supports crawling, parsing, routing, automation, and workflows behind the scenes. It exposes features such as click and form fill, distributed infrastructure, and parsing engines. OloStep also maintains low latency, typically between two and six seconds by combining optimized infrastructure and logic.&lt;/p&gt;

&lt;p&gt;Additionally, OloStep enables agents to reason about which pages to crawl, which subpages to explore, and how to filter results. Agents using OloStep do not need to manage the plumbing of proxies, anti-blocking measures, or parser maintenance. The agent issues high-level commands, and OloStep handles extraction, cleaning, formatting, and delivery.&lt;/p&gt;

&lt;p&gt;Because OloStep converts websites into structured outputs and enables agents to build higher-level workflows, it transforms the web into a real-time database usable by agents and applications. In effect, OloStep abstracts away the messy details, allowing agents to focus on reasoning and decision-making.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Capabilities of Autonomous Scraping Agents
&lt;/h2&gt;

&lt;p&gt;Here are several capabilities that distinguish modern scraping agents:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Goal driven workflows&lt;/strong&gt;&lt;br&gt;
Agents receive intents such as “collect top 100 product listings for brand X” and orchestrate multiple steps, including crawling, filtering, login, pagination, and error recovery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic adaptation&lt;/strong&gt;&lt;br&gt;
When a page fails, when elements shift, agents can detect anomalies, adjust selectors, or pivot strategies rather than fail outright.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Self improvement&lt;/strong&gt;&lt;br&gt;
Some agents can learn reusable “skills” (for example how to navigate a site or extract tables) and refine their library over time ([arXiv][4]). As agents accrue experience they become faster and more accurate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaborative human-agent control&lt;/strong&gt;&lt;br&gt;
In edge cases agents may defer to human review or allow human override, improving reliability and trust ([arXiv][5]).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability across domains&lt;/strong&gt;&lt;br&gt;
Because agents reason rather than rely on hand-coded rules they can scale across many websites, domains, languages, and content types.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Challenges and Ethical Considerations
&lt;/h2&gt;

&lt;p&gt;Despite their promise these agents face real challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sites fight back. Measures like CAPTCHAs, bot detection systems and active blocking make scraping harder.&lt;/li&gt;
&lt;li&gt;Changes in site licensing, terms of service, or robot policies require agents to follow legal and ethical constraints.&lt;/li&gt;
&lt;li&gt;Agent hallucination or misbehavior risk exists when agents misinterpret content or take unintended actions.&lt;/li&gt;
&lt;li&gt;Infrastructure cost grows when agents operate at scale across many domains.&lt;/li&gt;
&lt;li&gt;Maintaining agent safety, monitoring, auditability and human oversight becomes essential.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Moreover, the arms race continues: as agents get smarter, websites will adopt more advanced defenses, including behavioral heuristics or dynamic content injection.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future Landscape
&lt;/h2&gt;

&lt;p&gt;Looking ahead, autonomous agents will become a core layer of the web. The concept of a Web of Agents (where agents interact, collaborate, and request services from each other) is already being theorized in academia. In that world, web scraping capabilities will be internalized: agents will query agent services to fetch fresh data rather than building their own scrapers.&lt;/p&gt;

&lt;p&gt;Hybrid systems will dominate. Agents will issue goals while robust scraping platforms like OloStep serve as the reliable data backbone. Agents will compose skills, reuse parsing modules, coordinate across domains, and even negotiate data contracts.&lt;/p&gt;

&lt;p&gt;We will also see specialization. Some agents will focus on financial use cases, while others will concentrate on market monitoring, brand protection, compliance, or social listening. Each will lean on tailored scraping stacks behind the scenes.&lt;/p&gt;

&lt;p&gt;As agents evolve, the boundary between crawling, searching, and reasoning will become increasingly blurred. The future is a world where agents not only read the web but also act on it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web</category>
      <category>scraper</category>
      <category>data</category>
    </item>
    <item>
      <title>Boosting Developer Productivity: How Qodo Gen IDE Extension Transforms Coding Practices</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Sun, 06 Oct 2024 17:55:14 +0000</pubDate>
      <link>https://forem.com/davidking/boosting-developer-productivity-how-qodo-gen-ide-extension-transforms-coding-practices-g8m</link>
      <guid>https://forem.com/davidking/boosting-developer-productivity-how-qodo-gen-ide-extension-transforms-coding-practices-g8m</guid>
      <description>&lt;p&gt;Efficiency is key to the rapidity of modern development. A developer would always be in search of any tooling that can provide the ability to write cleaner code with speed and not compromise on quality. &lt;/p&gt;

&lt;p&gt;This article will showcase how to boost developer productivity with the help of the &lt;a href="https://www.qodo.ai/" rel="noopener noreferrer"&gt;Qodo Gen&lt;/a&gt; IDE extension on both explaining existing codes and also improving your codes directly in your code editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges Developers Face in Modern Coding
&lt;/h2&gt;

&lt;p&gt;In modern times, software development faces developers with various challenges that disrupt the process of progression at work and, therefore, productive levels. Following are some of the major challenges being faced nowadays:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repetitive Processing&lt;/strong&gt;: Much development time is spent by developers on writing boilerplate code, which is repetitive and sometimes boring. This leaves them with less time to spend on complex and creative tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Difficulty Debugging&lt;/strong&gt;: Debugging is a time-consuming activity, mainly in projects that are huge and have complicated codebases. Having to track down the source of bugs, especially in multi-layered applications, can be frustrating and kill progress.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Managing Code Consistency and Quality&lt;/strong&gt;: Quality and consistency across and within teams are a challenge to ensure. Code reviews, best practice enforcement, and style guide maintenance are usually additional tasks developers need to worry about.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Context Switching&lt;/strong&gt;: Many times, developers need to switch contexts amongst various tasks, tools, and frameworks. Each context switch is painful: focus gets lost, productivity suffers, and errors occur.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Such challenges can take a big bite out of the productivity of a developer and hence contribute to burnout. It is, therefore, absolutely necessary to have tools at hand that streamline workflows and reduce friction. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Qodo Gen IDE Extension?
&lt;/h2&gt;

&lt;p&gt;Qodo Gen is a developer solution powered by artificial intelligence for prominently writing, testing, and reviewing code. It provides its solutions via integrations with the most-used IDEs, like VSCode and JetBrains, to automate development processes that create meaningful tests for your code and edge cases or improve code quality in general.&lt;/p&gt;

&lt;p&gt;Unlike the general code completion tool, Qodo Gen is set on "code integrity," meaning it assists developers in ensuring that the code performs the work it is supposed to do while finding issues or making the code robust. Then comes automated test generation, behavior-specific tests, and the ability to customize tests in a way that best suits your project's needs. The AI can also help with smart code completion, PR reviews, and debugging, among other things.&lt;/p&gt;

&lt;p&gt;Qodo Gen provides support for a wide range of programming languages, hence is versatile to developers working in different environments. The uniqueness of Qodo Gen lies in its ability to parallelize and chain prompts with ease into a range of test cases, giving deep insights into potential vulnerabilities that may lie in code. It can be installed with just a few steps.&lt;/p&gt;

&lt;p&gt;The process of installation is very user-friendly and can be done in very few steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation from the marketplace
&lt;/h3&gt;

&lt;p&gt;Open your IDE marketplace and type Qodo Gen as shown in the image below, or click this &lt;a href="https://marketplace.visualstudio.com/items?itemName=Codium.codium" rel="noopener noreferrer"&gt;link&lt;/a&gt;. Then click Install and follow the setup processes.&lt;/p&gt;

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

&lt;p&gt;Currently, the Qodo Gen can work with programming languages, and advanced features are periodically introduced to support new versions of IDE.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd7o0b7h5yt4u1xl1xwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd7o0b7h5yt4u1xl1xwh.png" alt="Image description" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Qodo Gen is characterized by a plethora of functionalities that tackle the typical pain areas in any coding endeavors, that is why it can greatly enhance productivity:&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/ask&lt;/code&gt;: This allows you to ask free format questions concerning your code. This is a feature that can prove useful in resolving certain code problems directly in the IDE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/quick-test&lt;/code&gt;: It creates automatically unit tests for the particular parts of the code marked. In particular, this is a great help while writing test cases which can be a tiresome process considering the repetitive tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/explain&lt;/code&gt;: Involves providing a straightforward and plain English description of the code including its application with examples. This is especially helpful with one’s intent having a robust logic structure or working with colleagues who may not be in the same page with some of the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/enhance&lt;/code&gt;: Improves and beautifies codes making sure that it is clean, efficient and easy to read. This feature is very useful in the preservation of code quality, compliance with the rules and procedures for best coding practices conformed to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/docstring&lt;/code&gt;: This feature introduces automatic generation of the docstrings for every class, function or a method available in the code. Appropriate writing of the documentation serves the intended interpretation of the code and makes the work of the following developers in regard to the structure of the code and its relevance effortless.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/find-on-github&lt;/code&gt;: It enables you to search for public sources of codes located on github that have relevancy with the code that you have written. Thus helping people with ideas to source references for usual codes or coding solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;/test-suite&lt;/strong&gt;: Performs advanced behavior analysis and generates comprehensive unit test suites for your project. This feature enhances testing coverage and ensures edge cases are handled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;/improve&lt;/strong&gt;: Offers suggestions for improving various aspects of your code to create a more robust and optimized codebase. It’s a great tool for code refactoring and performance improvements.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These features combine to offer a powerful toolkit for developers, especially for enhancing code quality, &lt;a href="https://www.qodo.ai/features/run-tests/" rel="noopener noreferrer"&gt;generating tests&lt;/a&gt;, and promoting seamless collaboration within a development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Qodo Gen help improve the outcomes of a developer
&lt;/h2&gt;

&lt;p&gt;Extra productivity is achieved in coding practices through Qodo Gen by taking care of common operational-oriented tasks.  Practically reduces the amount of naive work that is meant to generate code by providing the form of such generation, eliminating the extra time wasted on mere activities and enabling them to tackle more intricate problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Code Generation
&lt;/h3&gt;

&lt;p&gt;Through usage of Qodo Gen devices, sequences and patterns that normally fall within monolithic templates are socially constructed freeing a significant portion of the developers’ time from such bare routine and mundane activities. They pay less time to synthesis of the routine aspects of the systems since more properties will be catered during the senior interactions of the system.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Context-Aware Suggestions
&lt;/h3&gt;

&lt;p&gt;The extension feeds you with appropriate suggestions to further enhance the quality of the code depending on where you are in the system or what you are currently working on. It is able to understand what you are editing and provide intelligent completion of the code along with suggestions that lead to faster and more accurate code writing with minimal errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactoring and Improving
&lt;/h3&gt;

&lt;p&gt;Processes such as structural restructuring are often readily achieved with software such as Qodo Gen which will replicate complex templates across a big coding population without requiring intensive human involvement. The embedded tools for aid towards elimination or &lt;a href="https://www.qodo.ai/products/ide-plugin/file-mode/improve/" rel="noopener noreferrer"&gt;modification of incorrect portions&lt;/a&gt; within the code also help in dealing with this, they are efficient allowing code quality strictness without decreasing the productivity of the practice.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Code Explanation with Qodo
&lt;/h3&gt;

&lt;p&gt;The features of the Qodo Gen IDE extension do not only assist in the writing and generation of code but also aid in comprehension by providing smart code explanations. When a coder hovers over a particular part of the code or when he selects particular statements of the code, Qodo Gen can expound on the logic and explain comprehensively so much more than the code, thus enhancing understanding and cleanup works.&lt;/p&gt;

&lt;p&gt;This feature comes in quite handy especially when developing complex functions which is why as a developer, you would desire to micromanage while debugging, Qodo would assist in elucidating on every component:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Qodo Gen vs Copilot
&lt;/h2&gt;

&lt;p&gt;Here is a comparison between Qodo Gen and GitHub Copilot based on their core features and capabilities:&lt;br&gt;
Here’s a more natural, human-like revision of your text with a conversational tone:&lt;/p&gt;




&lt;h3&gt;
  
  
  Capabilities Comparison: &lt;strong&gt;Qodo Gen&lt;/strong&gt; vs. &lt;strong&gt;GitHub Copilot&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Qodo Gen&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Main Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Primarily centered on generating tests, improving code quality, and assisting with refactoring.&lt;/td&gt;
&lt;td&gt;Specializes in code completion, inline suggestions, and auto-generating syntax while coding.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Automated Test Generation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes—creates thorough test suites, including edge cases and behavioral tests.&lt;/td&gt;
&lt;td&gt;Not directly—although it can suggest test templates based on existing code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code Awareness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Reviewing the entire codebase and providing valuable suggestions for refactoring and testing.&lt;/td&gt;
&lt;td&gt;"Code completion and suggestions are available, but limited to the current file and its context.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code Completion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Get instant, specific code completion that fits your testing requirements.&lt;/td&gt;
&lt;td&gt;Offers inline suggestions and code completion based on comments and code structure.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Collaboration Tools&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Includes features like code reviews, version control, and team collaboration tools built-in.&lt;/td&gt;
&lt;td&gt;Lacks direct collaboration tools—requires integration with external platforms for this.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Debugging Help&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Integrated debugging tools that help spot and resolve issues within the code.&lt;/td&gt;
&lt;td&gt;Limited—suggests code fixes based on patterns but doesn’t offer in-depth debugging assistance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Customization Options&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Highly customizable for test generation, code standards, and specific project needs.&lt;/td&gt;
&lt;td&gt;Offers limited customization—mainly focuses on code completion using common coding patterns.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supported Languages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Supports all major languages with specialized test generation features.&lt;/td&gt;
&lt;td&gt;Covers multiple languages but focuses heavily on JavaScript, Python, TypeScript, and Go.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Refactoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;It provides advanced tools to reorganize and maintain uniformity in your code.&lt;/td&gt;
&lt;td&gt;Basic code completion—doesn't offer dedicated refactoring capabilities.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Availability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Available as a plugin for VSCode, JetBrains, and other IDEs.&lt;/td&gt;
&lt;td&gt;Also available as an extension for VSCode, JetBrains, and a few other editors.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free for individual use, with a paid plan for larger enterprises coming soon.&lt;/td&gt;
&lt;td&gt;Subscription-based pricing (with options for individual and team plans).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;Qodo Gen focuses on enhancing test coverage and code integrity and making team collaboration tools. It excels at automating testing and helping maintain robust, error-free code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is Qodo Gen Preferred in the Context of Usability and Functional Scope?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Consolidation of Multiple Capabilities in One Extension: Qodo Gen is an intuitive extension that incorporates at least four major elements: code generation, debugging, code refactoring, and team work. This cuts down the need to install several extensions once again streamlining the work of developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy to Use: The extension smoothly plugs into leading IDEs without altering the development environment, thus providing good user experience and performance throughout the development lifecycle, including and especially complicated projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customization: Qodo Gen provides the user with the ability to tailor the extensions enhance functionality in line with his or her preferred luck and the projects107 style; this diversity cannot be said of the other tools possible exceptions notwithstanding.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Qodo Gen IDE extension dramatically changes the way of coding by auto performing boring tasks, suggesting code where it is needed and making things easier for the users for example like in refactoring as well as debugging. It contains an advanced set of tools which boosts the performance of an individual as well as enhances teamwork efficiency among the developers’ teams. On the other hand, Qodo Gen is not a regular extension, and it is rather universal in a way that it decreases the amount of plugins needed and instead allows developers concentrate on granular problem solutions instead of the tools.&lt;/p&gt;

&lt;p&gt;Because of reducing difficult processes and getting help at every stage of the development cycle, Qodo Gen helps to complete coding faster, better and more efficiently.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>Comparing React Mutative vs. React Immer</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Sat, 24 Aug 2024 15:07:07 +0000</pubDate>
      <link>https://forem.com/davidking/-comparing-react-mutative-vs-react-immer-4m3h</link>
      <guid>https://forem.com/davidking/-comparing-react-mutative-vs-react-immer-4m3h</guid>
      <description>&lt;p&gt;Managing &lt;a href="https://legacy.reactjs.org/docs/state-and-lifecycle.html" rel="noopener noreferrer"&gt;state&lt;/a&gt; in &lt;a href="https://legacy.reactjs.org/docs/getting-started.html" rel="noopener noreferrer"&gt;React&lt;/a&gt; apps is an important part of creating dynamic and responsive user interfaces. Traditionally, developers depended on immutable updates, which produce a new copy of the state with the necessary modifications. While this method provides predictability and facilitates debugging, it may have a performance penalty, particularly when dealing with big or complicated data structures.&lt;/p&gt;

&lt;p&gt;This article covers two popular React frameworks for handling state; React &lt;a href="https://mutative.js.org/" rel="noopener noreferrer"&gt;Mutative&lt;/a&gt; and &lt;a href="https://immerjs.github.io/immer/" rel="noopener noreferrer"&gt;Immer&lt;/a&gt;. Both libraries promote immutability, albeit through distinct means.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of React Mutative
&lt;/h2&gt;

&lt;p&gt;Mutative's implementation is very comparable to that of Immer, although more robust. Mutative handles data more efficiently than Immer and native reducers. According to the Mutative team, this state management solution makes immutable updates easier. It is approximately two to six times faster than an average handcrafted reducer as well as more than 10 times faster than Immer. &lt;br&gt;
Here are some benefits of &lt;a href="https://mutative.js.org/docs/intro/" rel="noopener noreferrer"&gt;Mutative.js&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conciseness: Code becomes more readable and easier to write.&lt;/li&gt;
&lt;li&gt;Performance: This can be faster than manual immutable updates, especially for large data structures.&lt;/li&gt;
&lt;li&gt;Error Reduction: Helps avoid accidental mutations of the state object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, suppose there is a state object that contains a list. We intend to mark the final item on the list as done and then add a new item:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn JavaScript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn React&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn Redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If we were to use regular immutable data updates, we could write it as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextState&lt;/span&gt; &lt;span class="o"&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&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="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn Mutative&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But while using the Mutative, we can write it this way:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mutative&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;nextState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;draft&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;draft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&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="nx"&gt;done&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn Mutative&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is the fundamental use of Mutative, which allows us to implement immutable updates more easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of React Immer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://immerjs.github.io/immer/" rel="noopener noreferrer"&gt;Immer&lt;/a&gt;, which means always in German, is a little package that makes working with an immutable state more convenient. Winner of the &lt;a href="https://osawards.com/javascript/" rel="noopener noreferrer"&gt;2019 JavaScript Open Source Award&lt;/a&gt; for "Most impactful contribution".&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of React Immer
&lt;/h3&gt;

&lt;p&gt;These benefits tend to be attained by ensuring you always create an edited copy of an object, array, or map rather than changing any of its properties. This can make writing code very difficult, and it's simple to break such restrictions unintentionally. Through the resolution of these issues, Immer will assist you in adhering to the immutable data approach. Here are some benefits of React Immer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Immer will report an error if it detects an unintentional mutation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Immer eliminates the requirement for the customary boilerplate code required when creating deep modifications to immutable objects. Without Immer, object duplicates must be made by hand at all levels. Typically, by doing a large number of... spread operations. When utilizing Immer, modifications are made to a draft object, which records them and creates the appropriate duplicates without changing the original object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Immer does not require you to master certain APIs or data structures to profit from the paradigm. Immer allows you to access plain JavaScript data structures as well as the well-known mutable JavaScript APIs, all while remaining secure.&lt;/p&gt;
&lt;h3&gt;
  
  
  Code Examples
&lt;/h3&gt;

&lt;p&gt;below is a simple example for a quick comparison:&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baseState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn JavaScript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Try Immer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;p&gt;Assume we have the previous base state, and we need to update the second todo and add a third one. However, we do not want to change the original baseState and avoid deep cloning (to maintain the first todo).&lt;/p&gt;
&lt;h3&gt;
  
  
  Without Immer
&lt;/h3&gt;

&lt;p&gt;Without Immer, maintaining immutability requires us to copy every impacted level of the state object.&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;baseState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// shallow clone the array&lt;/span&gt;
&lt;span class="nx"&gt;nextState&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// replace element 1...&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;nextState&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;// with a shallow clone of element 1&lt;/span&gt;
&lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// ...combined with the desired update&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//Since nextState was freshly cloned, using push is safe here,&lt;/span&gt;
&lt;span class="c1"&gt;// but doing the same thing at any arbitrary time in the future would&lt;/span&gt;
&lt;span class="c1"&gt;// violate the immutability principles and introduce a bug!&lt;/span&gt;
&lt;span class="nx"&gt;nextState&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tweet about it&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;
  
  
  With Immer
&lt;/h3&gt;

&lt;p&gt;Immer simplifies this process. We can use the generate function, which takes as its first argument the state we wish to start in, and as its second parameter a function called the recipe, which is handed a &lt;code&gt;draft&lt;/code&gt; to which we can apply simple modifications. Once the recipe is complete, the mutations are recorded and used to create the next state. generate will handle all of the necessary copying while also protecting the data from future unintentional alterations by freezing it.&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;immer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;const nextState = produce(baseState, draft =&amp;gt; {&lt;br&gt;
    draft[1].done = true&lt;br&gt;
    draft.push({title: "Tweet about it"})&lt;br&gt;
})&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Are you looking for an Immer with React? You are welcome to go directly to the [React + Immer](https://immerjs.github.io/immer/example-setstate) website.
## Core Functionality
Both Mutative and Immer achieve immutable updates in conceptually similar ways, but with key implementation differences that affect performance. Here's a breakdown:
1. **Draft State:** Both libraries create a draft version of the original state object. This draft behaves mostly like the original state, allowing you to write updates as if you were mutating it directly.
2. **Immutability Behind the Scenes:** When you make changes to the draft state, these libraries aren't modifying the original object. Instead, they track the changes you make.
3. **Generating a New State:** Once you're done with your updates in the draft state, Mutative, and Immer use different approaches to create a new, immutable state object reflecting the changes:
* **Mutative**: It leverages a high-performance algorithm to efficiently create a new data structure with the modifications from the draft. This approach prioritizes speed.
* **Immer**: It employs a proxy object that intercepts mutations on the draft and uses that information to construct a completely new, immutable state object. This approach offers more flexibility but can have some performance overhead.
## Performance Comparison
When it comes to raw performance, Mutative reigns supreme over Immer, especially for updates involving large data structures. Here's why:
* Speed Demon: Benchmarks show Mutative can be a staggering 2-6 times faster than writing state updates with traditional reducers and a whopping over 10 times faster than Immer in its default settings.

* Secret Sauce: This speed advantage boils down to how each library creates the final immutable state object. Mutative employs a highly optimized algorithm that efficiently builds a new data structure reflecting the changes you made in the draft, prioritizing raw speed.

* Immer's Overhead: Immer, on the other hand, utilizes a proxy object to track mutations on the draft state. This approach offers more flexibility but comes with an overhead that can significantly slow things down, particularly when dealing with large datasets. It's like adding an extra step in the process.

* Auto-Freeze and the Tradeoff: Immer offers an optional feature called auto-freeze, which helps prevent accidental modifications to the original state. This is great for safety, but it comes at a performance cost. Disabling auto-freeze can bring Immer closer to Mutative's speed, but then you lose the safety net.

Additionally, Immer enables automatic freezing by default as its optimal performance setting. Conversely, if you disable automatic freezing, the performance gap between Immer and Mutative could be as much as several dozen times. We have conducted extensive benchmark tests to confirm this point.

## The Ease of Use Comparison 
Both Mutative and Immer offer an intuitive way to write state updates that appear to mutate the state but ultimately result in immutable updates. However, there are some differences in syntax and potential for errors:
**Syntax Mutative**: Leverages familiar syntax that resembles traditional mutations. You write code as if you're directly modifying the state object.
Example:
```jsx
const draft = createDraft(currentState);
draft.todos.push({ text: 'Buy milk' });
const newState = commit(draft);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Immer Syntax&lt;/strong&gt;: Requires using specific Immer functions like produce to wrap your update logic.&lt;br&gt;
Example:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;draft&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Buy milk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Draft Escapes&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Draft escapes occur when you unintentionally modify the original state object instead of the draft copy in libraries like Mutative and Immer.&lt;br&gt;
&lt;strong&gt;Mutative&lt;/strong&gt;: While Mutative's syntax might feel familiar, there's a higher risk of accidentally modifying the original state object (draft escapes). This can happen if you forget to use the commit function to finalize the changes and create the new state. It requires stricter discipline to ensure all modifications go through the draft.&lt;br&gt;
&lt;strong&gt;Immer&lt;/strong&gt;: Immer's syntax explicitly forces you to work within the draft state using functions like produce. This reduces the chance of accidentally modifying the original state, making it inherently safer.&lt;/p&gt;

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

&lt;p&gt;Auto-Freeze and the Tradeoff: Immer offers an optional feature called auto-freeze, which helps prevent accidental modifications to the original state. This is great for safety, but it comes at a performance cost. Disabling auto-freeze can bring Immer closer to Mutative's speed, but then you lose the safety net.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Comparing DataSpaces and Cloud</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Thu, 22 Aug 2024 09:07:19 +0000</pubDate>
      <link>https://forem.com/davidking/comparing-dataspaces-and-cloud-m2d</link>
      <guid>https://forem.com/davidking/comparing-dataspaces-and-cloud-m2d</guid>
      <description>&lt;h1&gt;
  
  
  Comparing DataSpaces and Cloud
&lt;/h1&gt;

&lt;p&gt;In this article, we will go through what DataSpace is, what cloud is, their importance, and their differences.&lt;/p&gt;

&lt;p&gt;Lets ride on...&lt;/p&gt;

&lt;h2&gt;
  
  
  DataSpaces: An Overview
&lt;/h2&gt;

&lt;p&gt;Dataspaces are decentralized infrastructures that enable data owners to maintain control over their data while still allowing it to be shared and used by others for specific purposes. They are typically based on the following key characteristics and functions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Characteristics of DataSpaces
&lt;/h3&gt;

&lt;p&gt;Below are the key characteristics of DataSpace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data sovereignty&lt;/strong&gt;: Data owners retain control over their data and decide who can access and use it, and for what purposes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and privacy&lt;/strong&gt;: Dataspaces use a variety of security and privacy measures to protect data from unauthorized access, use, or disclosure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency and accountability&lt;/strong&gt;: Dataspaces operate in a transparent and accountable manner, with clear rules and procedures for data sharing and use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interoperability&lt;/strong&gt;: Dataspaces are designed to be interoperable so that data can be easily shared between different dataspaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Functions of DataSpaces
&lt;/h3&gt;

&lt;p&gt;The key functions of dataspaces include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data sharing&lt;/strong&gt;: Dataspaces enable data owners to share their data with others in a secure and controlled manner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data discovery&lt;/strong&gt;: Dataspaces enable data users to discover and access the data they need while protecting the privacy and security of the data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data governance&lt;/strong&gt;: Dataspaces provide mechanisms for governing the sharing and use of data, including defining and enforcing data access policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DataSpaces Use Cases and Applications
&lt;/h3&gt;

&lt;p&gt;Dataspaces can be used in a wide variety of settings, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Business&lt;/strong&gt;: Dataspaces can be used to facilitate data sharing between businesses, for example, to enable new products and services or to improve supply chain efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research&lt;/strong&gt;: Dataspaces can be used to share data between researchers, for example, to accelerate scientific discovery or to develop new medical treatments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Government&lt;/strong&gt;: Dataspaces can be used to share data between government agencies, for example, to improve public services or to combat fraud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gaia-X: An Overview
&lt;/h2&gt;

&lt;p&gt;Gaia-X is a project that aims to create a federated safe data infrastructure for Europe while also ensuring European digital sovereignty. It intends to create digital governance based on European ideals such as transparency, openness, data protection, and security, which can then be applied to cloud technologies to achieve transparency and control over data and services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Gaia-X
&lt;/h3&gt;

&lt;p&gt;Gaia-X offers several benefits, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data sovereignty&lt;/strong&gt;: Gaia-X is designed to give users control over their data, including where it is stored and processed. This is important for businesses and organizations that need to comply with data protection regulations, such as GDPR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency and trust&lt;/strong&gt;: Gaia-X is based on open standards and transparent governance. This means that users can trust that their data is being handled in a secure and compliant manner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interoperability&lt;/strong&gt;: Gaia-X services are designed to be interoperable with each other, making it easy for users to share data and services across different platforms. This can help to reduce costs and improve efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Innovation&lt;/strong&gt;: Gaia-X is a collaborative initiative that is open to all participants. This fosters innovation and the development of new data-driven products and services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Gaia-X Relates to Dataspaces
&lt;/h3&gt;

&lt;p&gt;Dataspaces are a key component of Gaia-X. A dataspace is a trusted environment where data can be shared and exchanged between participants. Gaia-X provides the technical framework and governance model for dataspaces.&lt;/p&gt;

&lt;p&gt;Dataspaces can be created for a variety of purposes, such as to share data within a specific industry or sector, or to support a specific research project. Dataspaces can also be public or private.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Computing: A Comprehensive Look
&lt;/h2&gt;

&lt;p&gt;Cloud computing is a technology that allows users to access and use computing resources over the internet, rather than owning and maintaining physical hardware and software. These computing resources include servers, storage, databases, networking, software, and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Cloud Services (IaaS, PaaS, SaaS)
&lt;/h3&gt;

&lt;p&gt;There are three main types of cloud services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure as a Service (IaaS)&lt;/strong&gt;: IaaS provides the basic building blocks of cloud computing, such as servers, storage, and networking. IaaS customers can deploy and manage their own applications on the provider's infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform as a Service (PaaS)&lt;/strong&gt;: PaaS provides a platform for developing, running, and managing applications. PaaS customers do not need to manage the underlying infrastructure, but they do have some control over the configuration of their applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software as a Service (SaaS)&lt;/strong&gt;: SaaS provides access to software applications over the Internet. SaaS customers do not need to install or manage the applications themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Providers in the Cloud Industry (AWS, Azure, Google Cloud)
&lt;/h3&gt;

&lt;p&gt;The three major cloud providers are Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Platform (GCP). These providers offer a wide range of cloud services, including IaaS, PaaS, and SaaS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS&lt;/strong&gt;: Amazon Web Server is the oldest and most mature cloud provider. It offers the widest range of cloud services and has the largest customer base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure&lt;/strong&gt;: Azure is a close second to AWS in terms of market share. It is well-integrated with Microsoft's on-premises products and services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GCP&lt;/strong&gt;: GCP is the third-largest cloud provider. It is known for its innovative technologies and its focus on open-source software.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Benefits and Limitations of Cloud Computing
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost savings&lt;/strong&gt;: Cloud computing can help businesses save money on IT costs, such as hardware, software, and maintenance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Cloud computing is scalable, meaning that businesses can easily add or remove resources as needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agility&lt;/strong&gt;: Cloud computing can help businesses to be more agile and responsive to change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Reach&lt;/strong&gt;: Cloud computing gives businesses access to global resources, such as data centers and servers located all over the world.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Limitations
&lt;/h4&gt;

&lt;p&gt;However, cloud computing also has some limitations, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Cloud computing security is a major concern for businesses. Businesses need to carefully evaluate the security of their cloud providers and take steps to protect their data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor lock-in&lt;/strong&gt;: Once a business has migrated its applications and data to a cloud provider, it can be difficult and expensive to switch to another provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexity&lt;/strong&gt;: Cloud computing can be complex to manage, especially for businesses with large and complex IT environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Multi-Cloud Environments Overview
&lt;/h3&gt;

&lt;p&gt;A multi-cloud environment uses multiple cloud service providers to meet its computing needs. This can give the organization more flexibility and options but also be more complex to manage. In a multi-cloud environment, workloads can be distributed across clouds based on specific requirements and objectives, such as security, compliance, and cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Cloud Use Cases
&lt;/h3&gt;

&lt;p&gt;Here are some common use cases for multi-cloud environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disaster recovery&lt;/strong&gt;: Multi-cloud can be used to create a disaster recovery plan by replicating applications and data across multiple cloud providers. This way, if there is an outage or disaster with one cloud provider, the organization's applications and data can still be accessed through the other cloud providers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application development and testing&lt;/strong&gt;: Multi-cloud can be used to create a development and testing environment that is separate from the production environment. This can help to improve the quality and reliability of applications by allowing developers to test them in a variety of different environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High availability and performance&lt;/strong&gt;: Multi-cloud can be used to improve the high availability and performance of applications by distributing them across multiple cloud providers. This can help to reduce the risk of outages and to improve the user experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Practices for Multi-Cloud
&lt;/h3&gt;

&lt;p&gt;Here are some best practices for managing a multi-cloud environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Develop a multi-cloud strategy&lt;/strong&gt;: The first step is to develop a multi-cloud strategy that outlines your goals and objectives. This will help you to choose the right cloud providers and services for your specific needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a cloud management platform&lt;/strong&gt;: A cloud management platform can help you to manage your multi-cloud environment more effectively. It can provide you with a single view of all of your cloud resources and can help you automate tasks such as provisioning, deployment, and monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement security and governance policies&lt;/strong&gt;: It is important to implement security and governance policies for your multi-cloud environment. This will help to protect your data and applications from unauthorized access and to ensure that they are used in compliance with your organization's policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparing DataSpaces, Multi-Cloud, and Traditional Cloud
&lt;/h2&gt;

&lt;p&gt;Below is a table that compares DataSpaces to multi-cloud and traditional cloud environments using basic criteria, including data management and storage, scalability, and more.&lt;/p&gt;

&lt;h1&gt;
  
  
  Comparing Dataspaces, Multi-Cloud, and Traditional Cloud
&lt;/h1&gt;

&lt;p&gt;Below is a table that compares DataSpaces to Multi-Cloud and Traditional Cloud environments using basic criteria, including data management and storage, scalability, and more.&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;DataSpaces&lt;/th&gt;
&lt;th&gt;Multi-Cloud&lt;/th&gt;
&lt;th&gt;Traditional Cloud&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Storage and Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dataspaces are a new paradigm for data storage and management that enables organizations to share and collaborate on data without moving it to a central location. Dataspaces are decentralized and federated, meaning that data remains under the control of its owners but can be accessed and processed by authorized users across multiple organizations.&lt;/td&gt;
&lt;td&gt;Multi-cloud environments allow organizations to store and manage their data across multiple cloud providers. This can give organizations more flexibility and choice, as well as the ability to take advantage of the best features and services from each provider. However, managing data across multiple clouds can be complex and challenging, unlike DataSpaces.&lt;/td&gt;
&lt;td&gt;In traditional cloud environments, data is stored and managed on a centralized server farm owned and operated by the cloud provider. This approach is relatively simple to manage, but it can be less flexible and scalable than DataSpaces.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability and Flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dataspaces are highly scalable and flexible. Organizations can add or remove data sources and users at any time without impacting performance or security.&lt;/td&gt;
&lt;td&gt;Multi-cloud environments can also be very scalable and flexible. However, the level of scalability and flexibility will depend on the specific cloud providers and services being used.&lt;/td&gt;
&lt;td&gt;Traditional cloud environments can be less scalable and flexible than other options. This is because organizations are typically limited to the resources available from their chosen cloud provider.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Security and Compliance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dataspaces can provide a high level of data security and compliance. Data is encrypted at rest and in transit, and organizations can retain full control over their data access policies. However, it is important to note that the security of dataspaces will depend on the specific implementation.&lt;/td&gt;
&lt;td&gt;Multi-cloud environments can also provide a high level of data security and compliance. However, it is important to carefully evaluate the security and compliance policies of each cloud provider before using their services.&lt;/td&gt;
&lt;td&gt;Traditional cloud environments can also provide a high level of data security and compliance. However, it is important to note that organizations will need to rely on the cloud provider to protect their data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost Considerations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The cost of dataspaces will vary depending on the specific implementation. However, dataspaces can be a cost-effective way to store and manage data, especially for organizations that need to share data with multiple partners.&lt;/td&gt;
&lt;td&gt;The cost of multi-cloud environments can also vary depending on the specific cloud providers and services that are being used. However, multi-cloud environments can be a cost-effective way to store and manage data, especially for organizations that need to take advantage of the best features and services from each provider.&lt;/td&gt;
&lt;td&gt;The cost of traditional cloud environments is typically more predictable than the cost of dataspaces or multi-cloud environments. However, traditional cloud environments can be more expensive in the long run, especially for organizations that need to store and manage large amounts of data.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Both dataspaces and cloud computing have distinct characteristics that cater to different needs in today's digital landscape. Dataspaces offer greater control, security, and sovereignty over data, making them ideal for organizations with strict data protection requirements. In contrast, cloud computing offers unmatched scalability, flexibility, and cost-efficiency, particularly in multi-cloud environments. Understanding these differences can help organizations make informed decisions about how to manage and share their data effectively.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>database</category>
      <category>data</category>
      <category>comparison</category>
    </item>
    <item>
      <title>Guide to Blockchain Interoperability</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Fri, 14 Jun 2024 18:08:00 +0000</pubDate>
      <link>https://forem.com/davidking/guide-to-blockchain-interoperability-ff8</link>
      <guid>https://forem.com/davidking/guide-to-blockchain-interoperability-ff8</guid>
      <description>&lt;p&gt;Blockchain technology has undoubtedly revolutionized various industries by providing a decentralized and secure platform for transactions and data management. However, as the number of blockchain networks continues to grow, the need for interoperability between these networks becomes increasingly critical. &lt;/p&gt;

&lt;p&gt;In this guide, we'll explore the concept of blockchain interoperability, its importance, challenges, approaches, real-world use cases, future trends, and considerations for developers and businesses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Blockchain Networks
&lt;/h2&gt;

&lt;p&gt;Blockchain networks are decentralized digital ledgers that record transactions in a secure and transparent manner. Examples include Bitcoin, Ethereum, and Hyperledger, each with its own consensus mechanisms and governance structures. However, these networks often operate in isolation, limiting their potential for collaboration and synergy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Blockchain Interoperability?
&lt;/h2&gt;

&lt;p&gt;Blockchain interoperability involves enabling communication and data exchange between disparate blockchain networks. This can take various forms, including protocol-level interoperability, platform interoperability, and cross-chain interoperability. By establishing interoperability standards and protocols, blockchain networks can seamlessly share information and assets, unlocking new possibilities for innovation and value creation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges to Interoperability
&lt;/h2&gt;

&lt;p&gt;Despite its potential benefits, achieving blockchain interoperability presents several challenges. These include scalability issues, disparities in consensus mechanisms, security concerns, and regulatory hurdles. Overcoming these challenges requires innovative solutions and collaboration across the blockchain ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approaches to Achieving Interoperability
&lt;/h2&gt;

&lt;p&gt;Several approaches have been proposed to address the challenges of blockchain interoperability. These include atomic swaps, sidechains, cross-chain communication protocols, and interoperability standards. Projects such as Cosmos, Polkadot, Aion, and Wanchain are pioneering efforts to facilitate interoperability between different blockchain networks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prominent Projects and Initiatives
&lt;/h2&gt;

&lt;p&gt;Cosmos, Polkadot, Aion, and Wanchain are among the leading projects and initiatives focused on blockchain interoperability. These platforms leverage unique architectures and technologies to enable seamless communication and data exchange between disparate blockchain networks, laying the foundation for a more interconnected and interoperable blockchain ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;Blockchain interoperability has numerous real-world applications across various industries. For example, it can facilitate cross-border payments, streamline supply chain management, enable interoperable decentralized finance (DeFi) platforms, and enhance identity management systems. By bridging different blockchain networks, interoperability unlocks new opportunities for efficiency, transparency, and collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Trends and Developments
&lt;/h2&gt;

&lt;p&gt;The future of blockchain interoperability holds significant promise, with ongoing advancements in technology and standards. As interoperability solutions evolve and mature, we can expect to see greater integration between blockchain networks, enhanced scalability, and improved security. These developments will drive further innovation and adoption of blockchain technology across industries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerations for Developers and Businesses
&lt;/h2&gt;

&lt;p&gt;Developers and businesses looking to leverage blockchain interoperability should carefully consider various factors. These include the compatibility of interoperability solutions with existing systems, integration challenges, and the potential risks and opportunities associated with cross-chain transactions. By understanding these considerations, organizations can effectively harness the power of blockchain interoperability to drive innovation and growth.&lt;/p&gt;

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

&lt;p&gt;Blockchain interoperability is a crucial enabler of collaboration, innovation, and value creation in the blockchain ecosystem. By enabling seamless communication and data exchange between disparate blockchain networks, interoperability unlocks new opportunities for efficiency, transparency, and collaboration across industries. As technology advances and standards evolve, the future of blockchain interoperability looks brighter than ever, promising a more interconnected and interoperable blockchain ecosystem for the benefit of all.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>cryptocurrency</category>
      <category>learning</category>
    </item>
    <item>
      <title>Overview of EOS Economics Model</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Wed, 12 Jun 2024 14:23:02 +0000</pubDate>
      <link>https://forem.com/davidking/overview-of-eos-economics-model-1h9f</link>
      <guid>https://forem.com/davidking/overview-of-eos-economics-model-1h9f</guid>
      <description>&lt;h1&gt;
  
  
  Overview of EOS Economics Model
&lt;/h1&gt;

&lt;p&gt;In this article, we'll delve into the key components of the EOS economics model and its implications for the ecosystem.&lt;/p&gt;

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

&lt;p&gt;EOS is a blockchain platform that aims to provide a scalable and user-friendly environment for building and deploying dApps. At the core of EOS is its economics model, which governs how tokens are distributed, resources are allocated, and decisions are made within the network. By understanding the economics of EOS, participants can better navigate the ecosystem and contribute to its growth and sustainability.&lt;/p&gt;

&lt;h2&gt;
  
  
  EOS’s Consensus Algorithm
&lt;/h2&gt;

&lt;p&gt;Consensus algorithms form the backbone of blockchain networks, facilitating agreement among network participants on the validity of transactions and the state of the ledger. EOS's DPoS consensus algorithm is a novel approach to achieving consensus in a decentralized manner, offering scalability and high transaction throughput while maintaining network security.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of DPoS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Scalability: DPoS enables EOS to achieve high transaction throughput compared to traditional Proof of Work (PoW) or Proof of Stake (PoS) consensus algorithms. With a smaller set of block producers and faster block production times, EOS can process a large number of transactions per second.&lt;/li&gt;
&lt;li&gt;Efficiency: The election of block producers through voting ensures that only reputable and competent entities are entrusted with the responsibility of maintaining the network. This leads to more efficient block validation and faster consensus.&lt;/li&gt;
&lt;li&gt;Governance: DPoS facilitates transparent and decentralized governance within the EOS ecosystem. Token holders have the power to vote for block producers and participate in decision-making processes regarding network upgrades and protocol changes.&lt;/li&gt;
&lt;li&gt;## Token Distribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The initial distribution of EOS tokens was conducted through a year-long ICO (Initial Coin Offering), during which 1 billion EOS tokens were made available for purchase. The ICO raised a record-breaking amount, resulting in a diverse and widespread distribution of tokens among investors. Additionally, EOS employs a continuous token inflation model to incentivize block producers and fund network development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3nhbiyygwacf80hivrxh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3nhbiyygwacf80hivrxh.jpeg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An image showing the distribution of EOS tokens during the ICO phase.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Resource Allocation
&lt;/h2&gt;

&lt;p&gt;EOS utilizes a unique resource allocation model to ensure that users have access to the resources they need to interact with the blockchain. This includes RAM allocation for storing data, CPU and network bandwidth for executing transactions, and stake-based voting for participating in network governance. Users can stake their EOS tokens to access resources or lease them from other token holders.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transaction Fees and Block Rewards
&lt;/h2&gt;

&lt;p&gt;Transaction fees on the EOS network are minimal and primarily serve as a spam prevention mechanism rather than a source of revenue for block producers. Instead, block producers are rewarded with newly minted EOS tokens for validating transactions and producing blocks. The distribution of block rewards is designed to incentivize active participation in the network and maintain its security and integrity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxymdi3s9hut5azues5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxymdi3s9hut5azues5h.png" alt="Image description" width="720" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Governance and Referendum
&lt;/h2&gt;

&lt;p&gt;EOS employs a delegated proof-of-stake (DPoS) consensus mechanism, where token holders vote to elect a set of block producers who are responsible for validating transactions and maintaining the network. Token holders also have the power to propose and vote on referendums that govern various aspects of the EOS ecosystem, including protocol upgrades, resource allocation, and community initiatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Economic Sustainability
&lt;/h2&gt;

&lt;p&gt;Ensuring the long-term sustainability of the EOS network is paramount to its success. The economics model of EOS is designed to incentivize developers to build and maintain dApps on the platform, users to engage with these dApps, and stakeholders to actively participate in network governance. However, achieving economic sustainability requires ongoing collaboration, innovation, and adaptation to changing market dynamics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison with Other Blockchain Economics Models
&lt;/h2&gt;

&lt;p&gt;Compared to other blockchain platforms like Ethereum, EOS offers distinct advantages in terms of scalability, resource management, and governance. While Ethereum relies on gas fees to prioritize transactions and compensate miners, EOS provides users with predictable resource costs and minimal transaction fees. Additionally, the delegated governance model of EOS enables more efficient decision-making and protocol upgrades.&lt;/p&gt;

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

&lt;p&gt;The economics model of EOS plays a crucial role in shaping the dynamics of the platform and its ecosystem. By understanding how tokens are distributed, resources are allocated, and decisions are made within the network, participants can effectively navigate the EOS ecosystem and contribute to its growth and sustainability. As EOS continues to evolve, its economics model will play an increasingly important role in driving innovation and adoption within the blockchain industry.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>eos</category>
      <category>economics</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Overview of Blockchain Consensus Algorithms</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Wed, 12 Jun 2024 14:08:48 +0000</pubDate>
      <link>https://forem.com/davidking/overview-of-blockchain-consensus-algorithms-564i</link>
      <guid>https://forem.com/davidking/overview-of-blockchain-consensus-algorithms-564i</guid>
      <description>&lt;p&gt;In this article, we'll delve into various consensus algorithms commonly used in blockchain networks, exploring their characteristics, advantages, and limitations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Blockchain consensus algorithms are protocols that enable nodes in a distributed network to agree on the state of the blockchain. Consensus is achieved through a series of rules and mechanisms that govern how transactions are validated and added to the blockchain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proof of Work (PoW)
&lt;/h2&gt;

&lt;p&gt;Proof of Work is perhaps the most well-known consensus algorithm, famously used by Bitcoin. In PoW, miners compete to solve complex mathematical puzzles to validate transactions and create new blocks. The first miner to solve the puzzle gets to add the block to the blockchain and is rewarded with cryptocurrency.&lt;/p&gt;

&lt;p&gt;PoW ensures network security through computational power, but it also consumes a significant amount of energy. Examples of blockchains utilizing PoW include Bitcoin and Ethereum (although Ethereum is transitioning to Proof of Stake).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfdw2d39gvtb34iy4hnm.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfdw2d39gvtb34iy4hnm.jpeg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An image showing miners engaged in solving cryptographic puzzles to validate transactions and create new blocks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Proof of Stake (PoS)
&lt;/h2&gt;

&lt;p&gt;Proof of Stake is an alternative consensus algorithm where validators are chosen to create new blocks based on the amount of cryptocurrency they hold and are willing to "stake" as collateral. In PoS, validators are incentivized to act honestly because they have a financial stake in the network.&lt;/p&gt;

&lt;p&gt;PoS is more energy-efficient compared to PoW and encourages coin holders to participate in network maintenance. Examples of blockchains utilizing PoS include Cardano and Tezos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delegated Proof of Stake (DPoS)
&lt;/h2&gt;

&lt;p&gt;Delegated Proof of Stake is a variation of PoS where coin holders vote to elect a set number of delegates who are responsible for validating transactions and creating new blocks. DPoS aims to improve scalability and efficiency by delegating consensus to a smaller group of trusted nodes.&lt;/p&gt;

&lt;p&gt;EOS and TRON are prominent examples of blockchains utilizing DPoS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Byzantine Fault Tolerance (PBFT)
&lt;/h2&gt;

&lt;p&gt;Practical Byzantine Fault Tolerance is a consensus algorithm designed to achieve consensus in a distributed system despite the presence of malicious nodes or communication failures. PBFT requires a predetermined number of nodes to agree on the validity of transactions before they are added to the blockchain.&lt;/p&gt;

&lt;p&gt;Hyperledger Fabric is an example of a blockchain platform that utilizes PBFT to achieve consensus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proof of Authority (PoA)
&lt;/h2&gt;

&lt;p&gt;Proof of Authority is a consensus algorithm where validators are identified and authorized to create new blocks based on their reputation or identity. Validators are typically known and trusted entities, which reduces the risk of malicious activity.&lt;/p&gt;

&lt;p&gt;PoA is commonly used in private or consortium blockchains where trust among participants is high. Examples include Quorum and Kovan Ethereum testnet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison of Consensus Algorithms
&lt;/h2&gt;

&lt;p&gt;Each consensus algorithm has its own set of advantages and limitations. Factors such as performance, security, energy consumption, and scalability vary depending on the algorithm used. It's essential to consider these factors when designing or choosing a blockchain network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Emerging Trends and Future Directions
&lt;/h2&gt;

&lt;p&gt;Hybrid consensus models, combining elements of multiple algorithms, are gaining traction as blockchain technology evolves. Research and development efforts continue to explore novel consensus mechanisms that address the shortcomings of existing algorithms and pave the way for greater scalability, security, and efficiency.&lt;/p&gt;

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

&lt;p&gt;As the technology continues to evolve, so too will the consensus algorithms that underpin it, shaping the future of decentralized finance, governance, and beyond.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Increase Your Code Coverage with Cover-Agent</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Thu, 23 May 2024 06:12:57 +0000</pubDate>
      <link>https://forem.com/davidking/increase-your-code-coverage-with-cover-agent-3g0p</link>
      <guid>https://forem.com/davidking/increase-your-code-coverage-with-cover-agent-3g0p</guid>
      <description>&lt;p&gt;Writing strong code is just half the battle.  Are you struggling to ensure your software is thoroughly tested?  Introducing Cover-Agent, the innovative tool that leverages AI to automate test generation and boost your code coverage!&lt;/p&gt;

&lt;p&gt;This article will help you to understand what cover agent is, the benefits, the installation and the process of implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importance of Code Coverage and Testing
&lt;/h2&gt;

&lt;p&gt;Code coverage is a critical metric in software development, indicating the extent to which the source code is tested by the suite of automated tests. High code coverage ensures that most parts of the codebase are executed during testing, which helps identify and eliminate bugs, ensuring the software's reliability and robustness. Effective testing practices contribute to the overall quality, security, and maintainability of the software, reducing the risk of unexpected failures in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges of Achieving High Code Coverage
&lt;/h2&gt;

&lt;p&gt;Despite its importance, achieving high code coverage presents several challenges. Developers often face time constraints, resource limitations, and the complexity of modern software systems. Writing comprehensive tests is a time-consuming task that requires a deep understanding of the codebase. Additionally, certain parts of the code, such as edge cases and error handling paths, can be particularly difficult to cover. These challenges can result in suboptimal coverage and potentially undiscovered bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Why Code Coverage Matters
&lt;/h2&gt;

&lt;p&gt;Imagine building a house without a blueprint or flying a plane without testing its engines.  Software development without thorough testing carries similar risks.  Here's why code coverage is crucial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hidden Bugs: Low code coverage means untested sections of code. These hidden areas are breeding grounds for bugs that can cause crashes, unexpected behavior, and security vulnerabilities.&lt;/li&gt;
&lt;li&gt;Unreliable Software: Software with low coverage might function under ideal conditions, but real-world use involves edge cases and unexpected inputs. Uncovered code is more likely to fail under pressure, leading to frustrated users and potential downtime.&lt;/li&gt;
&lt;li&gt;Maintenance Challenges: Untested code is poorly understood code. Making changes or fixing bugs in these areas becomes a guessing game, increasing development time and costs.
In short, neglecting code coverage is a recipe for disaster.  But achieving high coverage traditionally requires a lot of manual effort...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Risks of Low Code Coverage
&lt;/h3&gt;

&lt;p&gt;Low code coverage can lead to significant risks in software development. Uncovered code segments may harbor undetected bugs, which can result in software crashes, security vulnerabilities, and poor user experiences. These issues can be costly to fix post-release and can damage the reputation of the development team or organization. Furthermore, low coverage may indicate inadequately tested integrations and functionalities, increasing the risk of system failures in real-world usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traditional Methods for Increasing Coverage (Limitations)
&lt;/h3&gt;

&lt;p&gt;Traditional methods for increasing code coverage often involve manual test writing and code reviews. While these methods can be effective, they are typically labor-intensive and time-consuming. Developers must meticulously write tests for various scenarios, which can be prone to human error and oversight. Additionally, maintaining a high level of coverage can become increasingly difficult as the codebase grows and evolves. Automated testing frameworks can help, but they often require significant initial setup and continuous maintenance, which can detract from development time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Cover-Agent: Your AI-Powered Testing Friend
&lt;/h2&gt;

&lt;p&gt;Cover-Agent is an advanced &lt;a href="https://youtu.be/fIYkSEJ4eqE?feature=shared" rel="noopener noreferrer"&gt;AI-powered tool&lt;/a&gt; designed to assist developers in achieving higher code coverage effortlessly. By utilizing sophisticated machine learning techniques, Cover-Agent automatically analyzes the codebase, identifies untested areas, and generates comprehensive test cases. This proactive approach ensures that even the most challenging and overlooked parts of the code are tested, improving overall software quality.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.codium.ai/products/cover-agent/" rel="noopener noreferrer"&gt;Cover-Agent&lt;/a&gt; allows you to easily handle tedious yet critical tasks, such as increasing test coverage. Cover-Agent is at the forefront of integrating state-of-the-art test generation technology, beginning with regression tests, as an open-source project, Cover-Agent continuously strive for improvement and warmly invite contributions to their open-source software.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features and Benefits of Cover-Agent
&lt;/h3&gt;

&lt;p&gt;Below are some of the benefits of Cover-Agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated Test Generation: Cover-Agent excels in &lt;a href="https://www.youtube.com/watch?v=fIYkSEJ4eqE" rel="noopener noreferrer"&gt;automated test generation&lt;/a&gt;, creating a wide range of test cases based on the code's structure and behavior. This automation reduces the manual effort required from developers, allowing them to focus on more complex and creative aspects of development. By systematically targeting untested code, Cover-Agent ensures that no critical functionality is left unexamined.&lt;/li&gt;
&lt;li&gt;Increased Efficiency and Time Savings: One of the primary benefits of Cover-Agent is the significant time savings it offers. By automating the test generation process, developers can achieve high code coverage much faster than traditional methods. This efficiency allows teams to adhere to tight development schedules without compromising on testing rigor. Furthermore, Cover-Agent's integration into the development pipeline ensures continuous coverage improvement with minimal manual intervention.&lt;/li&gt;
&lt;li&gt;Improved Test Quality and Focus: Cover-Agent not only increases the quantity of tests but also enhances their quality. The AI algorithms are designed to create targeted, relevant test cases that focus on critical paths and edge cases within the code. This targeted approach ensures that the most important aspects of the application are thoroughly tested, leading to more robust and reliable software. Additionally, Cover-Agent can adapt to changes in the codebase, continuously updating and refining tests to maintain optimal coverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started with Cover-Agent
&lt;/h2&gt;

&lt;p&gt;Below are the installation step and guide&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation and Usage
&lt;/h3&gt;

&lt;p&gt;Requirements&lt;br&gt;
Before you begin, make sure you have the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OPENAI_API_KEY&lt;/code&gt; set in your environment variables, which is required for calling the OpenAI API.&lt;br&gt;
If running directly from the repository you will also need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python installed on your system.&lt;/li&gt;
&lt;li&gt;Poetry installed for managing Python package dependencies. Installation instructions for Poetry can be found at &lt;a href="https://python-poetry.org/docs/" rel="noopener noreferrer"&gt;https://python-poetry.org/docs/&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Standalone Runtime
&lt;/h3&gt;

&lt;p&gt;The Cover Agent can be installed as a Python Pip package or run as a standalone executable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python Pip&lt;/strong&gt;&lt;br&gt;
To install the Python Pip package directly via GitHub run the following command:&lt;/p&gt;

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

&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Codium&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Binary&lt;/strong&gt;&lt;br&gt;
The binary can be run without any Python environment installed on your system (e.g. within a Docker container that does not contain Python). You can download the release for your system by navigating to the project's release page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository Setup&lt;/strong&gt;&lt;br&gt;
Run the following command to install all the dependencies and run the project from source:&lt;/p&gt;

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

&lt;span class="n"&gt;poetry&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Running the Code&lt;/strong&gt;&lt;br&gt;
After downloading the executable or installing the Pip package you can run the Cover Agent to generate and validate unit tests. Execute it from the command line by using the following command:&lt;/p&gt;

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

&lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;path_to_source_file&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;path_to_test_file&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;path_to_coverage_report&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;test_command_to_run&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;directory_to_run_test_command&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;type_of_coverage_report&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;desired&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;desired_coverage_between_0_and_100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;max_number_of_llm_iterations&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;optional_list_of_files_to_include&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You can use the example projects within this repository to run this code as a test.&lt;/p&gt;

&lt;p&gt;Follow the steps in the README.md file located in the templated_tests/python_fastapi/ directory, then return to the root of the repository and run the following command to add tests to the python fastapi example:&lt;/p&gt;

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

&lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;templated_tests/python_fastapi/app.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;templated_tests/python_fastapi/test_app.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;templated_tests/python_fastapi/coverage.xml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pytest --cov=. --cov-report=xml --cov-report=term&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;templated_tests/python_fastapi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cobertura&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;desired&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;For an example using Go cd into &lt;code&gt;templated_tests/go_webservice&lt;/code&gt;, set up the project following the README.md and then run the following command:&lt;/p&gt;

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

&lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app.go&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app_test.go&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coverage.xml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;go test -coverprofile=coverage.out &amp;amp;&amp;amp; gocov convert coverage.out | gocov-xml &amp;gt; coverage.xml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cobertura&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;desired&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Try and add more tests to this project by running this command at the root of this repository:&lt;/p&gt;

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

&lt;span class="n"&gt;poetry&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cover_agent/main.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tests/test_main.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coverage.xml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;poetry run pytest --junitxml=testLog.xml --cov=templated_tests --cov=cover_agent --cov-report=xml --cov-report=term --log-cli-level=INFO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cobertura&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;desired&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; \
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Note: If you are using Poetry then use the poetry run cover-agent command instead of the cover-agent run command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Outputs
&lt;/h3&gt;

&lt;p&gt;A few debug files will be outputted locally within the repository (that are part of the &lt;code&gt;.gitignore&lt;/code&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generated_prompt.md: The full prompt that is sent to the LLM&lt;/li&gt;
&lt;li&gt;run.log: A copy of the logger that gets dumped to your &lt;code&gt;stdout&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;test_results.html: A results table that contains the following for each generated test:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failure reason (if applicable).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exit code,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;stderr.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;stdout.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generated test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Development
&lt;/h3&gt;

&lt;p&gt;This section discusses the development of this project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Versioning&lt;/strong&gt;&lt;br&gt;
Before merging to main make sure to manually increment the version number in cover_agent/version.txt at the root of the repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Running Tests&lt;/strong&gt;&lt;br&gt;
Set up your development environment by running the poetry install command as you did above.&lt;/p&gt;

&lt;p&gt;Note: for older versions of &lt;code&gt;Poetry&lt;/code&gt; you may need to include the &lt;code&gt;--dev&lt;/code&gt; option to install Dev dependencies.&lt;/p&gt;

&lt;p&gt;After setting up your environment run the following command:&lt;/p&gt;

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

&lt;span class="n"&gt;poetry&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;junitxml&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;testLog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xml&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;cov&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;templated_tests&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;cov&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cover_agent&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;cov&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;xml&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;cov&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This will also generate all logs and output reports that are generated in &lt;code&gt;.github/workflows/ci_pipeline.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Testing
&lt;/h2&gt;

&lt;p&gt;To demonstrate exactly how CodiumAI Cover-Agent functions, we will begin with an easy example. We are going to build a simple calculator.py file with functions for addition, subtraction, multiplication, and division.&lt;/p&gt;

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

&lt;span class="c1"&gt;# calculator.py
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Simple calculator class to perform basic arithmetic operations.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the sum of a and b.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the difference between a and b.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the product of a and b.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the quotient of a and b.

        Raise ValueError if b is zero.
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cannot divide by zero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Next step, Lets write a test file test_calculator.py and place it in the tests folder.&lt;/p&gt;

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

&lt;span class="c1"&gt;# tests/test_calculator.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestCalculator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&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="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;

    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&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="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&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="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;

    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&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="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;

    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&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="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;),&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_divide_by_zero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ZeroDivisionError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="nf"&gt;divide&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;To view the test coverage, we must first install pytest-cov, a pytest extension that reports coverage.&lt;/p&gt;

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

&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cov&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Run the coverage analysis with the below command:&lt;/p&gt;

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

pytest --cov=calculator


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

&lt;/div&gt;

&lt;p&gt;Result:&lt;br&gt;
The test result can be found below:&lt;/p&gt;

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

============================= test session starts ==============================
platform darwin -- Python 3.9.1, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: /path/to/your/project
collected 17 items                                                             

tests/test_calculator.py ................Q                                

============================== warnings summary ===============================
tests/test_calculator.py::TestCalculator::test_divide_by_zero
  /path/to/your/project/tests/test_calculator.py:34: PytestWarning: test_divide_by_zero raised in test (ZeroDivisionError: division by zero)

-- Docs: https://docs.pytest.org/en/stable/warnings.html
====================== 16 passed, 1 warning in 0.08s =======================


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

&lt;/div&gt;

&lt;p&gt;This above result shows all tests passing as expected, including handling the division by zero case correctly with a warning indicating the raised exception. If any tests had failed, &lt;code&gt;pytest&lt;/code&gt; would provide detailed information on the failures, including stack traces and the nature of the assertion failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using CodiumAI Cover-Agent
&lt;/h2&gt;

&lt;p&gt;To set up Codium Cover-Agent, follow the steps below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Cover-Agent&lt;/strong&gt;:&lt;/p&gt;

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

&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Codium&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Ensure &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; is set in your environment variables, as it is required for the OpenAI API.&lt;/p&gt;

&lt;p&gt;Create the command to start generating tests:&lt;/p&gt;

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

&lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;calculator.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tests/test_calculator.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coverage.xml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pytest --cov=. --cov-report=xml --cov-report=term&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;dir&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cobertura&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;desired&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coverage&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;additional&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;instructions&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Since I am using a test class, each line of code (including the first line) needs to be prepended with 4 whitespaces. This is extremely important to ensure that every line returned contains that 4 whitespace indent; otherwise, my code will not run.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Command Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;source-file-path&lt;/strong&gt;: The file path containing the functions that need tests generated for them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;test-file-path&lt;/strong&gt;: The file path where the agent will write the tests. It’s recommended to create a basic structure in this file with at least one test and the necessary import statements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code-coverage-report-path&lt;/strong&gt;: The file path where the code coverage report will be saved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;test-command&lt;/strong&gt;: The command used to run the tests (e.g., pytest).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;test-command-dir&lt;/strong&gt;: The directory where the test command should be executed. Set this to the root directory or the main file location to avoid issues with relative imports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;coverage-type&lt;/strong&gt;: The type of coverage tool to use. Cobertura is a recommended default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;desired-coverage&lt;/strong&gt;: The coverage percentage goal. A higher percentage is better, but achieving 100% is often impractical.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;max-iterations&lt;/strong&gt;: The number of retries the agent should attempt to generate test code. More iterations can increase OpenAI token usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;additional-instructions&lt;/strong&gt;: Prompts to ensure the code adheres to specific requirements, such as formatting the code to work within a test class.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After running the command above, it will generate the code below:&lt;/p&gt;

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

    &lt;span class="c1"&gt;# Tests the addition function with negative input values
&lt;/span&gt;    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_add_negative_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;

    &lt;span class="c1"&gt;# Tests the multiplication function with edge case of one input being zero
&lt;/span&gt;    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_multiply_by_zero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;

    &lt;span class="c1"&gt;# Tests the addition function with negative input values
&lt;/span&gt;    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_add_negative_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;
    &lt;span class="c1"&gt;# Tests the multiplication function with zero as one of the input values
&lt;/span&gt;    &lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a, b, expected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_multiply_by_zero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You can see that the agent also wrote tests for checking errors for edge cases, We can now test the coverage again by using the command below:&lt;/p&gt;

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

&lt;span class="n"&gt;pytest&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;cov&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Result:&lt;/p&gt;

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

&lt;span class="o"&gt;=============================&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="n"&gt;starts&lt;/span&gt; &lt;span class="o"&gt;==============================&lt;/span&gt;
&lt;span class="n"&gt;platform&lt;/span&gt; &lt;span class="n"&gt;linux&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;Python&lt;/span&gt; &lt;span class="mf"&gt;3.8&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="n"&gt;pytest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;7.1&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="n"&gt;py&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.11&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="n"&gt;pluggy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.13&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;rootdir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;
&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;codiumai&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;collected&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;                                                             

&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;test_calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="p"&gt;................&lt;/span&gt;&lt;span class="n"&gt;Q&lt;/span&gt;                                

&lt;span class="o"&gt;==============================&lt;/span&gt; &lt;span class="n"&gt;warnings&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;===============================&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;test_calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TestCalculator&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;test_divide_by_zero&lt;/span&gt;
  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;test_calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PytestWarning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;test_divide_by_zero&lt;/span&gt; &lt;span class="n"&gt;raised&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;test &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ZeroDivisionError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;division&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;Docs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;stable&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;
&lt;span class="o"&gt;======================&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="n"&gt;passed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;warning&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="mf"&gt;0.07&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=======================&lt;/span&gt;


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

&lt;/div&gt;

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

&lt;p&gt;In this straightforward example, we achieved 100% test coverage, for more explanations on bigger code base, you can read on these resources below:&lt;br&gt;
&lt;a href="https://dev.to/akshayballal/supercharge-your-tests-with-codiumai-cover-agent-4j9m"&gt;Devto 1&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Codium-ai/cover-agent/tree/main/cover_agent" rel="noopener noreferrer"&gt;CodiumAI&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/oluwadamisisamuel1/how-to-automate-test-generation-with-ai-using-codiumai-cover-agent-1kep"&gt;Praise&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Don't settle for shaky foundations!  Stop letting untested code lurk in the shadows.  Embrace Cover-Agent and watch your code coverage soar.  With its AI-powered automation and focus on quality, Cover-Agent is the key to building robust, reliable software that inspires confidence.  Start your free trial today and experience the difference Cover-Agent can make in your development process!&lt;/p&gt;

&lt;p&gt;Past article on other &lt;a href="https://dev.to/davidking/comparing-codiumai-pr-agent-to-copilot-for-pull-request-4o01"&gt;CodiumAI tools&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check out the open-source repository for the cover agent at &lt;a href="https://github.com/Codium-ai/cover-agent." rel="noopener noreferrer"&gt;CodiumAI&lt;/a&gt; &lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>productivity</category>
      <category>testing</category>
    </item>
    <item>
      <title>Harnessing Node.js Native File Watching for Enhanced Developer Productivity</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Sun, 12 May 2024 18:33:15 +0000</pubDate>
      <link>https://forem.com/davidking/harnessing-nodejs-native-file-watching-for-enhanced-developer-productivity-fa7</link>
      <guid>https://forem.com/davidking/harnessing-nodejs-native-file-watching-for-enhanced-developer-productivity-fa7</guid>
      <description>&lt;p&gt;Can you imagine a world where your code reflects your edits instantly, where the development feedback loop spins at the speed of light? This is the benefit promised by &lt;a href="https://nodejs.org/api/fs.html" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; native file watching, a potent tool waiting to be unleashed for developer productivity. This article will dive into techniques for file watching in Node.js, exploring strategies for optimizing performance, handling large file systems, and implementing custom file watchers for specific needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of Node.js native file watching
&lt;/h2&gt;

&lt;p&gt;File watching is a fundamental technique for monitoring file system changes and triggering actions accordingly. While Node.js provides the native &lt;code&gt;fs.watch()&lt;/code&gt; method for basic file watching, there are more advanced techniques that can enhance its capabilities and address complex use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of using Node.js native file-watching
&lt;/h2&gt;

&lt;p&gt;Below are the core benefits of using Node.js native file watching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lightweight and efficiency: Being a native module, it avoids the overhead of external libraries, minimizing resource consumption and maximizing performance.&lt;/li&gt;
&lt;li&gt;Cross-platform compatibility: It works seamlessly across major operating systems like Windows, macOS, and Linux, ensuring consistent behavior regardless of your environment.&lt;/li&gt;
&lt;li&gt;Highly customizable: It provides fine-grained control over the watching process, allowing you to specify what types of changes (addition, deletion, or modification) trigger events and the specific files or directories to monitor.&lt;/li&gt;
&lt;li&gt;Event-driven architecture: It leverages Node.js's event loop, enabling asynchronous and non-blocking monitoring, freeing your application from busy waiting and improving responsiveness.&lt;/li&gt;
&lt;li&gt;Reduced complexity: Eliminates the need for external dependencies and their associated installation, configuration, and maintenance, simplifying your development workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common use cases for Node.js native file watching
&lt;/h2&gt;

&lt;p&gt;Below are the common use cases for Node.js native file watching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time file syncing: mirror changes across local and remote filesystems, enabling seamless collaboration and data backup.&lt;/li&gt;
&lt;li&gt;Live reloading: Refresh web pages or applications automatically upon detecting changes in source code, enhancing development agility.&lt;/li&gt;
&lt;li&gt;Log file monitoring: Track application logs in real time for immediate insights into errors and performance issues.&lt;/li&gt;
&lt;li&gt;Media processing: trigger automated tasks like video transcoding or image resizing upon file arrival in a designated folder.&lt;/li&gt;
&lt;li&gt;Build automation: Watch for changes in configuration files or dependencies to trigger automated builds and deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementing live reloading using --watch()
&lt;/h2&gt;

&lt;p&gt;Let's assume you have a file named main.js that you want to keep track of for changes. You can use --watch() to monitor whenever its content changes and notify us. The following step will show a simple step to implement File Watcher and drop a message on the console whenever changes are made to the file. Note: The output reflecting the file changes will only be displayed on the terminal.&lt;/p&gt;

&lt;p&gt;Step 1: Create a file named main.js and run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log("Hello from Femi J!");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Go to your terminal and run the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node main.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the above command, the terminal will display what is in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkx3ptyva6xhr8y6vzddi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkx3ptyva6xhr8y6vzddi.png" alt="Image description" width="800" height="127"&gt;&lt;/a&gt;&lt;br&gt;
If you want to use the new native watch mode, just type the following command in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node --watch main.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can now go ahead to include the below code in your main.js file to see how it reflects the changes in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log("File just changed")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Node is aware that the file has changed and will run it again automatically :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2qsrwzvwm72z80ty312.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2qsrwzvwm72z80ty312.png" alt="Image description" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Live-Reloading with Nodemom
&lt;/h2&gt;

&lt;p&gt;Introducing the dynamic Nodemon here to automate your workflow and improve your productivity. With this tool at your fingertips, you will experience instant feedback, enhanced efficiency, seamless integration, and frontend and backend coverage: Enjoy live updates for both frontend and backend code changes by following the steps below.&lt;/p&gt;

&lt;p&gt;Setting up a Node Server&lt;/p&gt;

&lt;p&gt;You should have Nodejs installed on your machine, then enter the command below to set the directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir nodemons &amp;amp;&amp;amp; cd nodemons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can enter the command below to create a package.json.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to install Express to start a server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you should enter the command below to create an index.js file where the changes will be coming from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now navigate to the index.js file and enter the following lines of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const app = express();
const port = process.env.PORT || 3000

app.get('/', (req, res) =&amp;gt; {
   res.send("Hello World!");
})

app.listen(port, () =&amp;gt; {
   console.log(`App is running at port: ${port}`);
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In line 1, we are just importing the express package for running the server, We are making an app, by initiating the express module, and in line 3, We created a variable for the port that will search for an environment variable named PORT. If it cannot find any port by default, it will then assign &lt;code&gt;port 3000&lt;/code&gt;. In lines 5 to 7, we are just creating a route. So, if a person, sends a get request to /, then he will get Hello World as the response in lines 9 to 11 We are just making the app run and listen on the port variable Now, you could run this app, by simply typing the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above will give the output App is running at &lt;code&gt;port: 3000&lt;/code&gt; Then just go to your browser and type in &lt;code&gt;localhost:3000/&lt;/code&gt; but the disadvantage of this is that if you go to &lt;code&gt;index.js&lt;/code&gt; and change "Hello World!" to "Hello world !, Refresh the browser for changes" but if you go to the browser and reload the page, it will still remain the same stagnant as "Hello world !".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3nye4aunnex0u64pszw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3nye4aunnex0u64pszw.png" alt="Image description" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we have to implement Nodemon by following the steps below.&lt;/p&gt;

&lt;p&gt;Settings up Nodemon for live reloading&lt;/p&gt;

&lt;p&gt;To install nodemon run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install nodemon --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used &lt;code&gt;--save-dev&lt;/code&gt; because we want to only implement it in the development area and not publish it, Now, go to the &lt;code&gt;package.json&lt;/code&gt; file and edit the line: - &lt;code&gt;"test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"&lt;/code&gt; to &lt;code&gt;"start"&lt;/code&gt;:"nodemon index.js" what we just did is that we made nodemon run the server instead of the node. Now, terminate the node server which was running before and run the command below:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You can now go to &lt;code&gt;localhost:3000&lt;/code&gt; and try to change the response in the &lt;code&gt;index.js&lt;/code&gt; and after you save it, the server should auto-reload itself. Then go to the browser and refresh again to see that the new changes have been applied as shown in the gif below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprqnt24ndwyghdrca454.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprqnt24ndwyghdrca454.png" alt="Image description" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Node.js Native File Watching
&lt;/h2&gt;

&lt;p&gt;Below are the steps required to set up your Node.js file-watching&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing the fs.watch() method
&lt;/h3&gt;

&lt;p&gt;Now that we've explored the benefits and potential of Node.js native file watching, let's get our hands on implementing it using the &lt;code&gt;fs.watch()&lt;/code&gt; method. The &lt;code&gt;fs.watch()&lt;/code&gt; method, residing in the fs (file system) module, is your gateway to monitoring changes in files and directories. Its basic syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fs.watch(filename, options, callback);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a breakdown of the key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filename: This is the path to the file or directory you want to watch. You can also use wildcards, like .js to monitor multiple files.&lt;/li&gt;
&lt;li&gt;Options: This is an optional object that allows you to customize the watching behavior.&lt;/li&gt;
&lt;li&gt;Callback: This function gets called whenever a change occurs in the watched file or directory. It receives two arguments, which are called events: This string specifies the type of change, like change,rename, or delete. And the filename: Which is the name of the file or directory that changed. The examples below show how to use the Node.js fs.watch() method.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const msg = "Hello World";
console.log(msg);

const fs = require("fs");

// A Node.js script demonstrating how the fs.watch() method works

fs.watch("nide.txt", (eventType, filename) =&amp;gt; {
  console.log(`\nThe file ${filename} was modified!`);
  console.log(`The type of change was: ${eventType}`);
});

// Renaming the file to a new name
setTimeout(() =&amp;gt; fs.renameSync("nide.txt", "new_file.txt"), 1000);

// This will also Rename the file back to its former name
setTimeout(() =&amp;gt; fs.renameSync("new_file.txt", "nide.txt"), 2000);

// Changing the contents of the file
setTimeout(
  () =&amp;gt; fs.writeFileSync("nide.txt", "The file is modified"),
  3000
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code output will look like the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jxd1dx42ektqh4wqiyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jxd1dx42ektqh4wqiyi.png" alt="Image description" width="539" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the watch options
&lt;/h2&gt;

&lt;p&gt;The options object gives you fine-grained control over your file-watching experience. Here are some noteworthy options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;persistent: Set to true (default) to keep the watcher running even after the callback exits.&lt;/li&gt;
&lt;li&gt;recursive: Set to true to monitor changes in all sub-directories within the watched directory.&lt;/li&gt;
&lt;li&gt;ignored: an array of paths or patterns to exclude from monitoring.&lt;/li&gt;
&lt;li&gt;encoding: Specify the encoding used to read the changed file content (defaults to &lt;code&gt;utf8&lt;/code&gt;).
## Real-Time Code Automation with File Watching
Node.js native file watching isn't just a passive observer; it's a powerful tool to automate repetitive tasks and streamline your development process. Let's see how you can leverage it for real-time code automation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to monitor a file for changes in Node.js
&lt;/h2&gt;

&lt;p&gt;Remember our trusty &lt;code&gt;fs.watch()&lt;/code&gt; method? It's the heart of file-watching. You can use it to monitor single files, directories, or even specific file types. This allows you to trigger actions whenever relevant changes occur, making your workflow significantly more efficient.&lt;/p&gt;

&lt;p&gt;Step 1: Let's first build up a project so we can study the various file-watching options available in Node. To begin with, make a folder and use the terminal to navigate into it.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;Node.js&lt;/code&gt;, use the following command to generate a &lt;code&gt;package.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Installing the log-timestamp package from NPM and adding it to the package's dependencies is the next step.JSON document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save log-timestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;fs.watchfile&lt;/code&gt; command&lt;/p&gt;

&lt;p&gt;The built-in &lt;code&gt;fs-watchFile&lt;/code&gt; method appears to be a logical choice for monitoring changes in our log file. When the file is changed, the callback listener is called. Let's give it a shot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require('fs');
require('log-timestamp');

const buttonPressesLogFile = './button-presses.log';

console.log(`Watching for file changes on ${buttonPressesLogFile}`);

fs.watchFile(buttonPressesLogFile, (curr, prev) =&amp;gt; {
  console.log(`${buttonPressesLogFile} file Changed`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above monitors the file button-presses.log for changes. Whenever the file changes, it will log a message to the console showing that the file has changed. This can be useful for tracking when button presses are logged to the file.&lt;/p&gt;

&lt;p&gt;The code Output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodpe7l0a699umnt1p45p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodpe7l0a699umnt1p45p.png" alt="Image description" width="700" height="92"&gt;&lt;/a&gt;&lt;br&gt;
Here's a breakdown of the potential reasons for the two equal timestamps and their usefulness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initial File Creation: When the code starts, it likely creates the button-presses.log file if it doesn't already exist. Or the file creation itself triggers a change event, leading to the first "file Changed" log with a timestamp. However, since no actual content was modified within the file, the subsequent change events (where content is actually added) might also have the same timestamp, resulting in seemingly identical logs.&lt;/li&gt;
&lt;li&gt;Rapid Changes: If changes to the file occur very quickly, within the same second or millisecond, the timestamps logged might appear identical due to limited time resolution which is more likely if the changes are automated or occur in a burst.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usefulness of Equal Timestamps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highlighting Rapid Changes: The identical timestamps can draw attention to very fast, potentially unexpected modifications to the file, prompting investigation.&lt;/li&gt;
&lt;li&gt;Debugging File Watching Behavior: They can aid in debugging the file watching mechanism itself, revealing potential issues with how changes are detected or logged.&lt;/li&gt;
&lt;li&gt;Understanding Change Patterns: In specific use cases, they might reveal patterns in how the file is being modified, providing insights into system behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Automating repetitive development tasks
&lt;/h2&gt;

&lt;p&gt;Imagine spending hours manually rebuilding your project after every code change. No more! File-watching lets you automate tasks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live reloading: Inject changes into your running application instantly, saving you time and frustration during development.&lt;/li&gt;
&lt;li&gt;Linting and formatting: Automatically run linters and code formatters on saved files, ensuring consistent code quality.&lt;/li&gt;
&lt;li&gt;Unit test execution: trigger unit tests upon file changes, providing immediate feedback on your code's impact.&lt;/li&gt;
&lt;li&gt;Documentation generation: Automatically rebuild documentation when code changes, keeping it up-to-date effortlessly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Integrating file watching with build tools
&lt;/h2&gt;

&lt;p&gt;Popular build tools like Gulp and Grunt integrate seamlessly with Node.js file watching. This lets you leverage the power of both worlds.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define complex workflows: Chain multiple tasks together based on different file changes or events.&lt;/li&gt;
&lt;li&gt;Utilize build tool plugins: access a vast ecosystem of plugins for specific tasks like image optimization or code minification.&lt;/li&gt;
&lt;li&gt;Streamline your build process: eliminate manual intervention and automate repetitive tasks for a smoother development experience. By combining the flexibility of fs.watch() with the power of build tools, you can create robust and automated workflows that adapt to your project's specific needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code Examples&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const gulp = require('gulp');
const fs = require('fs');

// Define the file to watch
const watchFile = 'src/**/*.js';

// Define the build task
function build() {
  // Your build process here (e.g., minifying, transpiling)
  console.log('Building...');
}

// Watch the file for changes and trigger build on change
gulp.task('watch', () =&amp;gt; {
  gulp.watch(watchFile, build);
});

// Default task
gulp.task('default', build);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code Output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs8kc1hnlvh4lnlw7ug3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs8kc1hnlvh4lnlw7ug3z.png" alt="Image description" width="698" height="151"&gt;&lt;/a&gt;&lt;br&gt;
Webpack Example: below is an example to display the with webpack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const webpack = require('webpack');
const chokidar = require('chokidar');

// Define the entry point and output file
const entry = './src/index.js';
const output = './dist/bundle.js';

// Define the webpack config
const config = {
  entry,
  output,
  // ... other webpack config options
};

// Build and watch for changes
const compiler = webpack(config);

const watcher = chokidar.watch('src/**/*.js');

watcher.on('change', () =&amp;gt; {
  console.log('File changed. Rebuilding...');
  compiler.run(() =&amp;gt; {
    console.log('Build completed.');
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code Output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkurgzj9wf9koxizqlg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkurgzj9wf9koxizqlg2.png" alt="Image description" width="602" height="76"&gt;&lt;/a&gt;&lt;br&gt;
Each specific implementation will vary depending on your build tool and needs. However, the general pattern of watching files for changes and triggering a rebuild when necessary remains the same.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enhancing Developer Experience with File Watching
&lt;/h2&gt;

&lt;p&gt;We have explored the technical aspects of Node.js file watching, but how does it translate into real benefits for developers? Let's dive into the ways it can enhance your development experience:&lt;/p&gt;
&lt;h3&gt;
  
  
  Streamlining Code Compilation and Testing
&lt;/h3&gt;

&lt;p&gt;Say goodbye to manual rebuilds; Imagine editing a file and instantly seeing your changes reflected in your running application, thanks to live reloading. No more waiting for lengthy rebuilds; just immediate feedback for faster development cycles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated testing on demand: File watching triggers unit tests automatically upon changes, providing instant feedback on potential regressions or unexpected behavior. Catch bugs early and often, ensuring a more stable and reliable codebase.&lt;/li&gt;
&lt;li&gt;Smart compilation and optimization: Watch for specific file changes to trigger targeted compilation or optimization tasks. There's no need to waste resources recompiling everything; optimize only what's changed, leading to faster build times and improved. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enabling Instant Feedback During Development&lt;br&gt;
Below are the steps to enable instant feedback during your development:&lt;/p&gt;

&lt;p&gt;Live linting and formatting: Get notified instantly about code style violations or formatting inconsistencies as you type. Address issues in real time, keeping your code clean and consistent without sacrificing momentum.&lt;/p&gt;

&lt;p&gt;Automated documentation updates: Link your documentation generation process to file changes. As your code evolves, your documentation automatically reflects the latest updates, saving you time and ensuring accuracy.&lt;/p&gt;

&lt;p&gt;Error detection and logging: Monitor log files for errors in real time. React immediately to critical issues, minimizing downtime and maximizing application stability.&lt;/p&gt;
&lt;h2&gt;
  
  
  Improving Overall Development Workflow
&lt;/h2&gt;

&lt;p&gt;Here is how to improve the overall development workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduced cognitive load: Focus on your code, not the build process. File watching automates repetitive tasks, freeing your mental space for creative problem-solving and deeper thinking.&lt;/li&gt;
&lt;li&gt;Increased productivity: Eliminate the wait time between changes and results. Get instant feedback, iterate quickly, and ship features faster.&lt;/li&gt;
&lt;li&gt;Enhanced collaboration: Share live-reloading environments with teammates. See each other's changes in real time, facilitate discussions, and work together seamlessly. By leveraging Node.js file-watching, you can cultivate a more efficient, productive, and enjoyable development experience. It's not just about technology; it's about empowering you to write better code, faster. So embrace the power of automation and unlock the full potential of your development journey.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Advanced Techniques for File Watching with Code Examples
&lt;/h2&gt;

&lt;p&gt;Let's solidify our understanding by adding some code examples to illustrate the advanced techniques mentioned earlier:&lt;/p&gt;
&lt;h3&gt;
  
  
  Utilizing chokidar for enhanced performance
&lt;/h3&gt;

&lt;p&gt;The Chokidar library supercharges fs.watch() with advanced features and optimizations. Here's what it brings to the table:&lt;/p&gt;

&lt;p&gt;Cross-platform performance: Chokidar is optimized for various operating systems, ensuring consistent and performant watching across different environments.&lt;/p&gt;

&lt;p&gt;Debounced events: It minimizes unnecessary events by grouping changes into batches, preventing your application from being bombarded with updates.&lt;/p&gt;

&lt;p&gt;Glob patterns: You can use powerful globbing patterns to watch specific file types or nested directories with greater precision.&lt;/p&gt;

&lt;p&gt;Ignored paths and custom filters: exclude irrelevant files or directories from being watched, further reducing resource consumption and improving focus.&lt;/p&gt;

&lt;p&gt;Example 1: Watching directories recursively with Chokidar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const chokidar = require('chokidar');

// Define the root directory
const rootDir = '/path/to/root';

chokidar.watch(rootDir, {
  recursive: true, // Watch all subdirectories and files
  persistent: true, // Keep watching even after process restarts
  ignoreInitial: true, // Ignore initial events on startup
  followSymlinks: true, // Watch files even if accessed through symlinks
}).on('add, change', filePath =&amp;gt; {
  console.log(`File changed: ${filePath}`);
  // Perform your desired action here
});

// (Optional) Additional event handling for events like 'unlink', 'ready' etc.

// Keep the process running
process.stdin.resume();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example uses chokidar to watch for changes in .js files within the src directory, excluding the node_modules folder. It utilizes a persistent mode to keep the watcher alive and avoids polling for performance reasons.&lt;/p&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5l354xjwntp3ei0gyh80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5l354xjwntp3ei0gyh80.png" alt="Image description" width="681" height="49"&gt;&lt;/a&gt;&lt;br&gt;
Example 2: Using Chokidar with glob patterns for advanced filtering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const chokidar = require('chokidar');

// Define glob patterns for specific files and directories
const filePatterns = ['*.txt', '*.json'];
const dirPatterns = ['/path/to/dir1', '!**/subdir']; // Include and exclude directories

chokidar.watch(filePatterns, {
  cwd: '/path/to/root', // Set the working directory
  ignoreInitial: true,
  followSymlinks: true,
}).on('add, change', filePath =&amp;gt; {
  console.log(`File changed: ${filePath}`);
  // Perform your desired action here
});

// (Optional) Additional event handling and filtering logic

// Keep the process running
process.stdin.resume();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chokidar watches for file changes (txt, json) in a directory, ignoring subdirs and startup events. It logs changes and lets you handle them.&lt;/p&gt;

&lt;p&gt;The code Output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58pgr9v7wfvt8frtrpq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58pgr9v7wfvt8frtrpq6.png" alt="Image description" width="679" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling large file systems and multiple directories
&lt;/h2&gt;

&lt;p&gt;Watching vast directories or numerous files simultaneously can be daunting. Here's how to handle the challenge:&lt;/p&gt;

&lt;p&gt;Chunked watching: Break down large directories into smaller chunks and watch them individually. This reduces the initial load and improves responsiveness.&lt;/p&gt;

&lt;p&gt;Queued processing: Don't overwhelm your application with immediate processing. Queue file changes events and handles them asynchronously to maintain smooth performance.&lt;/p&gt;

&lt;p&gt;Worker threads: leverage Node.js's worker threads to parallelize file-watching tasks. This distributes the workload efficiently and prevents bottlenecks. Example 1: Watching specific files in multiple directories&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require('fs');

// Define directories and files to watch
const directories = ['/path/to/dir1', '/path/to/dir2', '/path/to/dir3'];
const filesToWatch = ['file1.txt', 'file2.json'];

// Create a watcher for each directory
directories.forEach(dir =&amp;gt; {
  filesToWatch.forEach(file =&amp;gt; {
    const filePath = `${dir}/${file}`;
    fs.watchFile(filePath, (eventType, eventFile) =&amp;gt; {
      if (eventType === 'change' &amp;amp;&amp;amp; eventFile === filePath) {
        console.log(`File changed: ${filePath}`);
        // Perform your desired action here
      }
    });
  });
});

// (Optional) Handle errors
process.on('uncaughtException', error =&amp;gt; {
  console.error(error);
});

// Keep the process running
process.stdin.resume();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This above code monitors files for changes. It tracks directories and files and then sets up watchers for each. If a file changes, it logs and allows you to take custom actions based on the updated data.&lt;/p&gt;

&lt;p&gt;The Output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feilrf1zfpmmphuv0gwb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feilrf1zfpmmphuv0gwb8.png" alt="Image description" width="678" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing custom file watchers for specific needs
&lt;/h2&gt;

&lt;p&gt;Custom file watchers are tools that automate tasks based on changes to specific files or directories. They offer more flexibility and control than built-in file watchers.&lt;/p&gt;

&lt;p&gt;To implement a custom file watcher, you need to define your needs, choose an approach, build the watcher, deploy it, and monitor it.&lt;/p&gt;

&lt;p&gt;Here are some key points to follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use programming languages, system tools, or GUI tools for file-watching.&lt;/li&gt;
&lt;li&gt;Detect events, filter relevant ones, execute actions, and handle errors.&lt;/li&gt;
&lt;li&gt;Deploy the watcher locally, use background services, or containerize it.&lt;/li&gt;
&lt;li&gt;Optimize performance, log events, secure file paths, and handle errors.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fswatch = require('fswatch');

const watcher = fswatch.createWatcher('./logs', {
  filter: (path) =&amp;gt; path.endsWith('.log'),
  interval: 1000, // Debounce events to prevent flooding
});

watcher.on('data', (event) =&amp;gt; {
  console.log(`Log file changed: ${event.file}`);
  // Analyze the log file content
});

watcher.start();

console.log('Watching for changes in log files...');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example utilizes the fswatch library to specifically watch for changes in files ending with .log. It debounces events to avoid overwhelming the system and demonstrates how to handle the event data for custom analysis.&lt;/p&gt;

&lt;p&gt;The Code Output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnizu4vtu9kdlpca72w7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnizu4vtu9kdlpca72w7j.png" alt="Image description" width="698" height="148"&gt;&lt;/a&gt;&lt;br&gt;
Each time a file ending with .log inside the ./logs directory changes, the data event will be emitted with information about the event, including the file path. The console will then log the file name that changed and trigger the analyze function to process the content of the updated log file.&lt;/p&gt;

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

&lt;p&gt;Remember, file watching is not just about watching files; it's about automating repetitive tasks, streamlining your workflow, and ultimately, writing better code with greater agility.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Achieving The Scroll Aware UI State For Better UI Control</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Mon, 19 Feb 2024 11:02:06 +0000</pubDate>
      <link>https://forem.com/davidking/achieving-the-scroll-aware-ui-state-for-better-ui-control-4132</link>
      <guid>https://forem.com/davidking/achieving-the-scroll-aware-ui-state-for-better-ui-control-4132</guid>
      <description>&lt;p&gt;Forget about using JavaScript; this tutorial will show you how to create dynamic, responsive UIs with pure CSS, looking at creative tactics like sticky-components, animation-timeline, and scroll-powered transitions to help you create websites that feel alive and captivate visitors with every click.&lt;/p&gt;

&lt;p&gt;Scroll-aware state, also sometimes called position-aware state or viewport-aware state, refers to a UI design pattern where the state of a component changes dynamically based on the user’s scroll position within the viewport. This means that the content or behavior of the component adapts as the user scrolls up or down the page. Here are some of the key characteristics of a scroll-aware state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reactivity: The component’s state updates automatically in response to changes in the scroll position. This can be achieved through various techniques, like event listeners, Intersection Observer API, or custom scroll detection mechanisms.&lt;/li&gt;
&lt;li&gt;Conditional rendering: Different content or UI elements may be displayed based on the scroll position. For example, a navigation bar might become fixed at the top of the screen when the user scrolls past a certain point, or an infinite scroll might dynamically load new content as the user approaches the bottom of the page.&lt;/li&gt;
&lt;li&gt;Smooth transitions: Ideally, the state changes should occur smoothly and seamlessly, providing a natural and intuitive user experience. Animations and other visual cues can be used to enhance the transition effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits of Using a Scroll-Aware State
&lt;/h2&gt;

&lt;p&gt;There are several benefits to using the scroll-aware state in your UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improved user engagement: By dynamically adapting to the user’s interaction, scroll-aware components can keep users engaged and interested in the content.&lt;/li&gt;
&lt;li&gt;Enhanced navigation and discovery: Scroll-aware state can reveal additional information or functionalities as the user scrolls, promoting exploration and discovery within the UI.&lt;/li&gt;
&lt;li&gt;Efficient resource utilization: With techniques like infinite scrolling, a scroll-aware state can help optimize resource usage by only loading content that is visible to the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CSS vs. JavaScript
&lt;/h2&gt;

&lt;p&gt;Prioritize CSS-only solutions for simple, performant scroll-aware effects that enhance visual appeal and user experience without compromising performance. You choose JavaScript for more intricate animations, advanced features, fine-grained control over timing, and complex interactions that require extensive JavaScript logic. But don’t forget to carefully weigh the trade-offs between performance, complexity, and control to select the most suitable approach for your specific use case. Here’s a comparison of CSS-only and JavaScript solutions for implementing a scroll-aware state, highlighting their advantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS-Only Solutions Advantages
&lt;/h3&gt;

&lt;p&gt;Below are the main advantages of using CSS-only solutions for scroll-aware:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance: CSS-only solutions often outperform JavaScript alternatives for simple scroll-sensitive effects. They leverage browser optimizations for rendering and animations, reducing the workload on the main thread, which leads to smoother interactions and less potential for performance bottlenecks.&lt;/li&gt;
&lt;li&gt;Declarative: CSS is inherently declarative, making the code more readable, maintainable, and easier to reason about. You define the visual states and transitions directly within the stylesheet, separating presentation from behavior.&lt;/li&gt;
&lt;li&gt;No JavaScript overhead: CSS-only solutions don’t require any JavaScript execution, which can benefit initial page load times and reduce overall JavaScript code complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CSS-Only Solution Disadvantages
&lt;/h3&gt;

&lt;p&gt;Below are the disadvantages of using CSS-only solutions for scroll-aware:&lt;/p&gt;

&lt;p&gt;Limited complexity: CSS-only solutions are often constrained to simpler scroll-aware effects. They might not be suitable for intricate animations or advanced interactions that require greater control over timing and logic.&lt;br&gt;
Browser compatibility: some CSS features for scroll-aware effects, like scroll-behavior: smooth or overscroll-behavior, have limited browser support. You might need to consider polyfills or fallbacks for older browsers.&lt;/p&gt;
&lt;h3&gt;
  
  
  JavaScript Solutions Advantages
&lt;/h3&gt;

&lt;p&gt;Below are the advantages of implementing JavaScript solutions for scroll-aware:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexibility: JavaScript offers unparalleled flexibility and control over scroll-aware interactions. You can create highly complex animations, fine-tune timing, and coordinate multiple elements precisely.&lt;/li&gt;
&lt;li&gt;Advanced features: JavaScript allows for features like lazy loading content, tracking scroll progress, triggering actions based on scroll position, implementing parallax effects, creating custom scrollers, and cross-browser compatibility where libraries and frameworks often handle browser inconsistencies to provide consistent experiences across different browsers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  JavaScript Solutions Disadvantages
&lt;/h3&gt;

&lt;p&gt;Below are the disadvantages of implementing JavaScript solutions for scroll-aware:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance overhead: JavaScript execution can impact performance, especially if not optimized carefully, and it is crucial to consider code optimization and avoid excessive DOM manipulation to maintain smooth scrolling.&lt;/li&gt;
&lt;li&gt;Code complexity: JavaScript code for scroll-aware interactions can become complex and harder to maintain, especially for intricate animations or interactions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Implementing Scroll-Aware UI With CSS
&lt;/h2&gt;

&lt;p&gt;The scroll-aware user interface may vary from a simple scroll-snap effect to an element that becomes animated when a user scrolls into view of it or when a user scrapes ahead or backward in direct reaction. There are various approaches to implementing this type of Design structure.&lt;/p&gt;

&lt;p&gt;The most frequent sort of scroll-aware UI is a basic scroll-snap. It is as simple as adding a scroll-snap-type to get this &lt;code&gt;effect: y&lt;/code&gt; or &lt;code&gt;position: fixed one-liner&lt;/code&gt; property to a container to get this result copy the Html codes below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"page1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"page2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"page3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Section 1&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"section-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Section 2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum 2&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Section 3&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum 3&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Section 4&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum 4&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Section 5&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum 5&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above creates a basic web page with a navigation bar linking to three pages, and a main content area divided into five sections with headings and paragraphs, and the CSS codes below will be used to style the above HTML code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.scroll-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;scroll-snap-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;mandatory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#658686&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;scroll-snap-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;scroll-snap-stop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;odd&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#756c6c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&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;The code above creates a full-screen vertically scrolling website with fixed height sections that snap into place as the user scrolls. The code output can be found in the GIF below:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p0mjzch8edm53kmqehy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p0mjzch8edm53kmqehy.gif" alt="implement" width="800" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code above creates a full-screen vertically scrolling website with a fixed height sections that snap into place as the user scrolls. The code output can be found in the GIF below:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p0mjzch8edm53kmqehy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p0mjzch8edm53kmqehy.gif" alt="implement" width="800" height="594"&gt;&lt;/a&gt;&lt;br&gt;
This kind of &lt;code&gt;scroll-aware&lt;/code&gt; UI can be easy to develop, but there's a lot more you can do. &lt;/p&gt;
&lt;h3&gt;
  
  
  Implementing Scroll-Aware With Animation-Timeline
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;animation-timeline&lt;/code&gt; is a CSS property that specifies the timeline used to control the progress of a CSS animation. Please keep in mind that &lt;code&gt;animation-timeline&lt;/code&gt; is included in the animation simple terms as a reset-only value. This means that including animation resets a previously declared &lt;code&gt;animation-timeline&lt;/code&gt; value to auto, but animation cannot set a specific value. For CSS &lt;code&gt;scroll-driven&lt;/code&gt; animations to work, you must declare &lt;code&gt;animation-timeline&lt;/code&gt; after declaring any animation shorthand. Below is an example to show how &lt;code&gt;animation-timeline&lt;/code&gt; works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Animation Timeline&amp;lt;/title&amp;gt;
    &amp;lt;link rel="stylesheet" href="timeline.css" /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;ANIMATION TIMELINE&amp;lt;/h1&amp;gt;
    &amp;lt;div id="container"&amp;gt;
      &amp;lt;div id="square"&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div id="stretcher"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code establishes the basic structure of a web page, including a title, heading, and placeholders for visual elements related to an animation timeline, while linking to an external stylesheet for styling.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;scroll-timeline-name&lt;/code&gt; property, the CSS for the container makes it the source of a scroll progress timeline named &lt;code&gt;--squareTimeline&lt;/code&gt; (we could explicitly set which scrollbar axis to use with &lt;code&gt;scroll-timeline-axis&lt;/code&gt;, but there is only a block direction scrollbar here, and it will be used by default).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;scroll-timeline-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--squareTimeline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;#square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;63&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;166&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;29&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotateAnimation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Firefox requires this to apply the animation */&lt;/span&gt;
    &lt;span class="nl"&gt;animation-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;animation-timeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--squareTimeline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;rotateAnimation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;#stretcher&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&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;The CSS code above creates a scrollable container with a green square that rotates 360 degrees whenever the user scrolls, The result of the above code implementation can be found in the gif as you scroll down to see the square element being animated.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf0irphr3hlsbapmrthc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf0irphr3hlsbapmrthc.gif" alt="timeline" width="1887" height="708"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Examples of Scroll-Aware Designs
&lt;/h2&gt;

&lt;p&gt;Below are a series of examples to showcase &lt;code&gt;scroll-aware&lt;/code&gt; designs with only Html and CSS: &lt;/p&gt;
&lt;h3&gt;
  
  
  Overlapping Horizontal Slideshow Using Position: Strictly
&lt;/h3&gt;

&lt;p&gt;This &lt;code&gt;scroll-aware&lt;/code&gt; feature is very responsive and supports virtually all known browsers which includes: Chrome, Edge, Firefox, Opera, and Safari. Here is an html code to implement &lt;code&gt;scroll-aware&lt;/code&gt; with only HTML and CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Scrolling&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Scrolling left and right&amp;lt;/h1&amp;gt;
    &amp;lt;ul&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/ezSFnAFi9hY/500x500"
          alt="cut citrus fruits. "
        /&amp;gt;Lorem Ipsum
      &amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/TIGDsyy0TK4/500x500"
          alt="sliced mango. "
        /&amp;gt;Dolor Sit
      &amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/TdDtTu2rv4s/500x500"
          alt="a bunch of blueberries. "
        /&amp;gt;Amet Consectetur
      &amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/eudGUrDdBB0/500x500"
          alt="a pineapple sitting on a table. "
        /&amp;gt;Adipiscing Elit
      &amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/eJH4f1rlG7g/500x500"
          alt="frozen raspberries. "
        /&amp;gt;
        Nunc Tortor
      &amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/24RUrLSW1HI/500x500"
          alt="a sliced strawberry. "
        /&amp;gt;Metus Mollis
      &amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/h5yMpgOI5nI/500x500"
          alt="an arrangement of assorted sliced fruits. "
        /&amp;gt;Congue Sagittis
      &amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;
        &amp;lt;img
          src="https://source.unsplash.com/2TYrR2IB72s/500x500"
          alt="sliced watermelons. "
        /&amp;gt;Vestibulum Et
      &amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This HTML code above creates a webpage with a heading and a horizontal list of images and text, designed to scroll left and right within the browser window.  It establishes the basic structure and content but will rely on an external CSS for styling and controlling the scrolling behavior. Below is an output of the code without adding an external CSS.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3r300rsx39cuwyndmqc7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3r300rsx39cuwyndmqc7.gif" alt="Image description" width="1870" height="912"&gt;&lt;/a&gt;&lt;br&gt;
Now let us include the external CSS and see what has changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:before&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*,&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;&amp;amp;::-webkit-scrollbar&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#6871b6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&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;amp;&lt;/span&gt;&lt;span class="nd"&gt;::-webkit-scrollbar-thumb&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#383d4d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;99em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#399882&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.5vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;36px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow-x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;white-space&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;nowrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;scroll-behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;smooth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-webkit-sticky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sticky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;350px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#132bdd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#9b9dad&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.5vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;22px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-10px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;#000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Inter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#4dce30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&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;This CSS code establishes a webpage with a vibrant green background, smoothly scrolling horizontal list items that stick to the left side of the screen, and customized scrollbars, all while ensuring consistent element sizing and spacing. The output of both the html and the CSS can be found in the gif below.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28eye2s04jt7uxed8yjq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28eye2s04jt7uxed8yjq.gif" alt="Image description" width="791" height="712"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  CSS Fixed Conic Fill
&lt;/h3&gt;

&lt;p&gt;Scroll through the contextual conic gradient text. The "fixed to viewport" &lt;code&gt;background-gradient&lt;/code&gt; is revealed by the text mask. Below is an html code to implement the CSS fixed conic fill.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Animation Timeline&amp;lt;/title&amp;gt;
    &amp;lt;link rel="stylesheet" href="timeline.css" /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;CSS Fixed Conic Fill&amp;lt;/h1&amp;gt;
    &amp;lt;h1&amp;gt;Achieving the scroll-aware UI state using CSS&amp;lt;/h1&amp;gt;
    &amp;lt;div id="container"&amp;gt;
      &amp;lt;div id="square"&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div id="stretcher"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;openreplay&amp;gt;
      &amp;lt;h1&amp;gt;Scroll Contextual Conic Gradient Text&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;text mask revealing "fixed to viewport" background gradient&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;
        Scroll through the contextual conic gradient text. The "fixed to
        viewport" background gradient is revealed by the text mask.
      &amp;lt;/p&amp;gt;
    &amp;lt;/openreplay&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above creates a webpage titled animation-timeline which demonstrates a fixed conic fill effect and a &lt;code&gt;scroll-aware&lt;/code&gt; UI state using CSS, likely involving a masked conic gradient effect that reacts to scrolling.  The specific styling and behavior are defined in an external stylesheet, and the external CSS code can be seen below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;openreplay&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/*  leverage cascade for cross-browser gradients  */&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;radial-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;60%&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;60%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;conic-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;60%&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;60%&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;60%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;-webkit-background-clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;-webkit-text-fill-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;197&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;51%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c"&gt;/*   background: conic-gradient(
      hsl(100 100% 60%), 
      hsl(200 100% 60%),
      hsl(100 100% 60%)
    ) fixed; */&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;213&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;min-block-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;min-inline-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5vmin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;place-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;system-ui&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5vmin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10vmin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;max-inline-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15ch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Dank Mono"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ui-monospace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1ch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.35&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;max-inline-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40ch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;block-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;inline-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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;This CSS code creates a webpage with a gradient background and bold, and centered text. It adapts across browsers and applies unique visual effects to text within the openreplay class, all structured using familiar HTML elements. Below is a gif showing the output of the above codes.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmb7tggjh15e8vb4l76j.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmb7tggjh15e8vb4l76j.gif" alt="fixedconic" width="1887" height="708"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Advanced CSS Scroll-Driven Animations
&lt;/h2&gt;

&lt;p&gt;Here we will be introducing a cutting-edge way to create captivating web experiences that come alive as users scroll.&lt;br&gt;
With advanced CSS &lt;code&gt;scroll-driven&lt;/code&gt; animations, you can effortlessly create dynamic visual effects without relying on JavaScript, resulting in smoother performance and greater control within CSS, crafting captivating user experiences that feel natural and intuitive, keeping visitors engaged and eager to discover more. And also adds a touch of sophistication and interactivity to your web pages, setting your designs apart from the rest.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implementing View Progress Timeline
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;view-timeline-name&lt;/code&gt; property on a subject element with the animation class is used to define a view progress timeline named&lt;code&gt;--subjectReveal&lt;/code&gt;. The timeline for the same element is then set using &lt;code&gt;animation-timeline&lt;/code&gt;: &lt;code&gt;--subjectReveal;&lt;/code&gt;. As a result, the subject element animates as it moves up the document as it is scrolled. The HTML for the example can be seen below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;div class="content"&amp;gt;
      &amp;lt;h1&amp;gt;Content&amp;lt;/h1&amp;gt;

      &amp;lt;p&amp;gt;
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Risus quis varius
        quam quisque id. Et ligula ullamcorper malesuada proin libero nunc
        consequat interdum varius. Elit ullamcorper dignissim cras tincidunt
        lobortis feugiat vivamus at augue.
      &amp;lt;/p&amp;gt;

      &amp;lt;p&amp;gt;
        Dolor sed viverra ipsum nunc aliquet. Sed sed risus pretium quam
        vulputate dignissim. Tortor aliquam nulla facilisi cras. 
      &amp;lt;/p&amp;gt;

      &amp;lt;div class="subject animation"&amp;gt;&amp;lt;/div&amp;gt;

      &amp;lt;p&amp;gt;
        Adipiscing enim eu turpis egestas pretium aenean pharetra magna ac. Arcu
        cursus vitae congue mauris rhoncus aenean vel. Sit amet cursus sit amet
        dictum. Augue neque gravida in fermentum et.
      &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code above creates the basic structure of a web page, containing a heading, paragraphs of text, and an animated element, all arranged within the main content area. The &lt;code&gt;subject-element&lt;/code&gt; and its containing &lt;code&gt;content-element&lt;/code&gt; are styled minimally, and the &lt;code&gt;text-content&lt;/code&gt; is given some basic font settings, the CSS code can be seen below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;58&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;173&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;75%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.animation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;view-timeline-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--subjectReveal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;animation-timeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--subjectReveal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-fill-mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;both&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Firefox requires this to apply the animation */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;appear&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scaleX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scaleX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="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;The above CSS code when linked to the html code, styles a purple subject box, a &lt;code&gt;content-area&lt;/code&gt; with text in Arial font, and an animation that reveals elements by scaling them in from the left to show how to view the progress timeline, the output is displayed in the gif below.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwwkbb5z92lfe666281m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwwkbb5z92lfe666281m.gif" alt="progresstimeline" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding Functionality With JavaScript
&lt;/h2&gt;

&lt;p&gt;The recent CSS features for animations are powerful, but not all browsers support them yet. But for guaranteed cross-browser compatibility and accessibility, you can improve the &lt;code&gt;scroll-driven&lt;/code&gt; animations using JavaScript. We use the new &lt;code&gt;animation-timeline&lt;/code&gt; CSS property and have it refer to the timeline's name to associate the &lt;code&gt;scroll-timeline&lt;/code&gt; with CSS animation, the HTML Code can be found below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;section&amp;gt;
  &amp;lt;h1&amp;gt;Scroll Down to Reveal Elements&amp;lt;/h1&amp;gt;
&amp;lt;/section&amp;gt;

&amp;lt;section&amp;gt;
  &amp;lt;div class="container reveal"&amp;gt;
    &amp;lt;h2&amp;gt;Caption&amp;lt;/h2&amp;gt;
    &amp;lt;div class="text-container"&amp;gt;
      &amp;lt;div class="text-box"&amp;gt;
        &amp;lt;h3&amp;gt;Section Text&amp;lt;/h3&amp;gt;
        &amp;lt;p&amp;gt;
          Your session replay, analytics, and co-browsing tools. Together. A
          full-featured session replay suite you can self-host, so your
          customer data never leaves your infrastructure.
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="text-box"&amp;gt;
        &amp;lt;h3&amp;gt;Section Text&amp;lt;/h3&amp;gt;
        &amp;lt;p&amp;gt;
          Session Replay See everything users do on your web app, down to
          the smallest detail. Understand all frustrations and visually get
          to the "why" of every issue.
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="text-box"&amp;gt;
        &amp;lt;h3&amp;gt;Section Text&amp;lt;/h3&amp;gt;
        &amp;lt;p&amp;gt;
          DevTools provides you with the full context so you can understand
          the state of your web application at any point in time. It's like
          reproducing bugs in your browser
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/section&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above creates a web page with a heading and a hidden section that reveals itself when the user scrolls down. The hidden section contains text boxes with information about session replay tools and developer tools, the CSS code can be seen below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('https://fonts.googleapis.com/css2?family=Asap&amp;amp;display=swap')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Asap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1326b6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e0ffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#121c65&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e0ffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e0ffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.reveal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.reveal.active&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This CSS code above sets up a webpage with a blue background, centered content, and animated text elements that gracefully slide into view. It achieves this by importing a font, styling the body and sections, and defining a class for content reveal animations, the JavaScript code for implementation can be seen below.&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;function&lt;/span&gt; &lt;span class="nf"&gt;reveal&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;reveals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.reveal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;reveals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;windowHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&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;elementTop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reveals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;top&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;elementVisible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elementTop&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;windowHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;elementVisible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;reveals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;reveals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reveal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JavaScript code above checks for elements with a reveal class as the user scrolls and reveals them by adding an active class when they come into view within a 150-pixel threshold from the top of the viewport. The output of the above codes can be seen in the gif below.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0p9ofnt6otxnvatvkxi0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0p9ofnt6otxnvatvkxi0.gif" alt="witjs" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Limitations to Scroll-Aware
&lt;/h2&gt;

&lt;p&gt;While CSS offers powerful tools for creating &lt;code&gt;scroll-aware&lt;/code&gt; UI elements, it does have some inherent limitations which are listed below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limited Event Handling: CSS lacks direct scroll event listeners as you can't trigger actions precisely when a user scrolls to a specific element or position.&lt;/li&gt;
&lt;li&gt;Indirect State Management: CSS can't directly change element states based on scroll position, it relies on &lt;code&gt;pseudo-classes&lt;/code&gt; like &lt;code&gt;:hover&lt;/code&gt; or &lt;code&gt;:active&lt;/code&gt; can be limiting for complex interactions.&lt;/li&gt;
&lt;li&gt;Performance Considerations: Complex CSS &lt;code&gt;scroll-aware&lt;/code&gt; effects, especially those involving multiple transitions or animations, can impact performance on resource-constrained devices.&lt;/li&gt;
&lt;li&gt;Browser Compatibility: Not all CSS &lt;code&gt;scroll-aware&lt;/code&gt; properties have consistent support across all browsers. It's essential to consider browser compatibility and provide polyfills or fallbacks when necessary.&lt;/li&gt;
&lt;li&gt;Limited Interaction Scope: CSS alone can't handle more complex scroll-based interactions like dynamic content loading, infinite scrolling, and real-time updates based on scroll position&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;CSS offers promising capabilities for achieving &lt;code&gt;scroll-aware&lt;/code&gt; UI states, adding a layer of visual interest and interactivity to web pages. By understanding scroll timelines, scroll-linked animations, browser compatibility, and potential JavaScript integration, developers can create dynamic and engaging user experiences that respond seamlessly to user actions.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Improving Your Vue.js Custom Drag-and-Drop File Uploading System</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Sun, 28 Jan 2024 13:17:25 +0000</pubDate>
      <link>https://forem.com/davidking/improving-your-vuejs-custom-drag-and-drop-file-uploading-system-3532</link>
      <guid>https://forem.com/davidking/improving-your-vuejs-custom-drag-and-drop-file-uploading-system-3532</guid>
      <description>&lt;p&gt;This tutorial will explore how to supercharge your custom drag-and-drop file uploader with &lt;a href="https://vuejs.org/guide/introduction.html" rel="noopener noreferrer"&gt;Vue.js&lt;/a&gt;, taking your web development skills to the next level. "Whether you are an experienced developer or just starting, this tutorial provides the knowledge and tools to create a more efficient and engaging file-uploading experience for your users.&lt;/p&gt;

&lt;p&gt;This article is an updated version of Building &lt;a href="https://blog.openreplay.com/building-a-custom-file-upload-component-for-vue/" rel="noopener noreferrer"&gt;A Custom File Upload Component For Vue&lt;/a&gt;. Add features like file preview, removal, and preventing duplicates to enhance the drag-and-drop component.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Familiarity with Vue.js&lt;/li&gt;
&lt;li&gt;Basics understanding of HTML and CSS&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Building a superficial drop zone
&lt;/h2&gt;

&lt;p&gt;In this part of the guide, we'll start by revisiting the fundamental concepts of a drop zone. A drop-zone is an area on a web page where users can drag and drop files for uploading. We'll refresh your understanding of how an essential drop-zone works, including &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML" rel="noopener noreferrer"&gt;HTML&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS" rel="noopener noreferrer"&gt;CSS&lt;/a&gt; elements that create this area. This step is crucial because it lays the groundwork for implementing advanced features with Vue.js. &lt;/p&gt;

&lt;p&gt;By understanding the basics, you'll be better prepared to enhance and customize the drop zone.&lt;/p&gt;

&lt;p&gt;The HTML &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tag with the 'file' type allows drag-and-drop functionality but usually only accepts one file at a time. To enable it to get multiple files, we can simply add the 'multiple' attribute (i.e., &lt;code&gt;&amp;lt;input type="file" multiple /&amp;gt;&lt;/code&gt;), adjust its width as needed, and add a border and padding.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa98xjlymkfki2ygdfec.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa98xjlymkfki2ygdfec.gif" width="1898" height="916"&gt;&lt;/a&gt;&lt;br&gt;
You'll agree that this needs to be improved in terms of aesthetics. Instead, we'll create a similar drag-and-drop file uploader; we'll still have a file input, but it will be hidden. Then, we'll create a visible label to allow dragging to the file input. We'll add another custom event to alter the dragging state and show or delete chosen files.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating an advanced drop zone
&lt;/h2&gt;

&lt;p&gt;To start, run the following command to build a new Vue application:&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="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="nx"&gt;vue&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;latest&lt;/span&gt; &lt;span class="nx"&gt;dropfile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your text editor, then create an empty &lt;code&gt;DropFile.vue&lt;/code&gt; file in the &lt;code&gt;src/component&lt;/code&gt; directory. Let's now add this component to our entry file. Replace the contents of &lt;code&gt;App.vue&lt;/code&gt; with the following code:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DropFile&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DropFile&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/DropFile.vue&lt;/span&gt;&lt;span class="dl"&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;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;DropFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Subsequently, we'll arrange all of the CSS codes. In the &lt;code&gt;src/assets&lt;/code&gt; directory, create a new &lt;code&gt;dropfile.css&lt;/code&gt; file and put the following code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-grow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.dropzone-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f7fafc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#e2e8f0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.hidden-input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.file-label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.preview-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.preview-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#a2a2a2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.preview-img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#a2a2a2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#a2a2a2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will replace the content in the &lt;code&gt;DropFile.vue&lt;/code&gt; file with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div class="main"&amp;gt;
    &amp;lt;div
      class="dropzone-container"
      @dragover="dragover"
      @dragleave="dragleave"
      @drop="drop"
    &amp;gt;
      &amp;lt;input
        type="file"
        multiple
        name="file"
        id="fileInput"
        class="hidden-input"
        @change="onChange"
        ref="file"
        accept=".pdf, .jpg, .jpeg, .png"
      /&amp;gt;

      &amp;lt;label for="fileInput" class="file-label"&amp;gt;
        &amp;lt;div v-if="isDragging"&amp;gt;Release to drop files here.&amp;lt;/div&amp;gt;
        &amp;lt;div v-else&amp;gt;Drop files here or &amp;lt;u&amp;gt;click here&amp;lt;/u&amp;gt; to upload.&amp;lt;/div&amp;gt;
      &amp;lt;/label&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
  data() {
    return {
      isDragging: false,
      files: [],
    };
  },
  methods: {
    onChange() {
      this.files.push(...this.$refs.file.files);
    },
    dragover(e) {
      e.preventDefault();
      this.isDragging = true;
    },
    dragleave() {
      this.isDragging = false;
    },
    drop(e) {
      e.preventDefault();
      this.$refs.file.files = e.dataTransfer.files;
      this.onChange();
      this.isDragging = false;
    },
  },
};
&amp;lt;/script&amp;gt;

&amp;lt;style scoped src="@/assets/dropfile.css"&amp;gt;&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we defined two reactive states: &lt;code&gt;isDragging&lt;/code&gt;, Indicate if the user is trying to drag a file onto our drop zone and list the picked or dropped files in an array. The primary file input was then given a special ref to make it more available in our Vue instance. We also included an &lt;code&gt;onChange&lt;/code&gt; event, which changes our files array with the files associated with our input.&lt;/p&gt;

&lt;p&gt;After that, we added the &lt;code&gt;dragover&lt;/code&gt;, &lt;code&gt;dragleave&lt;/code&gt;, and &lt;code&gt;drop-methods&lt;/code&gt; to the container that held our primary file input. As a result, using the custom ref we defined before, the drop event and method will catch the dropped file and connect it to our file input.&lt;/p&gt;

&lt;p&gt;We can also use the &lt;code&gt;dragover&lt;/code&gt; and &lt;code&gt;dragleave&lt;/code&gt; methods to change the status of &lt;code&gt;isDragging&lt;/code&gt; as needed. Finally, we utilized conditional rendering with &lt;code&gt;v-if&lt;/code&gt; and &lt;code&gt;v-else&lt;/code&gt; to check the status of &lt;code&gt;isDragging&lt;/code&gt; and show a different message depending on the state. &lt;/p&gt;

&lt;p&gt;If we run our app now, we should get the following results:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkf122g0y07q7l3jf137.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkf122g0y07q7l3jf137.gif" width="1898" height="916"&gt;&lt;/a&gt;&lt;br&gt;
Although we cannot see the dropped files, they are in the background. To test this, please log these &lt;code&gt;.files&lt;/code&gt; to the console inside the &lt;code&gt;onChange()&lt;/code&gt; function. The array should be recorded to the console whenever you drop or manually pick a file, with each file having the file name, size, last changed date, and other associated information.&lt;/p&gt;
&lt;h3&gt;
  
  
  Improve dragging state
&lt;/h3&gt;

&lt;p&gt;We may change the drop zone border to reflect its current operation state to improve the dragging and dropping experience. &lt;br&gt;
Add the following border styling code to the &lt;code&gt;dropzone-container&lt;/code&gt; in the css file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.dropzone-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* . . .  */&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;dashed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#9e9e9e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, then you update the &lt;code&gt;dropzone-container&lt;/code&gt; markup under the &lt;code&gt;DropFile.vue&lt;/code&gt; file to style its border conditionally during the dragging state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="main"&amp;gt;
  &amp;lt;div
    class="dropzone-container"
    @dragover="dragover"
    @dragleave="dragleave"
    @drop="drop"
    :style="isDragging &amp;amp;&amp;amp; 'border-color: blue;'"
  &amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this new update, the drop zone should look like the GIF below, in which the borderline will change to blue when you drag the file to upload:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnaacfw8whh46biq3ogbw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnaacfw8whh46biq3ogbw.gif" width="1898" height="916"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Listing the dropped files
&lt;/h2&gt;

&lt;p&gt;It is simple to preview the files that have been selected and dropped. We'll need to cycle over our file array. To do so, insert the following code directly after the &lt;code&gt;&amp;lt;/label&amp;gt;&lt;/code&gt; tag in the preceding code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- ... --&amp;gt;
&amp;lt;/label&amp;gt;
&amp;lt;!-- Note: Only add the code block below --&amp;gt;
&amp;lt;div class="preview-container mt-4" v-if="files.length"&amp;gt;
  &amp;lt;div class="preview-cart" v-for="file in files" :key="file.name"&amp;gt;

    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;{{ file.name }}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;button
        class="ml-3"
        type="button"
        @click="remove(files.indexOf(file))"
        title="Remove file"
      &amp;gt;
        &amp;lt;strong&amp;gt;×&amp;lt;/strong&amp;gt;
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code mentioned above, we utilized conditional rendering to determine whether our file array had a valid length. Then, we ran through it all, showing each file name in a paragraph.&lt;/p&gt;

&lt;p&gt;The GIF below shows the output of the above code:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtju1zwhmah9gaqy4qg3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtju1zwhmah9gaqy4qg3.gif" width="1898" height="916"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Removing files
&lt;/h3&gt;

&lt;p&gt;You'll note in the earlier code block that we also added a button to each iterable item, executing a &lt;code&gt;remove()&lt;/code&gt; method and supplying the index of the current file as its input. If we start our app now, we should see the selected file names shown as expected and a button to delete them.&lt;/p&gt;

&lt;p&gt;Nevertheless, the option to delete selected images still needs to be fixed. To solve this, we will need to attach a new &lt;code&gt;remove()&lt;/code&gt; function to all preceding methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ..&lt;/span&gt;
&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, everything should work perfectly. We should be able to pick files manually, drag and drop them, view their names, and delete them. &lt;br&gt;
A preview of the output is shown in the GIF below:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffot5adm62x61gy4nfp96.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffot5adm62x61gy4nfp96.gif" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Previewing selected image files
&lt;/h2&gt;

&lt;p&gt;Reviewing chosen picture files is an extra feature that will make our drop zone component even more user-friendly. We can do this by constructing an arbitrary URL using the native &lt;code&gt;URL.createObjectURL()method&lt;/code&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="c1"&gt;// ..&lt;/span&gt;
&lt;span class="nf"&gt;generateURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;fileSrc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&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;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revokeObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileSrc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fileSrc&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;To minimize memory loss, it is best to always revoke a URL after generating one with the &lt;code&gt;URL.createObjectURL()&lt;/code&gt; function. We've included an extra delay to accomplish this automatically after one second.&lt;/p&gt;

&lt;p&gt;Next, replace the paragraph &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag that displays the names of all chosen or dropped files with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img class="preview-img" :src="generateURL(file)" /&amp;gt;
&amp;lt;p&amp;gt;{{ file.name }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now everything is running! We can now drag and drop files, select them, remove them, and even preview them:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xcpwk18h3sudasekwmn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xcpwk18h3sudasekwmn.gif" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Showing file size
&lt;/h2&gt;

&lt;p&gt;As stated earlier, we have immediate access to each selected file size and its latest changed date. By default, the file size is displayed in bytes., but we can easily divide it by 1,000 to convert it to KB. &lt;br&gt;
Add the following code to the section of the file that displays the file name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;{{ file.name }} - {{ Math.round(file.size / 1000) + "kb" }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each selected file size is now shown beside its name:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13l897w43pm9speq3k9u.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13l897w43pm9speq3k9u.gif" width="1898" height="916"&gt;&lt;/a&gt;&lt;br&gt;
GIF file with name&lt;/p&gt;
&lt;h2&gt;
  
  
  Preventing duplicate files
&lt;/h2&gt;

&lt;p&gt;Currently, our file drop zone allows us to dump duplicate files. To avoid duplicates, we can compare incoming files to those already in our file array. If a duplicate is discovered, a notification will be displayed.&lt;/p&gt;

&lt;p&gt;To do so, add the following code to the &lt;code&gt;onChange&lt;/code&gt; method:&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="nf"&gt;onChange&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="nb"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;incomingFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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;fileExist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existingFile&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;incomingFiles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;existingFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;existingFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileExist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The new upload contains files that already exist.&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="nx"&gt;incomingFiles&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the above code  addition, the drop zone will check if the user attempts to upload an existing file based on its name and size.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9i88vb2m3nh4doo986hf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9i88vb2m3nh4doo986hf.gif" width="1898" height="916"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Uploading files to the server
&lt;/h2&gt;

&lt;p&gt;Uploading the specified files to the server is simple since they are tied to the file's state. Although there are other approaches to accomplishing this, utilizing &lt;code&gt;FormData&lt;/code&gt; is the most frequent.&lt;/p&gt;

&lt;p&gt;The following code demonstrates how we could use &lt;code&gt;FormData&lt;/code&gt; with Axios to submit our files to an &lt;a href="https://www.postman.com/api-platform/api-documentation/" rel="noopener noreferrer"&gt;API&lt;/a&gt; or server for processing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// . . .&lt;/span&gt;
&lt;span class="nf"&gt;uploadFiles&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;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;file&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;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedFiles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://path/to/api/upload-files&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;multipart/form-data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could then utilize various built-in methods or frameworks on the backend to process the files as needed, but this is outside the article's purpose and outline.&lt;/p&gt;

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

&lt;p&gt;This tutorial taught us how to use &lt;code&gt;Vue&lt;/code&gt; to develop a simple yet interactive drag-and-drop file uploader. Before uploading, we may inspect the titles and sizes of the selected files, preview picture files, and even delete files.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>vue</category>
    </item>
    <item>
      <title>Comparing CodiumAI PR-Agent to Copilot for Pull Request</title>
      <dc:creator>David Fagbuyiro</dc:creator>
      <pubDate>Tue, 05 Dec 2023 00:04:14 +0000</pubDate>
      <link>https://forem.com/davidking/comparing-codiumai-pr-agent-to-copilot-for-pull-request-4o01</link>
      <guid>https://forem.com/davidking/comparing-codiumai-pr-agent-to-copilot-for-pull-request-4o01</guid>
      <description>&lt;p&gt;In the software development field, pull requests (PRs) serve as the cornerstone for collaborative code review and integration. However, the process of reviewing PRs can be time-consuming and meticulous, often hindering the development process. This is where AI-powered tools like PR-Agent by CodiumAI and GitHub Copilot step in, offering a transformative approach to PR review and improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of PR-Agent and GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;PR-Agent and GitHub Copilot are both AI-powered tools that help developers with their work. PR-Agent is a tool that automates pull request analysis, feedback, and suggestions. GitHub Copilot is a tool that suggests code completions and turns natural language prompts into coding suggestions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pull Request
&lt;/h3&gt;

&lt;p&gt;A pull request (PR) is a way to propose changes to code in a code repository. It is a way for developers to review and discuss changes before they are merged into the main codebase.&lt;br&gt;
PR-Agent&lt;br&gt;
PR-Agent is an AI-powered tool that automates pull request analysis, feedback, and suggestions. It can help developers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify potential problems with their code.&lt;/li&gt;
&lt;li&gt;Improve the quality of their code.&lt;/li&gt;
&lt;li&gt;Get feedback from other developers.
PR-Agent is still under development, but it has already been shown to be effective in improving the quality of code.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  GitHub Copilot
&lt;/h3&gt;

&lt;p&gt;GitHub Copilot is an AI-powered tool that suggests code completions and turns natural language prompts into coding suggestions. It can help developers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write code more quickly&lt;/li&gt;
&lt;li&gt;Write more consistent code&lt;/li&gt;
&lt;li&gt;Write code that is more idiomatic to the language
GitHub Copilot is still under development, but it has already been shown to be effective in improving developer productivity.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Feature Comparison
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmt82hqoq5i3vg42rke3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmt82hqoq5i3vg42rke3.png" alt="Image description" width="485" height="733"&gt;&lt;/a&gt;&lt;br&gt;
CodiumAI vs. GitHub Copilot Comparison from &lt;a href="https://sourceforge.net/software/compare/Codeium-vs-CodiumAI-vs-GitHub-Copilot/" rel="noopener noreferrer"&gt;SourceForge&lt;/a&gt; and feature &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;Copilot&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;p&gt;Here are some code examples demonstrating the functionality of PR-Agent by CodiumAI and GitHub Copilot:&lt;/p&gt;
&lt;h3&gt;
  
  
  PR-Agent
&lt;/h3&gt;

&lt;p&gt;Code Example 1: &lt;strong&gt;Identifying Potential Problems&lt;/strong&gt;&lt;br&gt;
PR-Agent can help developers identify potential problems with their code by providing real-time feedback. For example, if a developer has a typo in a variable name, PR-Agent will flag this as a potential problem and suggest a correction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Typo&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PR-Agent would flag the use of the variable &lt;code&gt;world!&lt;/code&gt; as a potential problem and suggest that it be changed to &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Code Example 2: &lt;strong&gt;Suggesting Improvements&lt;/strong&gt;&lt;br&gt;
PR-Agent can also suggest improvements to the code in a pull request. For example, if a developer is using a less idiomatic expression, PR-Agent will suggest a more idiomatic alternative.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_average&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;average&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;average&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PR-Agent would suggest that the &lt;code&gt;sum&lt;/code&gt; variable be renamed to &lt;code&gt;totalSum&lt;/code&gt; to make the code more readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Copilot
&lt;/h3&gt;

&lt;p&gt;Code Example 1: &lt;strong&gt;Code Completion&lt;/strong&gt;&lt;br&gt;
GitHub Copilot can help developers write code more quickly and accurately by suggesting code completions. For example, if a developer is typing the name of a function, GitHub Copilot will suggest the rest of the function name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, {name}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub Copilot would suggest the completion of the &lt;code&gt;greet&lt;/code&gt; function, including the parentheses and curly braces.&lt;/p&gt;

&lt;p&gt;Code Example 2: &lt;strong&gt;Code Generation&lt;/strong&gt;&lt;br&gt;
GitHub Copilot can also generate code from natural language prompts. For example, if a developer wants to write a function that calculates the factorial of a number, they can write a natural language prompt, and GitHub Copilot will generate the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;n must be non-negative&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub Copilot would generate the code for the &lt;code&gt;factorial&lt;/code&gt; function from the natural language prompt "Write a function that calculates the factorial of a number".&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Open-source vs. Proprietary Nature
&lt;/h3&gt;

&lt;p&gt;PR-Agent is an open-source tool, while GitHub Copilot is a proprietary tool. This means that PR-Agent is available for anyone to inspect and modify, while GitHub Copilot is only available to users who have paid for a subscription.&lt;/p&gt;

&lt;h3&gt;
  
  
  IDE Integration
&lt;/h3&gt;

&lt;p&gt;PR-Agent integrates with a variety of &lt;a href="https://marketplace.visualstudio.com/items?itemName=Codium.codium" rel="noopener noreferrer"&gt;IDEs&lt;/a&gt;, including Visual Studio Code, Vim, and JetBrains IDEs. GitHub Copilot also integrates with a variety of IDEs, including Visual Studio Code, Vim, Neovim, JetBrains IDEs, and Azure Data Studio.&lt;br&gt;
For more information on using the PR-Agent IDE integration &lt;a href="https://dev.to/davydocsurg/the-future-of-code-quality-codiumais-ide-extension-redefines-developer-productivity-54bm"&gt;click here&lt;/a&gt; and follow the steps for both installation and implementation  &lt;/p&gt;
&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;PR-Agent is free to use, while GitHub Copilot costs $10 USD per month or $100 USD per year. There is also a free tier for students and educators.&lt;br&gt;
Sure, here is a discussion of the potential limitations and future directions for each tool, highlighting PR-Agent's potential advantages over GitHub Copilot:&lt;/p&gt;
&lt;h3&gt;
  
  
  Potential Limitations: PR-Agent
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Open-Source Nature&lt;/strong&gt;: While being open-source provides transparency and community support, it may also lead to slower development and less polished features compared to proprietary tools like GitHub Copilot.&lt;br&gt;
&lt;strong&gt;Accuracy and Maturity&lt;/strong&gt;: As a relatively new tool, PR-Agent may not be as accurate as human reviewers in identifying all potential problems or suggesting the most optimal improvements.&lt;/p&gt;
&lt;h3&gt;
  
  
  Future Directions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Enhanced Accuracy and Maturity:&lt;/strong&gt; Continuously refine the tool's algorithms and models to improve its ability to identify issues and provide accurate suggestions.&lt;br&gt;
Expanded Integration: Integrate with a wider range of IDEs and development environments to reach a broader audience.&lt;br&gt;
&lt;strong&gt;Community-Driven Development:&lt;/strong&gt; Leverage the open-source nature to foster community involvement in feature development and bug fixes.&lt;br&gt;
&lt;strong&gt;Potential Limitations:&lt;/strong&gt; GitHub Copilot&lt;br&gt;
Proprietary Nature: As a proprietary tool, GitHub Copilot lacks the transparency and community support of open-source tools like PR-Agent.&lt;br&gt;
&lt;strong&gt;Code Generation Accuracy:&lt;/strong&gt; While GitHub Copilot excels in code completion, its code generation capabilities may produce inaccurate or idiomatic code, requiring careful review by developers.&lt;br&gt;
&lt;strong&gt;Pricing Model:&lt;/strong&gt; The subscription-based pricing model may limit accessibility to GitHub Copilot, especially for individuals or small teams.&lt;/p&gt;
&lt;h3&gt;
  
  
  Future Directions:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Improved Code Generation:&lt;/strong&gt; Enhance the code generation capabilities to produce more accurate, idiomatic, and contextually relevant code.&lt;br&gt;
&lt;strong&gt;Expanded Functionality:&lt;/strong&gt; Explore additional functionalities beyond code completion and generation, such as code summarization and refactoring assistance.&lt;br&gt;
&lt;strong&gt;Pricing Options:&lt;/strong&gt; Consider alternative pricing models, such as tiered pricing or usage-based pricing, to make GitHub Copilot more accessible to a wider range of users.&lt;/p&gt;
&lt;h2&gt;
  
  
  PR-Agent's Potential Edge
&lt;/h2&gt;

&lt;p&gt;PR-Agent's open-source nature and commitment to community-driven development give it a potential edge over GitHub Copilot. This open approach allows for faster development cycles, broader community support, and a more transparent feedback loop, leading to continuous improvements and a more user-centric tool.&lt;br&gt;
Additionally, PR-Agent's focus on real-time feedback and pull request analysis positions it well to address the growing need for tools that assist with code review and improvement. By providing timely and actionable insights, PR-Agent can help developers enhance the quality of their code and streamline the code review process.&lt;/p&gt;

&lt;p&gt;While GitHub Copilot offers impressive code completion and generation capabilities, its proprietary nature and pricing model may limit its adoption and accessibility. PR-Agent's open-source approach and focus on real-time feedback could position it as a compelling alternative for developers seeking a more collaborative and community-driven tool for code review and improvement.&lt;br&gt;
PR-Agent supports a variety of commands for different functionalities, and here is the list of PR-Agent commands with proper syntax highlighting and code formatting::&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auto Description (/describe): Automatically generates PR description, including title, type, summary, code walkthrough, and labels.&lt;/li&gt;
&lt;li&gt;Auto Review (/review): Provides adjustable feedback about the PR main theme, type, relevant tests, security issues, score, and various suggestions for the PR content.&lt;/li&gt;
&lt;li&gt;Question Answering (/ask ...): Answers free-text questions about the PR, covering various aspects of the code and its context.&lt;/li&gt;
&lt;li&gt;Code Refactoring (/refactor): Suggests refactoring opportunities to improve code quality, readability, and maintainability.&lt;/li&gt;
&lt;li&gt;Code Generation (/generate): Generates code snippets or entire functions based on natural language prompts or code examples.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;snippets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/generate snippet &amp;lt;natural language prompt or code example&amp;gt;`&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="nx"&gt;entire&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/generate function &amp;lt;function description&amp;gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Summarization (/summarize):&lt;/strong&gt; Provides a concise summary of the PR code, highlighting key points, functions, and logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Testing (/test):&lt;/strong&gt; Generates test cases for the PR code, covering various scenarios and potential edge cases.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="nx"&gt;basic&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;cases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/test basic`&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="nx"&gt;comprehensive&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;cases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/test comprehensive`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Code Debugging (/debug):&lt;/strong&gt; Assists in debugging code by identifying potential errors, suggesting fixes, and explaining error messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Identify&lt;/span&gt; &lt;span class="nx"&gt;potential&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/debug identify`&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Suggest&lt;/span&gt; &lt;span class="nx"&gt;fixes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/debug fix`&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Explain&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/debug explain`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Optimization (/optimize):&lt;/strong&gt; Suggests optimizations to improve code performance, efficiency, and resource utilization.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Improve&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/optimize performance`&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Improve&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;efficiency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/optimize efficiency`&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Improve&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="nx"&gt;utilization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/optimize resources`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Documentation (/document):&lt;/strong&gt; Generates code documentation for functions, classes, and modules, explaining their purpose and usage.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;documentation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/document function &amp;lt;function name&amp;gt;`&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;documentation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/document class &amp;lt;class name&amp;gt;`&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="nx"&gt;documentation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/document module &amp;lt;module name&amp;gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands provide a comprehensive set of functionalities for code review, improvement, and generation, enabling developers to enhance the quality and efficiency of their work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The importance of evaluating both tools
&lt;/h2&gt;

&lt;p&gt;The importance of evaluating both PR-Agent and GitHub Copilot hands-on to determine the best fit for individual developers and teams:&lt;br&gt;
While both PR-Agent and GitHub Copilot offer impressive capabilities for assisting developers with code review, code completion, and code generation, the best tool for a particular developer or team will depend on their specific needs, preferences, and workflow.&lt;/p&gt;

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

&lt;p&gt;PR-Agent and GitHub Copilot are both promising AI-powered tools that can help developers improve their work. PR-Agent can help developers to identify potential problems with their code and improve the quality of their code. Both tools are still under development, but they have already been shown to be effective in their respective areas and I can’t wait to witness the greatness of PR-Agent.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
