<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Libraries - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Libraries - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 11 Jun 2026 23:14:58 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/libraries/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How Does the Morgan Express Middleware Library Work? Explained with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ Morgan is an Express middleware library that examines HTTP requests and logs details of the request to an output. It is one of the most popular Express middleware libraries with over 8,000 GitHub star ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-does-the-morgan-library-work/</link>
                <guid isPermaLink="false">68dacc9e86b3b4616655000a</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Orim Dominic Adah ]]>
                </dc:creator>
                <pubDate>Mon, 29 Sep 2025 18:14:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759169256698/9cb4e87a-2bc3-49ac-b1a6-b9d02d410ea1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><a href="https://www.npmjs.com/package/morgan">Morgan</a> is an Express middleware library that examines HTTP requests and logs details of the request to an output. It is one of the most popular Express middleware libraries with over 8,000 GitHub stars and more than 9,000 npm libraries dependent on it. GitHub reports that Morgan is used by at least 3.6 million repositories.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>This guide explains the Morgan library’s code to help you understand how it works under the hood. This is helpful if you have experience with Express and you're interested in understanding the inner workings that produce Morgan log lines. An understanding of closures in JavaScript is helpful for this guide but not necessary.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-is-an-express-middleware">What is an Express Middleware?</a></p>
</li>
<li><p><a href="#heading-a-brief-overview-of-how-morgan-works">A Brief Overview of How Morgan Works</a></p>
</li>
<li><p><a href="#heading-what-is-a-morgan-token">What is a Morgan Token?</a></p>
</li>
<li><p><a href="#heading-what-happens-when-morgan-is-initialised">What Happens When Morgan is Initialised?</a></p>
</li>
<li><p><a href="#heading-what-happens-when-morgan-captures-a-request">What Happens When Morgan Captures a Request?</a></p>
</li>
<li><p><a href="#heading-next-steps">Next Steps</a></p>
</li>
</ul>
<h2 id="heading-what-is-an-express-middleware">What is an Express Middleware?</h2>
<p>According to <a href="https://expressjs.com/en/guide/writing-middleware.html">Express documentation</a>, a middleware is a function that has access to the request and response objects and the <code>next</code> function of an Express request cycle. They are generally used to intercept requests to execute side-effects before or after the request is handled by its route handler.</p>
<p>A middleware can be used to:</p>
<ul>
<li><p><strong>Make changes to the request and the response objects</strong>: It can make changes to the request and response objects by attaching properties like headers and cookies to them.</p>
</li>
<li><p><strong>Terminate the request-response cycle</strong>: It can terminate a request and send a response to the client before or after the request is handled by its route handler.</p>
</li>
<li><p><strong>Execute the next middleware in the stack</strong>: It can trigger the execution of the middleware after it via the <code>next</code> function argument.</p>
</li>
</ul>
<p>A function called <code>next</code> is usually the third argument of a middleware and it is used to pass the request to the next middleware. If the <code>next</code> function is not executed in a middleware and the request is not explicitly terminated by sending a response to the client, the request will be left hanging.</p>
<p>The interface of a middleware is shown in the code snippet below:</p>
<pre><code class="language-javascript">function middleware(request, response, next) {
    // operations to be performed when this middleware is executed
    next() // execute the next middleware
}
</code></pre>
<p>A middleware can intercept and handle cases where preceding middleware or route handlers throw unhandled errors. These middlewares are usually called error handler middlewares and accept four arguments as shown below:</p>
<pre><code class="language-javascript">function errorHandlerMiddleware(error, request, response, next) {}
</code></pre>
<p>The <code>error</code> argument represents the unhandled error.</p>
<p>Some middlewares like Morgan and <a href="https://www.npmjs.com/package/cors">cors</a> are higher-order functions. They accept configuration arguments when initialised and return a middleware function, executed by Express when hit by a request.</p>
<pre><code class="language-javascript">function initialise(...configArgs) {
    // make use of configArgs here
    return function middleware(request, response, next) {
        // can also make use of configArgs here
        // operations to perform when this middleware is hit by a request
        next() // execute the next middleware
    }
}
</code></pre>
<h2 id="heading-a-brief-overview-of-how-morgan-works">A Brief Overview of How Morgan Works</h2>
<pre><code class="language-javascript">import morgan from "morgan"
// morgan(format, [options])
morgan("tiny") // initialise morgan and return a middleware
// Sample output: GET /tiny 200 2 - 0.188 ms
</code></pre>
<p>Morgan is initialised by executing it with a required <code>format</code> argument and an optional <code>options</code> argument. The <code>format</code> argument may be:</p>
<ul>
<li><p>A predefined Morgan format name</p>
</li>
<li><p>A format string containing predefined tokens (a token set)</p>
</li>
<li><p>A custom format function that returns a log output in the form of a string</p>
</li>
</ul>
<p>The <code>options</code> argument is optional. It is an object with three properties:</p>
<ul>
<li><p><code>immediate</code> (boolean): If <code>true</code>, the log output will be created on receiving requests and not when a response is sent. It defaults to <code>false</code>.</p>
</li>
<li><p><code>skip</code> (function): The function accepts the request and response objects as arguments and returns a boolean value based on the logic in it. If the value returned is <code>true</code>, the log line for a request is not logged. <code>skip</code> defaults to <code>false</code>.</p>
</li>
<li><p><code>stream</code> (WritableStream): Output stream for writing log lines. It defaults to <code>process.stdout</code> but it could be a file.</p>
</li>
</ul>
<p>When Morgan is initialised, it stores its initialisation arguments in closure variables and returns a middleware function. The function is executed when a request hits it and it outputs a log line for the request. The format and where the log line is output to are determined by the initialisation arguments.</p>
<h2 id="heading-what-is-a-morgan-token">What is a Morgan Token?</h2>
<p>A Morgan token is a string prefixed by a colon, corresponding to property of the request or response objects or a user-generated value. For example, the request method’s token is <code>':method'</code> and the response status code’s token is <code>':status'</code>. A token can also accept an argument to customise its behaviour. For instance, in <code>':date[format]'</code>, <code>format</code> can be replaced with <code>clf</code>, <code>iso</code> or <code>web</code> to set the format of the date that would be in the log line. An understanding of Morgan tokens is crucial to understanding how Morgan works.</p>
<p>You can create new tokens using the <code>morgan.token</code> function. The code snippet below creates a new token called <code>':type'</code> which corresponds to the response <code>Content-Type</code> header:</p>
<pre><code class="language-javascript">morgan.token('type', function (req, res) {
    return res.headers['content-type']
})
</code></pre>
<p>Morgan has predefined named format (<code>tiny</code>, <code>dev</code>, <code>short</code>, <code>combined</code>, <code>common</code>) strings containing a set of tokens and each named format has its specific token set and configuration. The token set for tiny is <code>':method :url :status :res[content-length] - :response-time ms'</code>. Morgan can accept these named formats as the value of the <code>format</code> argument.</p>
<p>Aside from accepting named formats, Morgan can also accept a token set (for example <code>':method :url :status :res[content-length] - :response-time ms'</code>) as the <code>format</code> argument. A third argument type that Morgan accepts as the <code>format</code> argument is a format function. A format function accepts three arguments and returns a string that forms the log line for each request. For example, the format function described below:</p>
<pre><code class="language-javascript">morgan(function (tokens, req, res) {
    return `method: ${tokens.method(req, res)}
path: ${tokens.url(req, res)}
code: ${tokens.status(req, res)}`
})
</code></pre>
<p>This will produce a log line output like:</p>
<pre><code class="language-bash">method: GET
path: /
code: 200
</code></pre>
<p><code>tokens.method</code>, <code>tokens.url</code> and <code>tokens.status</code> are examples of functions on the <code>morgan</code> object that can generate values to be logged. To illustrate, the table below shows sample token methods, their token and sample output values:</p>
<table>
<thead>
<tr>
<th>Token method</th>
<th>Token</th>
<th>Sample output</th>
</tr>
</thead>
<tbody><tr>
<td>method</td>
<td><code>“:method”</code></td>
<td>GET</td>
</tr>
<tr>
<td>url</td>
<td><code>“:url”</code></td>
<td>/</td>
</tr>
<tr>
<td>status</td>
<td><code>”:status”</code></td>
<td>200</td>
</tr>
</tbody></table>
<p>The next sections of this article explain how Morgan works under the hood. To follow along, open up <a href="https://github.com/expressjs/morgan/blob/master/index.js">Morgan’s index.js file on GitHub</a>.</p>
<h2 id="heading-what-happens-when-morgan-is-initialised">What Happens When Morgan is Initialised?</h2>
<p>When Morgan is initialised, it makes a copy of the arguments provided to it. For arguments that were not provided, Morgan sets default values for them. For instance, if no <code>format</code> string argument was provided, Morgan uses the <code>'default'</code> named format and logs a deprecation notice afterwards with a suggested fix.</p>
<p>Morgan then sets up the <code>formatLine</code> function - the function that creates and returns the log line for a request when executed. How does it create the log line?</p>
<p>First, Morgan checks if <code>format</code> is a format function. If it is, the format function is assigned to <code>formatLine</code> and next, Morgan sets up the output stream. If <code>format</code> is not a function, it is passed as an argument to <code>getFormatFunction</code>. <code>getFormatFunction</code> accepts <code>format</code> and looks up Morgan’s object store to check if <code>format</code> is:</p>
<ul>
<li><p>One of Morgan’s named formats or a user-defined named format created via <code>morgan.format</code></p>
</li>
<li><p>A token set</p>
</li>
</ul>
<p>If it is neither of the two, Morgan uses the <code>default</code> named format.</p>
<pre><code class="language-javascript">function getFormatFunction (name) { // `name` is also `format`
  var fmt = morgan[name] || name || morgan.default

  return typeof fmt !== 'function'
    ? compile(fmt)
    : fmt
}
</code></pre>
<p>If the named format corresponds to a format function after the lookup, Morgan returns the format function, which is then assigned to <code>formatLine</code>, else, it corresponds to a token set. Morgan compiles the token set into a format function through the <code>compile</code> function - one of the most important functions in the Morgan package.</p>
<h3 id="heading-how-the-compile-function-works">How the <code>compile</code> Function Works</h3>
<p>The <code>compile</code> function accepts a token set and returns a function that has the interface of a format function. How does it do this?</p>
<p>With the JavaScript <code>replace</code> method, it uses a RegEx to search for all occurrences of a token in the token set and replaces each occurrence. If the token set is <code>':method :res[content-length] - :response-time ms'</code> , the RegEx <code>replace</code> method replaces the tokens as illustrated in the table below:</p>
<table>
<thead>
<tr>
<th>name</th>
<th>arg</th>
<th>replacement string</th>
</tr>
</thead>
<tbody><tr>
<td>‘method’</td>
<td><code>undefined</code></td>
<td>`(tokens["method"](req, res)</td>
</tr>
<tr>
<td>‘res’</td>
<td><code>’content-length’</code></td>
<td>`(tokens["res"](req, res, "content-length")</td>
</tr>
<tr>
<td>‘response-time’</td>
<td>undefined</td>
<td>`(tokens["response-time"](req, res)</td>
</tr>
</tbody></table>
<p>The result of the RegEx replace is prefixed with <code>"use strict"\n return ""</code> and ends up producing the string below:</p>
<pre><code class="language-plaintext">"use strict" 
    return "" +  
    (tokens["method"](req, res) || "-") + " " +   
    (tokens["res"](req, res, "content-length") || "-") + " - " + 
    (tokens["response-time"](req, res) || "-") + " ms"
</code></pre>
<p>The string above is used to create a format function using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function">Function constructor</a> and returned as:</p>
<pre><code class="language-javascript">function (tokens, req, res) {
  "use strict"
  return "" +
    (tokens["method"](req, res) || "-") + " " +
    (tokens["res"](req, res, "content-length") || "-") + " - " +
    (tokens["response-time"](req, res) || "-") + " ms"
}
</code></pre>
<p>The format function is eventually stored in <code>formatLine</code>.</p>
<p>When <code>formatLine</code> is executed with <code>morgan</code> as the <code>tokens</code> argument, it will create a log line. In the case of the sample token set, it will create a log line that will look like GET 20 - 1.233 ms.</p>
<p>After creating the <code>formatLine</code> function, Morgan uses the <code>createBufferStream</code> function to set up the streaming of the log lines created to the preferred output if set by <code>options.stream</code>. If <code>options.stream</code> is not set, it uses <code>process.stdout</code>.</p>
<p>Morgan does all this setting up so that it can create log lines quickly on capturing a request. It will be inefficient to do all of these for each request.</p>
<h2 id="heading-what-happens-when-morgan-captures-a-request">What Happens When Morgan Captures a Request?</h2>
<p>When Morgan captures a request, it stores the IP address of the client using the <code>getip</code> function. Next, it stores the time that the request was triggered in the <code>startAt</code> property of the request object.</p>
<p>Then Morgan tries to generate the log line for the request and log it by executing the <code>logRequest</code> function. Morgan checks if the log line should be output on request, and if it should, Morgan executes <code>logRequest</code> and executes <code>next</code> thereafter to pass the request to the next middleware.</p>
<pre><code class="language-javascript">if (immediate) {
  logRequest()
} else {
  onHeaders(res, recordStartTime)
  onFinished(res, logRequest)
}

next()
</code></pre>
<p>If the log output should be created on response, Morgan registers two functions on the response object event listeners:</p>
<ul>
<li><p><strong>An function to be run when headers start to be written to the response object</strong>: When this listener is triggered, it records the time when headers start to be written to the response object as <code>_startAt</code> and <code>startTime</code>. These values are used to calculate the response time and the total time of the request.</p>
</li>
<li><p><strong>A function to be run when the request closes, finishes or errors</strong>: It executes <code>logRequest</code> when this event occurs.  </p>
<p>Just when Node.js starts sending a response to the client, a <code>_startAt</code> property – the time when the response starts getting sent – is attached to the response object. The absolute difference between <code>_startAt</code> on the request object and <code>_startAt</code> on the response object is the response time of the request and can be seen through ":response-time".  </p>
<p>":total-time" is the total time taken from when the request was received to when the response was completely sent. In practice, total-time will be equal to or slightly greater than response-time, depending on how long it takes to write the response body to the stream after the response has started.</p>
</li>
</ul>
<p>Within <code>logRequest</code>, Morgan checks the value of the <code>skip</code> option. If it is a function, it is executed and if it returns <code>true</code>, Morgan doesn’t create a log output for the request and it exits.</p>
<pre><code class="language-javascript">function logRequest () {
  if (skip !== false &amp;&amp; skip(req, res)) {
    debug('skip request')
    return
  }

  var line = formatLine(morgan, req, res)

  if (line == null) {
    debug('skip line')
    return
  }

  stream.write(line + '\n')
};
</code></pre>
<p>If <code>skip</code> is <code>false</code> or executing it evaluates to <code>false</code>, Morgan generates the log line for the request using <code>formatLine</code>. If the log line is <code>null</code>, Morgan exits, else it sends the log line to the output medium and exits.</p>
<h2 id="heading-next-steps">Next Steps</h2>
<p>You have learned how the Morgan Express middleware outputs logs. You now have foundational skills to pick up another middleware or Node.js library like helmet or cors that you use and study it to see how it works. Choose one, study it, write about it, and share it with others.</p>
<p>If you have any questions, you can connect with me on <a href="https://www.linkedin.com/in/orimdominicadah/">LinkedIn</a>. I’ll be happy to respond.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Libraries to Use in Your Projects in 2024 ]]>
                </title>
                <description>
                    <![CDATA[ If you're building applications with React, you should learn how to use some helpful libraries that'll make it easier to add the features you need. For example, to add features like authentication or styling, you'll need to find a good third-party li... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-libraries-to-use-in-your-projects/</link>
                <guid isPermaLink="false">66d037caccf811d3117aeeef</guid>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Fri, 02 Feb 2024 18:42:15 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/react-libraries-2024.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're building applications with React, you should learn how to use some helpful libraries that'll make it easier to add the features you need.</p>
<p>For example, to add features like authentication or styling, you'll need to find a good third-party library to handle it.</p>
<p>In this comprehensive guide, I'm going to show you all of the libraries that I would recommend you use in 2024 to build fast, reliable React apps with ease.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-react-framework">React Framework</a></li>
<li><a class="post-section-overview" href="#heading-package-manager">Package Manager</a></li>
<li><a class="post-section-overview" href="#heading-css-amp-ui-libraries">CSS &amp; UI Libraries</a></li>
<li><a class="post-section-overview" href="#heading-state-management">State Management</a></li>
<li><a class="post-section-overview" href="#heading-data-fetching">Data Fetching</a></li>
<li><a class="post-section-overview" href="#heading-routing">Routing</a></li>
<li><a class="post-section-overview" href="#heading-authentication">Authentication</a></li>
<li><a class="post-section-overview" href="#heading-database-amp-orm">Database &amp; ORM</a></li>
<li><a class="post-section-overview" href="#heading-dates-amp-times">Dates &amp; Times</a></li>
<li><a class="post-section-overview" href="#heading-forms">Forms</a></li>
<li><a class="post-section-overview" href="#heading-drag-amp-drop">Drag &amp; Drop</a></li>
<li><a class="post-section-overview" href="#heading-mobile-apps">Mobile Apps</a></li>
<li><a class="post-section-overview" href="#heading-deployment">Deployment</a></li>
<li><a class="post-section-overview" href="#heading-the-1-library-to-know">TypeScript</a></li>
<li><a class="post-section-overview" href="#heading-become-a-professional-react-developer">Become a Pro React Developer</a></li>
</ul>
<h2 id="heading-react-framework">🛠️ React Framework</h2>
<p>First of all, how do we even create our React app in 2024?</p>
<p>If you want a client-rendered React project, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-react-app-in-2024/">your best choice is <strong>Vite</strong></a>, which has displaced the deprecated Create React App tool.</p>
<p>If you're interested in building a server-rendered or full-stack React project, <strong>Next.js</strong> is the most complete and popular full-stack React framework. </p>
<p>Next.js version 13 introduced the app router, which gave us features like server components and server actions. These allow us to fetch data and render our React components on the server.</p>
<p>If some of Next.js's features are too complex or you don't understand how to use them, a great full-stack alternative for making dynamic and static sites is <strong><a target="_blank" href="https://remix.run/">Remix</a></strong>.</p>
<p>If you're making an application that you want to load quickly and largely serve static content, another great pick is <strong><a target="_blank" href="https://www.freecodecamp.org/news/learn-the-astro-web-framework/">Astro</a></strong>. Astro allows you to use React alongside other frameworks like Vue and Svelte (meaning it is “framework agnostic”) and is designed to ship the smallest amount of JavaScript necessary to the client, which results in very fast load times.</p>
<h2 id="heading-package-manager">📦 Package Manager</h2>
<p>To install all of these libraries listed in this guide, you're going to need something called a package manager.</p>
<p>If you have Node.js installed, which is necessary to run a React project locally on your computer, you can simply use <strong>NPM</strong>, which is still a great choice in 2024. There are other alternatives to NPM, including Yarn and PNPM.</p>
<p>The newest alternative, which is quickly becoming very popular in the JavaScript world, is <strong><a target="_blank" href="https://www.freecodecamp.org/news/learn-bun-a-faster-node-js-alternative/">Bun</a></strong>. Bun is both a JavaScript runtime like Node as well as a package manager and is marketed as a faster alternative to Node and NPM.</p>
<h2 id="heading-css-amp-ui-libraries">🎨 CSS &amp; UI Libraries</h2>
<p>Now that you've got your project set up and your libraries installed, how are you going to style your React projects?</p>
<p>All of the frameworks I've mentioned above include basic CSS support. It's perfectly fine in 2024 if you want to stick to just styling your React projects with <strong>plain CSS</strong>.</p>
<p>You can use CSS style sheets or CSS modules, but perhaps the most popular choice at the moment in terms of pure styling is to use <strong><a target="_blank" href="https://www.freecodecamp.org/news/learn-tailwind-css/">Tailwind CSS</a></strong>. Tailwind CSS does come with a few setup steps, but it allows you to chain pre-made classes together to quickly add styles directly within your component files.</p>
<p><strong><a target="_blank" href="https://ui.shadcn.com/">ShadCN</a></strong> is a very popular UI library for 2024 that combines Tailwind CSS with a component library called Radix UI. Component libraries like Radix allow you to easily add components without coding them yourself. </p>
<p>ShadCN has become popular due to the greater control it provides over how your components look with the help of Tailwind CSS.</p>
<p>There are a bunch of other very popular functional component libraries as well. <strong>Material UI</strong> still remains popular, as well as others like <strong>Mantine</strong> and <strong>Chakra UI</strong>. Which one you pick really depends on how you want your final app to look. I'd recommend trying out a bunch of these UI libraries and see which one you like best.</p>
<h2 id="heading-state-management">💽 State Management</h2>
<p>React has built-in tools such as <a target="_blank" href="https://www.freecodecamp.org/news/learn-react-usestate-hook-in-10-minutes/">useState</a> and <a target="_blank" href="https://www.freecodecamp.org/news/usereducer-hook-react/">useReducer</a> to manage your app state in basic applications. If you're using Next.js, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-urls-for-state-management-in-react/">state management has been moved to the URL</a> when working with server components. Despite these options, you may need a way to manage state in a more precise way.</p>
<p>You might have lots of pieces of state and want greater control over how state updates render your components. If so, you can reach for a dedicated state management library.</p>
<p>Libraries such as <strong>Zustand</strong>, <strong>Recoil</strong>, and <strong>Jotai</strong>, which are all very similar, allow you to manage state simply by declaring properties and methods on an object. This ultimately is the simplest way to handle state management across your app's components.</p>
<p>If I had to pick one state management library for all of my React projects in 2024, I would choose <strong><a target="_blank" href="https://www.npmjs.com/package/zustand">Zustand</a></strong>. It takes almost no time to learn how to use it. It also doesn't require you to add a provider component to your application, which makes it very convenient to use in any component you like.</p>
<h2 id="heading-data-fetching">🐕 Data Fetching</h2>
<p>State management and data fetching often go hand in hand. If you're building a client-rendered React app, you're likely going to need a data fetching library.</p>
<p>The best way to fetch data from a server in a React app in 2024 remains React Query or <strong>Tanstack Query</strong> as it's now called. TanStack Query gives you fine-grained control over not only fetching data, when to fetch and refetch it, caching, all through convenient custom hooks, as well as very easily change or mutate data.</p>
<p>Another solid alternative is <strong>SWR</strong>, which also offers a custom hook to handle queries and mutations, but it's far simpler in terms of what it offers. You can't go wrong with picking either one and fetching data and performing your HTTP requests with the fetch API.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-fetch-api-data-in-react/">Here's an article</a> that walks you through some of the most popular methods of data fetching in React (including Tanstack Query and SWR).</p>
<h2 id="heading-routing">🧭 Routing</h2>
<p>If you're using a framework like Next.js, Remix, or Astro, your routing is already taken care of. All of them come with built-in ways to create routes or pages in your project.</p>
<p>With a client-rendered React app such as one made with Vite or Create React App, you're going to need to pick a routing library. <strong><a target="_blank" href="https://www.freecodecamp.org/news/learn-react-router-6-full-course/">React Router</a></strong> still remains the most popular choice. It takes care of every routing need you might have. It’s also very advanced due to its data loading features with the <code>loader</code> prop. The <code>loader</code> prop allows you to fetch data for a given route without using an external library like React Query.</p>
<p>An up-and-coming library that appears to have equally good features is <strong><a target="_blank" href="https://tanstack.com/router/latest">Tanstack Router</a></strong>. The Tanstack Router was made to be fully type-safe and offer great defaults for data fetching just like React Router version 6 provides.</p>
<p>While Tanstack Router is a bit newer, you really can't go wrong with either choice, and it's a perfect pairing if you're already using Tanstack Query or SWR in your applications.</p>
<h2 id="heading-authentication">🔒 Authentication</h2>
<p>While authentication is something that's handled by the server side of our projects, it's worth knowing what libraries integrate best with React projects, both on the client and the server.</p>
<p>In 2024, <a target="_blank" href="https://www.freecodecamp.org/news/learn-supabase-open-source-firebase-alternative/"><strong>Supabase</strong> has emerged</a> as a very robust authentication solution and offers easy integration with React apps, both on the server, say, in a Next.js project, and on the client. In past years, Firebase was chosen for similar reasons, but it's harder to integrate on the server side of things.</p>
<p>If you're using Next.js, you have a ton of options available to you such as <strong>NextAuth</strong>, <strong>Clerk</strong>, and the newcomer <strong>Lucia</strong>. It's unfortunate that there isn't currently a built-in auth library for Next.js, but perhaps in the future there'll be one.</p>
<p>In the meantime, I'll personally be using Supabase and would highly recommend you check them out as well via their documentation.</p>
<h2 id="heading-database-amp-orm">🥞 Database &amp; ORM</h2>
<p>Much like authentication, your database is something that will and should speak largely to your server-side code.</p>
<p>Databases like Supabase and Firebase don't require that you have a server. You can get and change data directly in the client, and you can add security rules within your dashboard to make sure certain types of requests are allowed or not allowed according to users' authentication status and role.</p>
<p>Outside of these two options, if you're using a traditional server or a full-stack framework, there are countless options. In 2024, the general preference is clearly for SQL databases like MySQL or PostgreSQL over NoSQL databases like MongoDB or Firebase.</p>
<p>With your database, to talk to your database, you'll either use plain SQL or an ORM that allows you to use a custom query language. Popular options for ORMs include <strong>Prisma</strong> or <strong>Drizzle</strong>. Both of them allow you to generate type-safe code so that you know what data will be returned and both integrate very well with SQL or NoSQL databases of your choosing.</p>
<h2 id="heading-dates-amp-times">🕰️ Dates &amp; Times</h2>
<p>When you're working with JavaScript, it's always recommended to have a date library. JavaScript's date constructor is unpredictable and virtually impossible to work reliably with things like time zones.</p>
<p>There are a bunch of options, but I tend to gravitate to <strong>date-fns</strong> or <strong>day.js</strong>. Both are very small but extensive libraries that allow you to manipulate JavaScript dates either in the browser or on the back end. You can't go wrong with either one.</p>
<h2 id="heading-forms">📋 Forms</h2>
<p>You may not need a form library in most cases if you're just building an app with a simple sign-up form, using the <code>required</code> prop on your inputs is usually all you need.</p>
<p>If you're building something more complex and have a lot of forms, <strong><a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-forms-in-react-using-react-hook-form/">React Hook Form</a></strong> is a fully featured form library that allows you to validate form input and display errors with very minimal code.</p>
<p>Other form libraries, such as Formik and React Final Form, will give you the same functionality, but React Hook Form is a bit better because it has a more modern API based on hooks and usually requires less code.</p>
<h2 id="heading-drag-amp-drop">☔️ Drag &amp; Drop</h2>
<p>When it comes to adding drag and drop to your application, you almost certainly need a third-party library. The most popular choice in the past has been React Beautiful DnD. As of 2024, it is no longer receiving regular updates.</p>
<p>Going forward, a solid replacement for drag and drop is to use <strong><a target="_blank" href="https://dndkit.com/">DnD Kit</a></strong>. It's lightweight, very flexible, and the documentation includes a bunch of super helpful examples covering every use case you might have when implementing drag and drop.</p>
<h2 id="heading-mobile-apps">📱 Mobile Apps</h2>
<p>If you want to build a mobile app, the library to do so for React developers has always been <a target="_blank" href="https://www.freecodecamp.org/news/react-native-full-course-android-ios-development/">React Native</a>. There are some exciting libraries pushing the boundaries of React Native to extend to the web.</p>
<p><a target="_blank" href="https://expo.dev/"><strong>Expo</strong> is a tool similar to Vite</a>, but for making mobile React apps. It has great features like fast refresh, and with Expo Go, you can easily run your project on your own device as you develop it. Expo is making it easier to take your mobile code base and also deploy it to the web.</p>
<p>This is the end goal of other projects such as <strong><a target="_blank" href="https://tamagui.dev/">Tamagui</a></strong>, which you should also check out if you want to make a real native app that runs on Android, iOS, and the web.</p>
<p>If you have a React app that you've already written to run in the browser, the fastest way to have it run as a native app and launch it on the Apple App Store or Google Play Store is to use <strong><a target="_blank" href="https://capacitorjs.com/">Capacitor.js</a></strong>.</p>
<h2 id="heading-deployment">🚀 Deployment</h2>
<p>There are more ways than ever to deploy your React app. <a target="_blank" href="https://www.freecodecamp.org/news/deploy-react-app/">Vercel is probably the easiest platform</a> to deploy your React app with, whether it's client-rendered or server-rendered. They support just about every framework you can think of, including non-JavaScript languages. They have a generous hobby plan, and competitors in the same space include Netlify and Cloudflare Pages.</p>
<p>Cloudflare Pages might be a little bit trickier to set up, especially if you have a full-stack React project, but it is the most generous in terms of price out of all of these options. If you don't mind paying for a server, you can use something like Railway or Render, which is great to deploy to if you have a server that is separate from your React app.</p>
<h2 id="heading-the-1-library-to-know">✨ The #1 Library To Know</h2>
<p>Finally, the number one essential library you should know if you're a React developer in 2024 is <a target="_blank" href="https://www.freecodecamp.org/news/learn-typescript-beginners-guide/">TypeScript</a>. All of the frameworks I've mentioned include options to build a React app with TypeScript.</p>
<p>TypeScript is a tool that allows you to detect type errors in your JavaScript code to help you prevent runtime errors. You can build all of your React projects with just JavaScript, but at some point, you're going to either see the benefits of using TypeScript yourself or be looking at a codebase that has TypeScript in it.</p>
<p>I'd highly recommend you set aside some time to learn TypeScript. It's the most essential, the most in-demand tool to know as a React developer and can greatly improve your overall code quality.</p>
<h2 id="heading-become-a-professional-react-developer">🏆 Become a Professional React Developer</h2>
<p>Looking for the ultimate resource to learn React from start to finish?</p>
<p>✨ <strong><a target="_blank" href="https://www.thereactbootcamp.com">Introducing: The React Bootcamp</a></strong></p>
<p>The bootcamp features every resource to help you succeed with React:</p>
<ul>
<li>🎬 200+ in-depth videos</li>
<li>🕹️ 100+ hands-on React challenges</li>
<li>🛠️ 5+ impressive portfolio projects</li>
<li>📄 10+ essential React cheatsheets</li>
<li>🥾 A complete Next.js bootcamp</li>
<li>🖼️ A complete series of animated videos</li>
</ul>
<p>Click below to try the React Bootcamp for yourself.</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a><br><em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Documentation Libraries to Help You Write Good Docs ]]>
                </title>
                <description>
                    <![CDATA[ Good project documentation is key to success for every company, startup, or individual project. Without documentation, it's much harder for new developers or others to use your project. In this article, I'll discuss some of my favourite libraries you... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/documentation-libraries-to-help-you-write-good-docs/</link>
                <guid isPermaLink="false">66d038a215ea3036a953996a</guid>
                
                    <category>
                        <![CDATA[ documentation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rajdeep Singh ]]>
                </dc:creator>
                <pubDate>Thu, 01 Feb 2024 15:45:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Documentation-Libraries-to-Help-You-Write-Good-Docs.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Good project documentation is key to success for every company, startup, or individual project. Without documentation, it's much harder for new developers or others to use your project.</p>
<p>In this article, I'll discuss some of my favourite libraries you can use for building your documentation site. </p>
<p>And don't worry if you don't have that much experience creating documentation yet. Whether you've built a simple documentation site for a small startup or personal project or a vast and complex site for a large company, these libraries will be helpful to you.</p>
<h2 id="heading-tips-for-writing-good-documentation">Tips for Writing Good Documentation</h2>
<p>Before we get into the libraries themselves, though, there are some critical points you'll want to keep in mind when you're building your documentation sites.</p>
<h3 id="heading-make-sure-your-documentation-is-clean-and-easily-recognizable">Make sure your documentation is clean and easily recognizable.</h3>
<p>Ensure your documentation folder is separate in the mono repo, even if you use a <a target="_blank" href="https://www.accenture.com/us-en/blogs/software-engineering-blog/how-to-choose-between-mono-repo-and-poly-repo">poly repo</a> or separate repository.</p>
<p>This separate repository should contain only the markdown and mdx files. This will help your contributors easily be able to recognize which folder is for documentation.</p>
<p>A great example of clean documentation is <a target="_blank" href="https://github.com/vercel/next.js">Next.js</a>, which has a separate folder for documentation, as you can see below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/nextjs-documentation.png" alt="Nextjs documentation is easy to recognize in mono repo, and it contains only the markdown." width="600" height="400" loading="lazy">
<em>Nextjs documentation is <strong>easily recognizable</strong> in the mono repo and contains only the Markdown.</em></p>
<h3 id="heading-provide-clear-guidelines-in-your-documentation">Provide clear guidelines in your documentation.</h3>
<p>To improve documentation quality, you should write clear guidelines for technical writers. For example,</p>
<ol>
<li>what front matter is required in the file markdown?</li>
<li>Which spelling conventions are correct – for example, do you accept javascript (all lowercase) or JavaScript (with the proper casing)? Or both?</li>
<li>Which commands are needed for formatting and linting before applying a pull request?</li>
</ol>
<p>A pro tip for documentation sites is mentioning additional resources, such as tutorials, courses, and article links for new contributors.</p>
<p>The best examples of clear guidelines are <a target="_blank" href="https://nextjs.org/docs/community/contribution-guide">Next.js</a> and the <a target="_blank" href="https://github.com/sindresorhus/awesome/blob/main/pull_request_template.md">Awesome</a> Repository. Both have clear guidelines for documentation.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/docs-guidelines.png" alt="Nextjs has clear guidelines for documentation." width="600" height="400" loading="lazy">
<em>Nextjs has clear guidelines for documentation.</em></p>
<h3 id="heading-make-it-easy-to-contribute">Make it easy to contribute.</h3>
<p>When contributors want to help out with your project, many of them just want to focus on writing. Most technical writers or documentation contributors do not have time to install and set up your project locally.</p>
<p>Many online IDEs are available these days, and more are coming, such as GitHub Dev, VS Code Dev, Code Sandbox, and GitLab.</p>
<p>Nowadays, many developers and contributors update the documentation file using GitHub's inbuilt IDE or other online IDEs and create pull requests without installing your repository locally.</p>
<p>So, you should at least configure your project to work with one of the online IDEs. It helps to save time and improves the productivity of the technical writer and contributor.</p>
<h2 id="heading-helpful-documentation-libraries">Helpful Documentation Libraries:</h2>
<ol>
<li><a class="post-section-overview" href="#heading-nextra">Nextra</a></li>
<li><a class="post-section-overview" href="#heading-docusaurus">Docusaurus</a></li>
<li><a class="post-section-overview" href="#heading-lume">Lume</a></li>
<li><a class="post-section-overview" href="#docsifyjs">Docsify.js</a></li>
<li><a class="post-section-overview" href="#heading-markdoc">Markdoc</a></li>
<li><a class="post-section-overview" href="#content-layer">Content layer</a></li>
<li><a class="post-section-overview" href="#git-book">Git book</a></li>
<li><a class="post-section-overview" href="#outstatic-CMS">Outstatic CMS</a></li>
<li><a class="post-section-overview" href="#heading-code-doc">Code doc</a></li>
<li><a class="post-section-overview" href="#heading-front-matter">Frontmatter</a></li>
</ol>
<h2 id="heading-nextra">Nextra</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/nextra.png" alt="Nextra" width="600" height="400" loading="lazy">
<em>Nextra</em></p>
<p><a target="_blank" href="https://nextra.site"><strong>Nextra</strong></a> is an open-source, simple, powerful, and flexible site generation framework built on Nextjs. Nextra was created by developers at <a target="_blank" href="https://vercel.com/">Vercel</a>.</p>
<p>Nextra helps manage your content with MDX. With Nextra, you can build both small and large-scale documentation websites.</p>
<p>Nextra comes with various built-in features, such as:</p>
<ol>
<li>Organizing content with file-system routing.</li>
<li>Theme Toggling (Light to Dark theme)</li>
<li>Inbuilt search</li>
<li>Multiple layouts</li>
<li>Syntax highlighting</li>
<li>Multiple languages (Internationalized) </li>
<li>Custom themes</li>
</ol>
<p>Nextra also helps to save you time and energy, as you can directly work on your documentation without writing a single line of code. You also do not have to maintain the code base. This lets you focus on documentation writing.</p>
<h3 id="heading-cons">Cons</h3>
<ol>
<li>There are fewer customizations you can make with Nextra</li>
<li>Nextra comes with more limited features</li>
</ol>
<p>To learn more about Nextra, <a target="_blank" href="https://medium.com/frontendweb/how-to-create-a-markdown-blog-with-nextjs-and-nextra-2985362f9708">you can check out the tutorial I wrote about it</a>. </p>
<h2 id="heading-docusaurus">Docusaurus</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/docusaurus.png" alt="docusaurus" width="600" height="400" loading="lazy">
<em>docusaurus</em></p>
<p><strong><a target="_blank" href="https://docusaurus.io">Docusaurus</a></strong> is an open-source static-site generator built and maintained by the Meta team. Docusaurus helps you write and manage your large and small documentation and blog websites.</p>
<p>Docusaurus comes with various built-in features, such as:</p>
<ol>
<li>It's easy to configure</li>
<li>You can customize your site's layout, design, and features with React components</li>
<li>You can write content in Markdown and MDX. </li>
<li>It handles localization well</li>
<li>You can manage versioning</li>
<li>It has a built-in plugins ecosystem </li>
<li>You can customize and change themes</li>
<li>There's good client API support</li>
<li>It has TypeScript and JSDoc support</li>
<li>You can create both a blog and a documentation website with Docusaurus.</li>
</ol>
<p>Docusaurus is a well-established library used by many companies. And one of the best parts about Docusaurus is that it has a more significant number of active contributors, so the tool is well-maintained. </p>
<h3 id="heading-cons-1">Cons</h3>
<ol>
<li>Customizing and managing a large documentation website with Docusaurus can be tricky because of complex Docusaurus configuration options.</li>
<li>Configuring Docusaurus blog plugins can be a massive headache because of the configuration. Lastly, Docusaurus can not support categories for articles.</li>
<li>Docusaurus does not come with search functionality. To enable search functionality, you have to depend on a third-party service. Confirming the third-party search functionality is sometimes not an easy task.</li>
</ol>
<h2 id="heading-lume">Lume</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/lume.png" alt="lume" width="600" height="400" loading="lazy">
<em>lume</em></p>
<p><a target="_blank" href="https://lume.land/"><strong>Lume</strong></a> is a fast and flexible open-source static site generator based on Deno. You can build documentation sites, a portfolio, a company website, or a blog with Lume. </p>
<p>Lume comes with various built-in features, such as:</p>
<ol>
<li>Processors</li>
<li>Plugins support</li>
<li>Multiple file formats, like <code>markdown</code>, <code>yaml</code>, <code>JavaScript</code>, <code>typescript</code>, <code>jsx</code> and <code>nunjucks</code>, and it's easy to extend with other features.</li>
<li>Inbuilt search and pagination support</li>
<li>It supports multiple template engines (JSX, Preact, MDX, Remark, and so on)</li>
<li>Ability to create relationships between two pages</li>
</ol>
<p>You can customize so many things with Lume that you may not even be able to imagine until you try it out. </p>
<h3 id="heading-cons-2">Cons</h3>
<ol>
<li>Starting with Lume is not an easy task. It's a steeper learning curve, and it may take some time to get enough experience to use it effectively – so Lume is not the best for beginners. </li>
<li>You need a third-party service to enable search functionality on your website.</li>
<li>Since there's so much customization possible, sometimes you might get confused about what you've chosen.</li>
</ol>
<p>Still, Lume gives you more control and power over your documentation site, so if you're willing to take the time to learn it, I think you'll enjoy it. You can <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-static-blog-with-lume/">read my in-depth tutorial on freeCodeCamp to learn more about Lume</a>.</p>
<h2 id="heading-docsifyjs">Docsify.js</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/docsify.png" alt="Docsify.js" width="600" height="400" loading="lazy">
<em>Docsify.js</em></p>
<p><a target="_blank" href="https://docsify.js.org"><strong>Docsify</strong></a> is an open-source, simple, and lightweight documentation generator. It's heaven for developers with a C, Rust, and C++ background. You can start using Docsify without having any knowledge of JavaScript or React.js. </p>
<p>Docsify comes with a number of built-in features, such as:</p>
<ol>
<li>It's simple and lightweight</li>
<li>It's easy to customize and configure</li>
<li>You can extend Docsify's functionally with built-in plugin API</li>
<li>It has multiple themes support</li>
<li>There's emoji support</li>
<li>It supports server-side rendering</li>
</ol>
<p>In Docsify, you can focus on writing documentation without worrying about maintaining the codebase. </p>
<p>You can start your documentation site within minutes. You can deploy the Docsify website with one click on GitHub pages.</p>
<p>The most important thing about Docsify is that you don't need prior knowledge to work with Docsify or any other tools or configuration.</p>
<h3 id="heading-cons-3">Cons</h3>
<ol>
<li>Docsify comes with fewer features, but customization options are available.</li>
<li>Docsify only has a few themes and plugins available on the internet.</li>
<li>Most of the themes you find on the internet are outdated in terms of their UI. </li>
</ol>
<p>To learn more about Docsify, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-write-good-documentation-with-docsify/">read my in-depth tutorial on freeCodeCamp</a>. </p>
<h2 id="heading-markdoc">Markdoc</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/markdoc.png" alt="Mark doc" width="600" height="400" loading="lazy">
<em>Mark doc</em></p>
<p><strong><a target="_blank" href="https://markdoc.dev/">Markdoc</a></strong> is an open-source, powerful, and flexible Markdown-based framework. Markdoc is built and maintained by the Stripe team. With Markdoc, you can develop your personal blogs and documentation sites. </p>
<p>Markdoc comes with several built-in features, such as:</p>
<ol>
<li>It's lightweight</li>
<li>There's built-in syntax validation</li>
<li>It has support for partials</li>
<li>You can extend Markdoc with custom functions</li>
<li>It supports tags </li>
<li>You can customize styles with annotations</li>
<li>It supports variables and attributes</li>
</ol>
<p>Markdoc is developer and writer-friendly. You can build interactive documentation and static content sites using pure HTML, Next.js, and React.js. </p>
<h3 id="heading-cons-4">Cons</h3>
<ol>
<li>To work with makdoc, you must write the entire website code from scratch.</li>
<li>Markdoc is not for beginner developers. You must know some advanced JavaScript and React concepts when working with Markdoc.</li>
</ol>
<h2 id="heading-contentlayer">Contentlayer</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/content-layer.png" alt="Content layer" width="600" height="400" loading="lazy">
<em>Content layer</em></p>
<p><strong><a target="_blank" href="https://contentlayer.dev/">Contentlayer</a></strong> is an open-source content SDK that validates and transforms your content into type-safe JSON data so you can easily use it with your existing frameworks, such as Next.js.</p>
<p>The best part about Contentlayer is that you can build a type-safe schema for your blog and documentation. </p>
<p>Contentlayer works similarly to Markdoc – you must write the documentation and maintain the code base.</p>
<p>There are many helpful features, but here are a few:</p>
<ol>
<li>It's framework agnostic</li>
<li>It's built to be very fast</li>
<li>Makes it easier to parse content on your site</li>
<li>You can use JavaScript/TypeScript – no new query language required</li>
<li>It has automatic content and frontmatter validation</li>
</ol>
<h3 id="heading-cons-5">Cons</h3>
<ol>
<li>Contentlayer comes with support for a limited number of frameworks.</li>
<li>You must write website code from scratch to work with the Content layer.</li>
</ol>
<p>Read <a target="_blank" href="https://officialrajdeepsingh.medium.com/list/create-static-blog-with-nextjs-and-markdown-34cbab11b5ed">my in-depth tutorial on Medium</a> to learn more about Contentlayer<a target="_blank" href="https://officialrajdeepsingh.medium.com/list/create-static-blog-with-nextjs-and-markdown-34cbab11b5ed">.</a> </p>
<h2 id="heading-gitbook">Gitbook</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/gitbook.png" alt="Git book" width="600" height="400" loading="lazy">
<em>Git book</em></p>
<p><a target="_blank" href="https://www.gitbook.com/"><strong>Gitbook</strong></a> is not open-source, but it comes with free and paid plans. Gitbook is built and designed to manage documentation. You can even develop your API and service documentation website with Gitbook. </p>
<p>Git Book comes with various built-in features, such as:</p>
<ol>
<li>It has a no-code solution</li>
<li>You can easily integrate it with other applications</li>
<li>You can customize and change the theme with one click</li>
<li>It's easy to use it to collaborate with your team</li>
<li>It has a powerful block-based editor</li>
<li>You can embed code your demo code with code sandbox IDE</li>
<li>It has built-in search support</li>
<li>It has built-in SEO, sitemap and caching &amp; CDN support</li>
</ol>
<p>Gitbook comes with a no-code solution – you do need to write a single line of code to create a documentation site. Gitbook provides you with a modern feel for creating documentation without writing code.</p>
<p>You can integrate Gitbook with other services like GitHub. And you do not need to worry about deploying Gitbook – it does all the hard work for you. With one click, you can focus on writing and designing or changing themes in your documentation in Gitbook.</p>
<h3 id="heading-cons-6">Cons</h3>
<ol>
<li>Many features like theme customization and team management come with the paid plan.</li>
</ol>
<h2 id="heading-outstatic-cms">Outstatic CMS</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/outstatic-cms.png" alt="Outstatic CMS" width="600" height="400" loading="lazy">
<em>Outstatic CMS</em></p>
<p><a target="_blank" href="https://outstatic.com/"><strong>Outstatic CMS</strong></a> is a Next.js-based open-source static CMS that helps you manage your content with the help of GitHub. </p>
<p>Outstatic cms comes with several built-in features, such as:</p>
<ol>
<li>There's an AI completion option</li>
<li>You can manage your content with custom fields</li>
<li>It's quick and easy to setup</li>
<li>You don't need a database</li>
<li>It's a modern content editor</li>
</ol>
<p>Using Outstatic CMS, you can easily publish, update, and remove the content using the dashboard and editor. This is helpful if you don't know how to use Markdown and some who depend on grammar tools, for example, Grammarly, Turnitin, Quillbot, and so on.  </p>
<p>Outstatic CMS only works with Next.js and GitHub. Outstatic directly creates content inside your GitHub repository using Github API.</p>
<h3 id="heading-cons-7">Cons</h3>
<ol>
<li>You need to write website code design to build and test from scratch.</li>
<li>Outstatic CMS does not work offline.</li>
</ol>
<p><a target="_blank" href="https://medium.com/frontendweb/start-the-static-blog-website-with-outstatic-cms-in-2024-a909c12318f0">Read my in-depth tutorial on Medium</a> to learn more about it. </p>
<h2 id="heading-code-doc">Code doc</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/codedoc-1.png" alt="Code Doc" width="600" height="400" loading="lazy">
<em>Code Doc</em></p>
<p><strong><a target="_blank" href="https://codedoc.cc">Code Doc</a></strong> is an open-source, simple, lightweight, easy-to-configure documentation generator tool that helps create beautiful and modern software documentation websites within minutes. </p>
<p>Code Doc comes with several built-in features, such as:</p>
<ol>
<li>It's simple and lightweight</li>
<li>It's easy to customize and configure</li>
<li>It has an enhanced markdown and code block experience</li>
<li>It has integrated search and dark mode</li>
<li>You can extend the functionality with the Code doc Plugin API</li>
<li>You can build your own custom components</li>
</ol>
<p>With code doc, you focus on your documentation writing rather than writing and maintaining your codebase.  But Code Doc is easy to customize and configure. You do not need prior knowledge to use it.</p>
<p>The most important thing about Code Doc is that it has more modern UI features than Docsify.</p>
<h3 id="heading-cons-8">Cons</h3>
<ol>
<li>A Code Doc project or repository cannot be actively maintained by its developer.</li>
</ol>
<h2 id="heading-front-matter">Front Matter</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Front-Matter.png" alt="Front Matter CMS" width="600" height="400" loading="lazy">
<em>Front Matter CMS</em></p>
<p><a target="_blank" href="https://frontmatter.codes/"><strong>Front Matter</strong></a> is a Headless CMS right in your Visual Studio Code. Front matter gives a helping hand to technical writers and coders. </p>
<p>Front Matter cms comes with several built-in features, such as:</p>
<ol>
<li>It works seamlessly with any static site generator</li>
<li>It's fully configurable</li>
<li>It brings the features/benefits of a CMS to your VS Code </li>
<li>You get a full site/page preview within VS Code</li>
<li>You can manage your content, media, snippets, and data with VS Code</li>
<li>You can edit your metadata</li>
<li>You can check your SEO status in VS Code</li>
</ol>
<p>The tool works inside VS Code, letting you edit, write, update, and delete documentation in your VS Code without ever having to leave the editor. You can write your documentation using Markdown and VS Code. </p>
<p>You can also edit your metadata (front matter like title, description, tag, date, and so on) and check the SEO status in VS Code.</p>
<p>The best part is integrating Front Matter with other tools or libraries, such as Nextra, Docusaurus, Lume, and Docsify, to enhance the developer's writing experience using VS Code.</p>
<h3 id="heading-cons-9">Cons</h3>
<ol>
<li>You cannot use Front Matter CMS with other IDEs like Vim, Neovim, Atom, Sublime Text, JetBrains IDEs, and so on.</li>
<li>Front Matter CMS is not useful for everyone. Front matter CMS Only targets software developers who will find it very useful.</li>
</ol>
<p><a target="_blank" href="https://medium.com/frontendweb/what-is-frontmatter-headless-cms-and-how-to-use-it-with-nextjs-b764b76718ea">Read my in-depth tutorial on Medium</a> to learn more about the Front Matter CMS.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Without documentation, your product or service will never be successful. Spend equal time on one code base and as well on documentation. </p>
<p>For quick and short-term documentation, I recommended Git Book, nextra, and Docusaurus. If you have time and teams, go with Outstatic CMS, Content layer, and Mark doc. Lastly, you do not know JavaScript and reactjs. You can go with Git Book and Docsify.</p>
<p>I am not recommending the Code Doc library due to inactive maintenance by its developer. I'm not sure if the code doc was abandoned by its developer or not.</p>
<p>You can hire me as a freelance developer with <a target="_blank" href="https://www.upwork.com/freelancers/~01a4e8ba7a41795229">Upwork</a> and other updates. Follow me on <a target="_blank" href="https://twitter.com/Official_R_deep">Twitter (X)</a> and <a target="_blank" href="https://officialrajdeepsingh.medium.com/">Medium</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ An Overview of Prismane  – An Open-Source React UI Library ]]>
                </title>
                <description>
                    <![CDATA[ Prismane is a free, comprehensive, have-it-all React UI library that provides a broad array of hooks, components, and form validators to help you build beautiful and functional user interfaces. Prismane was designed with performance in mind, ensuring... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/prismane-react-ui-library/</link>
                <guid isPermaLink="false">66ba612ae30fab558579a156</guid>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ valentine Gatwiri ]]>
                </dc:creator>
                <pubDate>Wed, 27 Sep 2023 12:52:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/09/Screenshot-from-2023-09-26-15-16-49.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Prismane is a free, comprehensive, have-it-all React UI library that provides a broad array of hooks, components, and form validators to help you build beautiful and functional user interfaces.</p>
<p>Prismane was designed with performance in mind, ensuring lightning-fast loading times for a better user experience.</p>
<p>In this article, you will learn what Prismane is, its cons and pros, how to set up our development environment, and how to build applications using Prismane.</p>
<h2 id="heading-key-features-of-prismane-ui">Key Features of Prismane UI</h2>
<p>The library is a large collection of 107+ React components, including buttons, inputs, menus, tables, and more. This enables developers to not reinvent the wheel every time they need common UI elements. Plus, you can customize them according to your preference.</p>
<p>In addition, Prismane offers prebuilt Dark mode support, which adds an extra layer of accessibility and style to your projects. Many users prefer dark mode because it reduces eye strain and improves readability in low-light conditions.</p>
<p>It also has TypeScript support, which allows for type-safe and error-free development. TypeScript enforces strong typing, which means variables, parameters, and return values must adhere to specific data types. This helps catch type-related errors at compile-time rather than at runtime, which reduces the likelihood of unexpected issues in your code.</p>
<p>Prismane also offers a custom styling system that allows you to easily create and apply custom themes to your applications.</p>
<p>Lastly, it has a variety of custom hooks, such as a form builder hook and a toast notification hook, which allow you to encapsulate and reuse complex logic across different parts of your application.</p>
<h2 id="heading-benefits-of-using-prismane-ui">Benefits of Using Prismane UI</h2>
<p>Prismane UI components are all designed to follow a consistent style guide, which ensures that your application has a polished and professional look and feel.</p>
<p>The library also provides a variety of styling options, as well as the ability to create your own custom components. It is highly customizable, so you can easily create user interfaces that match your specific needs.</p>
<p>On top of that, it is free and open source, which gives you the freedom to run, study, modify, and distribute the software. This means you have control over how the software functions, which can be crucial for customization and security.</p>
<p>Lastly, the library is designed to be easy to use – even for developers who are new to React. It provides developers with a large collection of pre-built components and hooks, which can significantly speed up the development process.</p>
<h2 id="heading-disadvantages-of-using-prismane-ui">Disadvantages of Using Prismane UI</h2>
<p>Prismane is a relatively new library, so it may not have the same level of documentation, features, and community as older, more established libraries.</p>
<h2 id="heading-how-to-build-a-prismane-application">How to Build A Prismane Application</h2>
<p>We will be using Next.js and Prismane to develop our application.</p>
<p>Let's start by making sure our development environment is ready.</p>
<p>First, install Node.js (you can download it <a target="_blank" href="https://nodejs.org/en">here</a> if you don't already have it). Node.js version 18 or above is required.</p>
<p>In this tutorial, we will be using Visual Studio Code, but you can use any IDE of your choice.</p>
<p>Now, let's create a Next.js app by running the following command:</p>
<pre><code class="lang-plaintext">npx create-next-app@latest nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
</code></pre>
<p>Then, change the directory to our project's directory using the following command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> nextjs-blog
</code></pre>
<p>Let's run the development server using the following command to make sure our application is running well:</p>
<pre><code class="lang-plaintext">npm run dev
</code></pre>
<p>After making sure everything is fine, press <code>CTRL+C</code> and install Prismane:</p>
<pre><code class="lang-bash">npm install @prismane/core
</code></pre>
<p>In <code>pages/index.js</code>, add the following code:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Card, Image, Text, Button, Flex, fr, PrismaneProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">"@prismane/core"</span>;
<span class="hljs-keyword">import</span> { Star, ShoppingCart } <span class="hljs-keyword">from</span> <span class="hljs-string">"@phosphor-icons/react"</span>;


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">PrismaneProvider</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Card</span> <span class="hljs-attr">w</span>=<span class="hljs-string">{360}</span> <span class="hljs-attr">gap</span>=<span class="hljs-string">{fr(2)}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"card"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
        <span class="hljs-attr">src</span>=<span class="hljs-string">"https://img.freepik.com/free-photo/black-headphones-digital-device_53876-96805.jpg?size=626&amp;ext=jpg&amp;ga=GA1.1.460882575.1681882906&amp;semt=sph"</span>
        <span class="hljs-attr">br</span>=<span class="hljs-string">"md"</span>
        <span class="hljs-attr">fit</span>=<span class="hljs-string">"cover"</span>
        <span class="hljs-attr">mb</span>=<span class="hljs-string">{fr(2)}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">gap</span>=<span class="hljs-string">{fr(2)}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">fs</span>=<span class="hljs-string">"md"</span> <span class="hljs-attr">cl</span>=<span class="hljs-string">"green"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Star</span> /&gt;</span> 4.5 (120 reviews)
        <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">fs</span>=<span class="hljs-string">"md"</span> <span class="hljs-attr">cl</span>=<span class="hljs-string">"blue"</span>&gt;</span>
          In Stock
        <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">fs</span>=<span class="hljs-string">"lg"</span> <span class="hljs-attr">fw</span>=<span class="hljs-string">"bold"</span> <span class="hljs-attr">cl</span>=<span class="hljs-string">"black"</span>&gt;</span>
        Premium Headphones
      <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">cl</span>=<span class="hljs-string">"gray"</span>&gt;</span>
        Enjoy crystal-clear sound quality with our premium headphones, perfect
        for music lovers and audiophiles.
      <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">fw</span>=<span class="hljs-string">"bold"</span> <span class="hljs-attr">fs</span>=<span class="hljs-string">"2xl"</span> <span class="hljs-attr">cl</span>=<span class="hljs-string">"primary"</span>&gt;</span>
        $149.99
      <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">gap</span>=<span class="hljs-string">{fr(4)}</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">"auto"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">cl</span>=<span class="hljs-string">"primary"</span> <span class="hljs-attr">bg</span>=<span class="hljs-string">"yellow"</span>&gt;</span>
          Add to Wishlist
        <span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">cl</span>=<span class="hljs-string">"white"</span> <span class="hljs-attr">bg</span>=<span class="hljs-string">"blue"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">ShoppingCart</span> /&gt;</span> Add to Cart
        <span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Card</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PrismaneProvider</span>&gt;</span></span>
  );
}
</code></pre>
<p>The above code is a React component that renders a card with information about a product. The code imports the necessary components and icons from the Prismane and Phosphor Icons libraries, and then defines a component named <code>App()</code>.</p>
<p>The <code>App()</code> component renders a <code>Card</code> component with the following children:</p>
<ul>
<li><p>An <code>Image</code> component with the product image</p>
</li>
<li><p>A <code>Flex</code> container with two <code>Button</code> components, one for adding the product to the wishlist, and one for adding the product to the cart</p>
</li>
<li><p>A <code>Text</code> component displaying the product name</p>
</li>
<li><p>A <code>Text</code> component displaying the product description</p>
</li>
<li><p>A <code>Text</code> component displaying the product price</p>
</li>
<li><p>A <code>Flex</code> container with two <code>Button</code> components, one for adding the product to the wishlist and one for adding the product to the cart</p>
</li>
</ul>
<p>We are also using <a target="_blank" href="https://www.prismane.io/docs/styling/style-props">Prismane's style props</a> for styling our app in the code above.</p>
<p>Prismane has its own <code>reset.css</code>, so it is automatically injected when the app is wrapped with the <code>PrismaneProvider</code> component.</p>
<h2 id="heading-how-to-style-our-application">How to Style Our Application</h2>
<p>Next, let's create an <code>_app.js</code> file in <code>pages</code> folder and add the following code:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params">{ Component, pageProps }</span>) </span>{
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Component</span> {<span class="hljs-attr">...pageProps</span>} /&gt;</span></span>
    );
  }

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>In a Next.js application, the <code>_app.js</code> file is a special layout component that is used to wrap our entire application. It serves as the entry point for customizing the behavior and appearance of our app across all pages.</p>
<p>Now, let's style our app. Create a <code>global.css</code>file in our <code>pages</code>folder and add the following code:</p>
<pre><code class="lang-plaintext">@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&amp;display=swap');

  .card {
    font-family: Poppins, sans-serif;
  }
  body {
    width: 100vw;
    height: 100vh;
    display: flex;
    background-color: rgb(var(--prismane-colors-base-300));
  }
</code></pre>
<p>The code is importing the <code>Poppins</code> font from Google Fonts and applying it to the <code>.card</code> element. It also defines the width, height, display property, and background color for the <code>body</code> element.</p>
<p>Lastly, let's import our <code>global.css</code> file in our <code>app.js</code> file by adding the following line of code:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> <span class="hljs-string">'./global.css'</span>;
</code></pre>
<p>You can find the full code <a target="_blank" href="https://github.com/gatwirival/prismane-ui-demo">here</a>.</p>
<p>And here it the code's output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/Screenshot-from-2023-09-26-13-34-29.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Output</em></p>
<p>This is just a simple example of how to develop a web application using Prismane. There are many other features and options available in Prismane UI that you can use to create more complex and sophisticated applications.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Overall, Prismane UI is a great React UI library that offers a wide range of features and benefits. It is a good choice for developers of all experience levels, and it is well-suited for a variety of projects.</p>
<h2 id="heading-references">References</h2>
<p><a target="_blank" href="https://www.prismane.io/">Prismane website</a></p>
<p><a target="_blank" href="https://nextjs.org/learn/basics/create-nextjs-app">Next.js website</a></p>
<p><a target="_blank" href="https://github.com/phosphor-icons/react">Phosphor-icons repository</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the Rough Notation Library to Animate Your Website ]]>
                </title>
                <description>
                    <![CDATA[ I love animating websites. It's so fun when you just look at a site, and there are cool animations that make everything look pretty. Getting started with an animation library does not have to be hard. Anyone can add a bit of animation to their site r... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-animation-to-your-site-with-rough-notation/</link>
                <guid isPermaLink="false">66d4608ba326133d12440a4b</guid>
                
                    <category>
                        <![CDATA[ animation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Njong Emy ]]>
                </dc:creator>
                <pubDate>Tue, 02 Aug 2022 16:52:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/png_20220803_195955_0000.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I love animating websites. It's so fun when you just look at a site, and there are cool animations that make everything look pretty.</p>
<p>Getting started with an animation library does not have to be hard. Anyone can add a bit of animation to their site regardless of whether they are good working with the front end or not.</p>
<p>Let me show you how you can get started.</p>
<h1 id="heading-what-is-rough-notation">What is Rough Notation?</h1>
<p>Rough notation is lightweight yet amazing JavaScript animation library that you can use to get started with animations pretty quickly. And it is open source!</p>
<p>The docs are pretty straightforward, which is one reason it's a great animation library to start with.</p>
<p>In this article, I'll take you through the basic steps to get started with Rough Notation, and we'll build a pretty small site with some animations.</p>
<p>If you like using the library, check out their super repository. Give it a star, and if you love this article, shout them out! (This isn't sponsored. I just love the library :))</p>
<p>You can <a target="_blank" href="https://github.com/rough-stuff/rough-notation">check out the Rough Notation docs here</a>.</p>
<h2 id="heading-lets-get-animating">Let's Get Animating</h2>
<h3 id="heading-how-to-code-the-htmlcss">How to Code the HTML/CSS</h3>
<p>We can't animate something we don't see. So to start, we'll create a pretty simple static page with some minimal HTML and CSS.</p>
<p>For now, our HTML will just look bland. Nothing much going on. Just a nicely centered thing with a Poppins font going on.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"main"</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"header"</span>&gt;</span>Aloha. Hello. Salut.<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Today, we will animate this with <span class="hljs-tag">&lt;<span class="hljs-name">scan</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"rough-notation"</span>&gt;</span>Rough Notation<span class="hljs-tag">&lt;/<span class="hljs-name">scan</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a pretty simple site. If you love this, check Rough Notation out on <span class="hljs-tag">&lt;<span class="hljs-name">scan</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"link"</span>&gt;</span>Github<span class="hljs-tag">&lt;/<span class="hljs-name">scan</span>&gt;</span>. They are open source, and they are amazing!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maiores omnis molestias voluptas, odit laboriosam esse distinctio provident pariatur accusamus cum?<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>A bit about Rough Notation<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"list"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>It's open source.<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>It's easy to start with.<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>I love it!<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>In the above code, notice the classes I have added to some of the elements. This is how we select what elements to animate.</p>
<p>Our CSS itself is bare, but here is how it is and what our page looks like:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css2?family=Poppins:wght@300&amp;display=swap'</span>);
*{
    <span class="hljs-attribute">box-sizing</span>: border-box;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
}
<span class="hljs-selector-tag">body</span>{
    <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Poppins'</span>, sans-serif;
}
<span class="hljs-selector-class">.main</span>{
    <span class="hljs-attribute">display</span>: flex;
    <span class="hljs-attribute">justify-content</span>: center;
    <span class="hljs-attribute">align-items</span>: center;
    <span class="hljs-attribute">flex-direction</span>: column;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">40px</span>;
}
<span class="hljs-selector-tag">h1</span>{
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">10px</span>;
}
<span class="hljs-selector-tag">p</span>{
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">15px</span>;
}
<span class="hljs-selector-tag">ul</span>{
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">20px</span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Screenshot-from-2022-08-01-17-31-32.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Screenshot of how our bare static page looks. There is an h1 header that says 'Aloha. Hello. Salut.' A few other paragraphs make up the page and there is an unordered list that states three little facts about Rough Notation.</em></p>
<h3 id="heading-lets-add-some-javascript">Let's Add Some JavaScript</h3>
<p>Hold on, this is the juicy part! For our animations to take any kind of effect, we need a JavaScript file. Just create one, and link it to your HTML like you would normally do.</p>
<p>Now let's see how Rough Notation works.</p>
<p>The docs offer a few ways to add the library to our projects. For the sake of simplicity, we will load the ES module directly.</p>
<p><a target="_blank" href="https://github.com/rough-stuff/rough-notation">Check out the repo and the docs here</a>.</p>
<p>So essentially, we will add the an extra script tag to our HTML so that it looks like this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/rough-notation?module"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Now that Rough Notation is partially present in our project, we can dig into our JavaScript file, and import it. The first line of our JavaScript doc would look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { annotate } <span class="hljs-keyword">from</span> <span class="hljs-string">'rough-notation'</span>;
</code></pre>
<p>Now that Rough Notation is fully set up, let's grab what we want to animate from the page. Based on what elements we added classes to, we would have the following:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> header = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.header'</span>);
<span class="hljs-keyword">const</span> roughNotation = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.rough-notation'</span>);
<span class="hljs-keyword">const</span> link = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.link'</span>);
<span class="hljs-keyword">const</span> list = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.list'</span>);
</code></pre>
<p>The next step is what will bring our page to life. Say, I wanted to highlight the header a light pink color. I would write this code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> annotation = annotate(header, { <span class="hljs-attr">type</span>: <span class="hljs-string">'highlight'</span> , <span class="hljs-attr">color</span>:<span class="hljs-string">'pink'</span>});
annotation.show();
</code></pre>
<p>We assign the variable annotation to a function called <code>annotate</code>. The annotate function takes two parameters – the element we want to annotate, and an object.</p>
<p>The object can take in a few attributes. In this case we have two: the type of annotation we want on the header, and the color.</p>
<p>And just to mention a few other types of annotations that we can do:</p>
<ul>
<li><p>Highlight</p>
</li>
<li><p>Circle</p>
</li>
<li><p>Underline</p>
</li>
<li><p>Brackets</p>
</li>
<li><p>Box</p>
</li>
<li><p>Strike-through</p>
</li>
<li><p>Crossed-off</p>
</li>
</ul>
<p>Back to our header animation. The last line is <code>annotation.show()</code> which just basically displays our animation.</p>
<p>If we save our page, and check our browser, nothing happens. It was supposed to work (according to the docs), but we get nothing.</p>
<p>I found a solution to the problem on a YouTube video, and in order for us to make the animation come to life, we have to adjust the import line in our JavaScript file.</p>
<p>So you can update it like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { annotate } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://unpkg.com/rough-notation?module"</span>;
</code></pre>
<p>If you are like me, and love opening issues to complain (just kidding) about open source projects, feel free to raise an issue on the Rough Notation repository if the animation doesn't work for you either. But only open an issue if no one has beat you to it yet. So do check recent open and closed issues first. May the best issue opener win :)</p>
<p>If you refresh after fixing the problem we had, our header gets a nice pink highlight. You see it nicely swooshing across the page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Screenshot-from-2022-08-01-18-24-31.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Screenshot of our site now, with the header highlighted in pink.</em></p>
<p>Nice and pretty, right?</p>
<p>Let's go ahead and add a few more animations:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> annotation = annotate(header, { <span class="hljs-attr">type</span>: <span class="hljs-string">'highlight'</span> , <span class="hljs-attr">color</span>:<span class="hljs-string">'pink'</span>});
<span class="hljs-keyword">const</span> annotation2 = annotate(roughNotation, {<span class="hljs-attr">type</span>:<span class="hljs-string">'circle'</span>, <span class="hljs-attr">color</span>:<span class="hljs-string">'yellow'</span>, <span class="hljs-attr">padding</span>:<span class="hljs-number">7</span>});
<span class="hljs-keyword">const</span> annotation3 = annotate(link, { <span class="hljs-attr">type</span>: <span class="hljs-string">'box'</span> , <span class="hljs-attr">color</span>:<span class="hljs-string">'blue'</span>, <span class="hljs-attr">padding</span>:<span class="hljs-number">7</span>});
<span class="hljs-keyword">const</span> annotation4 = annotate(list, { <span class="hljs-attr">type</span>: <span class="hljs-string">'bracket'</span> , <span class="hljs-attr">color</span>:<span class="hljs-string">'red'</span>, <span class="hljs-attr">brackets</span>:[<span class="hljs-string">'left'</span>, <span class="hljs-string">'right'</span>], <span class="hljs-attr">strokeWidth</span>:<span class="hljs-number">5</span>});

<span class="hljs-keyword">const</span> array = annotationGroup([annotation, annotation2, annotation3, annotation4]);
array.show();
</code></pre>
<p>This time, we have added quite a bit. But don't let it get overwhelming. We'll walk through it step by step.</p>
<p>First, we have added <code>padding</code> to our <code>annotation2</code> animation. Just like we saw with the header, the <code>roughNotation</code> (which is the <code>rough-notation</code> class in our HTML) gets a yellow circle with a padding of 7.</p>
<p>But padding isn't the only new attribute we introduced. <code>annotation4</code> has a few new things we need to learn about. The object parameter has an attribute, <code>brackets</code>, with an array as value. <code>left</code> and <code>right</code> indicate that we want opening and closing brackets on both sides of the element. It also has <code>strokeWidth</code>, which determines the thickness of the brackets.</p>
<p>Since we have to "show" the animation of each element, which kind of gets boring if we have to animate a lot, I created an array, stored each animation in it, and then "showed" the array all at once. It's neat, and saves a lot of time.</p>
<p>So we've introduced <code>annotationGroup</code>. For this to take effect, we are going to add it to our import line like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { annotate, annotationGroup } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://unpkg.com/rough-notation?module"</span>;
</code></pre>
<p>So... our final site looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Screenshot-from-2022-08-01-19-46-08.png" alt="Final screenshot with all animations put in place." width="600" height="400" loading="lazy"></p>
<p>The animations will work better on your browser, because you get to refresh and see them take effect one after the other.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Writing this was fun! And I hope that you not only learned something new, but that you tried it out too.</p>
<p>Make sure to check out the Rough Notation repository and docs, because they cover a whole lot more than what we discussed in this article.</p>
<p>Happy animating!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is a Software Framework? ]]>
                </title>
                <description>
                    <![CDATA[ These days, companies both big and small use some kind of software framework to build their websites. And if you want to get into coding, it's important to learn and understand some of the popular frameworks – regardless of the field you choose in th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-a-software-framework/</link>
                <guid isPermaLink="false">66ba535a8e44e0cdf1281272</guid>
                
                    <category>
                        <![CDATA[ framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tiago Capelo Monteiro ]]>
                </dc:creator>
                <pubDate>Wed, 13 Jul 2022 19:28:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/logo-freecodecamp.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>These days, companies both big and small use some kind of software framework to build their websites.</p>
<p>And if you want to get into coding, it's important to learn and understand some of the popular frameworks – regardless of the field you choose in the industry. ‌‌‌‌But why? ‌‌‌‌</p>
<p>Frameworks help you easily create new apps and ideas without having to write as much code yourself.</p>
<p>They also help eliminate a lot of headaches, so you can spend your time on what really counts.</p>
<p>Basically, they can be a real time saver.</p>
<p>In this article, we will explore:</p>
<ul>
<li>What is a framework?</li>
<li>What is a software framework?</li>
<li>Examples of software frameworks</li>
<li>The difference between a library and a framework</li>
</ul>
<p>So let's get started!</p>
<h2 id="heading-what-is-a-framework">What is a Framework?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/pexels-ludvig-hedenborg-axe.jpg" alt="Image" width="600" height="400" loading="lazy">
_Photo by [<strong>Pexels</strong>](https://www.pexels.com/@photolisious?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" rel="noopener"&gt;<strong>Ludvig Hedenborg</strong> from &lt;a href="https://www.pexels.com/photo/brown-and-black-axe-3433348/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm<em>source=pexels" rel="noopener)</em></p>
<p>Imagine, if you will, a guy called John.</p>
<p>John needs to cut down a tree to light his fireplace up to make his family warm.</p>
<p>He goes into the woods, some time passes, and he finally chops down a tree.</p>
<p>Then, he needs to cut the tree into small pieces that can fit in his fireplace.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/pexels-ron-lach-anotheraxe.jpg" alt="Image" width="600" height="400" loading="lazy">
_Photo by [<strong>Pexels</strong>](https://www.pexels.com/@ron-lach?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" rel="noopener"&gt;<strong>Ron Lach</strong> from &lt;a href="https://www.pexels.com/photo/axe-stuck-in-trunk-10397927/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm<em>source=pexels" rel="noopener)</em></p>
<p>Finally, John has successfully cut all the wood needed in the right size to warm his family.</p>
<h3 id="heading-but-what-if-john-had-a-chainsaw-instead">But, what if John had a chainsaw instead?</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/pexels-karolina-grabowska-chainsaw.jpg" alt="Image" width="600" height="400" loading="lazy">
_Photo by [<strong>Pexels</strong>](https://www.pexels.com/@karolina-grabowska?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" rel="noopener"&gt;<strong>Karolina Grabowska</strong> from &lt;a href="https://www.pexels.com/photo/crop-lumberman-sawing-log-with-electric-power-saw-4205983/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm<em>source=pexels" rel="noopener)</em></p>
<p>‌If he had a chainsaw, the work would be done much more quickly and he would lose less time and energy cutting the wood for the fireplace.</p>
<p>Especially if he needed to chop down many trees.</p>
<p>But John likes to use his axe because he says it allows him more control over every <strong>bit</strong> of wood he chops off.</p>
<p>And with an axe he is able to cut small tree branches and it is better to chop up the wood.</p>
<p>So, with an axe, he can take care of minor things more easily. We don't need a tool like a chainsaw to do it. But when we're cutting down many big trees, it is a good idea to use a chainsaw, because it saves time and effort.</p>
<p>The same applies to coding. When we're programming and we just need to do simple stuff, it is better to just write our own code from scratch and/or get some libraries to help us with that.</p>
<p>But when we need to tackle many big projects, it is better to use a framework, because the project is big and frameworks can save us time.</p>
<p>According to the analogy:</p>
<ul>
<li>Cutting the tree with an axe = programming from scratch</li>
<li>Cutting trees with a chainsaw = Programming with a framework</li>
</ul>
<p>A chainsaw allows people to more <strong>easily cut trees.</strong></p>
<p>A framework allows people to more <strong>easily develop programs.</strong></p>
<h2 id="heading-what-is-a-software-framework">What is a Software Framework?</h2>
<p>Just as the chainsaw is a tool to work faster and more efficiently, a software framework is also a “tool” that helps a programmer work faster and achieve more in less time.</p>
<p>Just as there are many types of chainsaws, there are also many types of software frameworks.</p>
<h3 id="heading-examples-of-software-frameworks">Examples of software frameworks</h3>
<p>Now I'll share how and where you can use different frameworks in different areas of programming.</p>
<h4 id="heading-web-development-frameworks">Web development frameworks</h4>
<p>Web development frameworks make it easier to interact with the website database.</p>
<p>Frameworks automate functions and boring processes used to record and retrieve user-input data.</p>
<p>These frameworks can also make it easier to arrange and organize elements when you're designing the front-end of the site.</p>
<p>Vue is an example of a front-end web development framework.</p>
<p>Front-end means it is only the part the user sees – in other words, the <a target="_blank" href="https://www.freecodecamp.org/news/osi-model-networking-layers-explained-in-plain-english/">presentation layer</a> or OSI layer 6.</p>
<p>As a web development framework, Vue:</p>
<ul>
<li>Can <a target="_blank" href="https://vuejs.org/about/faq.html#does-vue-scale">Scale large applications</a></li>
<li><a target="_blank" href="https://vuejs.org/about/faq.html#should-i-use-javascript-or-typescript-with-vue=">Supports typescript</a></li>
<li><a target="_blank" href="https://router.vuejs.org/">Has its own router</a></li>
<li><a target="_blank" href="https://vuex.vuejs.org/">Has a state management library</a></li>
</ul>
<p>This is <a target="_blank" href="https://www.statista.com/statistics/1124699/worldwide-developer-survey-most-used-frameworks-web/">one of the most used frameworks</a> in the web development industry, along side with <a target="_blank" href="https://reactjs.org/">React</a> and <a target="_blank" href="https://angular.io/">Angular</a>.</p>
<p>The following organizations use Vue:</p>
<ul>
<li><a target="_blank" href="https://madewithvuejs.com/upwork">Upwork</a></li>
<li><a target="_blank" href="https://madewithvuejs.com/alibaba">Alibaba</a></li>
<li><a target="_blank" href="null">E</a><a target="_blank" href="https://madewithvuejs.com/euronews">uronews</a></li>
<li><a target="_blank" href="null">G</a><a target="_blank" href="https://madewithvuejs.com/google-careers">oogle careers</a> Platform</li>
</ul>
<p>I recommend Vue because I think it's easier to learn compared to other web development frameworks like <a target="_blank" href="https://reactjs.org/">React</a> and <a target="_blank" href="https://angularjs.org/">Angular</a>. Vue is also growing in popularity.</p>
<p>Normally, developers choose which framework they are going to use based on their team experience, the type of project their working on, or the complexity of their projects.</p>
<p>It really depends on your circumstances.</p>
<p>You can check out <a target="_blank" href="https://vuejs.org/">Vue's official site</a> for more information.</p>
<h4 id="heading-machine-learning-frameworks">Machine learning frameworks</h4>
<p>Machine learning frameworks help programmers by making it easy to implement complex ML algorithms in their programs.</p>
<p>You don't have to create these complex algorithms by yourself. Someone has already done it for you.</p>
<p>This makes your life easier as you just have to get your dataset, optimize the data to be used in the machine learning model, save the model, and run your analysis.</p>
<p>One of the most popular machine learning frameworks <a target="_blank" href="https://www.statista.com/statistics/793840/worldwide-developer-survey-most-used-frameworks/">worldwide</a> is <a target="_blank" href="https://pytorch.org/">PyTorch</a>.</p>
<p>PyTorch is a machine learning based on the <a target="_blank" href="http://torch.ch/">torch</a> library, developed by <a target="_blank" href="https://ai.facebook.com/research/">Facebook AI research lab</a>.</p>
<p>PyTorch has:</p>
<ul>
<li>Open Neural Network Exchange support</li>
<li>Hybrid Front-End</li>
<li>Dynamic Computational Graph Support</li>
<li>Data Parallelism</li>
</ul>
<p>PyTorch has been used in some cool projects, like:</p>
<ul>
<li>A<a target="_blank" href="https://pytorch.org/blog/amazon-ads-case-study/">mazon has reduce inference costs by 71% and drive scale out using PyTorch, TorchServe, and AWS Inferentia</a>.</li>
<li><a target="_blank" href="https://pytorch.org/">Stanford PyTorch’s flexibility to efficiently research new algorithmic approaches.</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=oBklltKXtDE">U</a>sed in tesla cars to detect traffic lights, crosswalks, roadsigns...</li>
</ul>
<p><a target="_blank" href="https://pytorch.org/ecosystem/">Many GitHub projects</a> use this framework, from computer vision to natural language processing applications.</p>
<p>I recommending PyTorch because it is easy to learn compared to other machine learning frameworks, it's written in Python, it has a big community around it, and so much more!</p>
<p>You can also check out <a target="_blank" href="https://www.tensorflow.org/">TensorFlow</a> and <a target="_blank" href="https://scikit-learn.org/stable/index.html">sci-kit-learn</a>, as they are also very popular.</p>
<p>Just keep in mind that TensorFlow and sci-kit-learn are both libraries, not frameworks. We'll discuss the difference more below.</p>
<p>In general, companies use TensorFlow, while machine learning researchers use PyTorch.</p>
<p>This is mainly for three reasons:</p>
<ul>
<li>Python's API hasn't changed much over the years compared to TensorFlow, so the code from some months back is almost the same in PyTorch. In Tensofrlow, it may be different or even not run at all.</li>
<li>The Tensorflow API has changed, but the documentation has not changed much, making it difficult for researchers to find online help.</li>
<li>Most research done by big companies is in PyTorch.</li>
</ul>
<p>So, if you are reading research in advanced stages, most of the code you see will be in PyTorch.</p>
<p>There are <a target="_blank" href="https://www.researchgate.net/post/Why_most_researchers_are_shifting_from_tensorFlow_to_Pytorch">many</a> more reasons for this, but these are just some examples.</p>
<p>Here is the website for PyTorch:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://pytorch.org/">https://pytorch.org/</a></div>
<h4 id="heading-mobile-development-frameworks">Mobile development frameworks</h4>
<p>Mobile development frameworks help programmers a lot by automating many tasks that would otherwise make maintaining projects a hassle.</p>
<p>For example, instead of using 50 lines of code to create a button or to better navigate the space in a screen, frameworks let you drop some button code in, ready to apply to your app.</p>
<p>With a framework a lot of that work is already done for you.</p>
<p><a target="_blank" href="https://reactnative.dev/">React native</a> is a mobile development framework based on the <a target="_blank" href="https://reactjs.org/">React</a> library.</p>
<p>This framework comes from the web version of React.</p>
<p>This mobile framework was one of the <a target="_blank" href="https://www.statista.com/statistics/869224/worldwide-software-developer-working-hours/">most popular</a> in the world from 2019 to 2021.</p>
<p>Its main features are:</p>
<ul>
<li>Seamless Cross-Platform Development</li>
<li>Fast Refresh</li>
<li>Code Reusability</li>
<li>Improved UI/UX</li>
<li>Hot Reload</li>
</ul>
<p>Just as with PyTorch, React Native has also been used to develop many projects:</p>
<ul>
<li><a target="_blank" href="https://instagram-engineering.com/react-native-at-instagram-dd828a9a90c7">Instagram</a></li>
<li><a target="_blank" href="https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab">Airbnb</a></li>
<li><a target="_blank" href="https://eng.uber.com/ubereats-react-native/">Uber eats</a></li>
<li><a target="_blank" href="https://medium.com/pinterest-engineering/supporting-react-native-at-pinterest-f8c2233f90e6">Pinterest</a></li>
</ul>
<p>I recommending React Native because it's based on React.</p>
<p>And if you know JavaScript and React well, you can easily develop cross platform apps.</p>
<p>There are also <a target="_blank" href="https://flutter.dev/">Flutter</a>, <a target="_blank" href="https://kivy.org/#home">kivy</a>, <a target="_blank" href="https://cordova.apache.org/">cordova</a>, and many more mobile development frameworks.</p>
<p>Compared to React native, flutter uses the <a target="_blank" href="https://dart.dev/">Dart programming language</a>, Kivy uses Python, and Cordova uses HTML, CSS, and JavaScript</p>
<p>With all of these frameworks, the best choice comes down to what knowledge you already have and the constraints placed on you by your company or team.</p>
<p>For example, if you already know how to use Python and want to develop a small personal project, maybe the best choice is Kivy.</p>
<p>If you join a company and work on the front end with React, is best choice is probably React Native.</p>
<p>Since there are many choices, it really come down to your requirements and projects.</p>
<p>Here is the website for React Native:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://reactnative.dev/">https://reactnative.dev/</a></div>
<p>These are just three types of frameworks you can look into. Also, keep in mind that there are many frameworks. I just showed you some of them here.</p>
<h2 id="heading-whats-the-difference-between-a-library-and-a-framework">What's the Difference Between a Library and a Framework?</h2>
<p>If you're new to coding, you might not know the differences between a library and a framework. But they're not the same thing.</p>
<p>A library is code from a collection of files that someone wrote pre-made for your project.</p>
<p>Like using a shovel. You can use it to dig whatever you want.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/pexels-anna-tarazevich-7299923.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Photo by Anna Tarazevich: https://www.pexels.com/photo/a-shovel-on-brown-dirt-ground-7299923/</em></p>
<p>A framework is like using an excavator. While you can dig more dirt with an excavator, you only use it for specific (big) construction projects.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/pexels-ilya-5328418.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Photo by Ilya: https://www.pexels.com/photo/construction-vehicles-at-work-5328418/</em></p>
<p>With a library, you are in control of the code. You use the library to add new features to help your project</p>
<p>With a framework, you are limited by it. You can only work with the "space" the framework gives you. There are also technical reasons for this, which you can <a target="_blank" href="https://www.freecodecamp.org/news/the-difference-between-a-framework-and-a-library-bd133054023f/">read more about in this article</a>.</p>
<h3 id="heading-should-i-use-a-framework-or-library-for-my-project">Should I use a framework or library for my project?</h3>
<p>It depends on the complexity of your project, who or what teams will maintain it, and so on.</p>
<p>By analogy, imagine that one of John's hobbies is wood carving.</p>
<p>To do that, he needs to use a simple set of tools to cut wood. He cannot use his axe.</p>
<p>While it can help in some phase of his project, it can also, by accident, destroy the project. It can't work in fine enough detail.</p>
<p>So in this case, the best thing to do is to do everything from scratch. The same applies to programming.</p>
<p>If you want to do a simple project, but need to use function you don't know how to create, you should use libraries.</p>
<p>If you want to work on a complex project where there are a lot of things you don't currently understand, a framework might help you get going.</p>
<p>Also keep in mind that if you work at a big company you might write the code without using any frameworks at all. This way, there is more space for programmers and engineers to develop projects without any limitations.</p>
<p>In many cases, simple programming projects are better the fewer library dependencies they have.</p>
<p>And in general, I believe that the more you code your projects yourself, the better the project is. At least in most cases. :)</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>Great! In this article you have learned:</p>
<ul>
<li>What a software framework is</li>
<li>3 different software frameworks and how to learn more about them</li>
<li>The differences between a software framework and software library</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a CSS Library with Vite.js ]]>
                </title>
                <description>
                    <![CDATA[ By Ali Haydar Building a CSS library might seem like something you'd do out of pure curiosity, just to learn and explore. But it can be so much more than that.  I've seen custom-built CSS libraries used everywhere from big organisations to scrappy yo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-css-library-with-vitejs/</link>
                <guid isPermaLink="false">66d45d97d62e921b49e02cb4</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 15 Sep 2021 16:47:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/09/pexels-markus-spiske-3872166.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ali Haydar</p>
<p>Building a CSS library might seem like something you'd do out of pure curiosity, just to learn and explore. But it can be so much more than that. </p>
<p>I've seen custom-built CSS libraries used everywhere from big organisations to scrappy young startups.</p>
<h2 id="heading-what-is-a-css-library">What is a CSS Library?</h2>
<p>You can think of a CSS library like a theme that you can use across multiple projects. It's helpful if you don't want to repeat the styling every time or copy-paste your code. It's also useful if you want to be consistent across your web apps (which is good for your brand).</p>
<p>So, a shared CSS library/theme will increase your efficiency and development speed and it can help you scale your product while maintaining consistency. This can also be a part of a more extensive <a target="_blank" href="https://www.robertcreative.com/blog/what-is-a-design-system">design system</a>.</p>
<p>The focus of this post will be more on building the CSS library rather than styling it. The output will be a library with a concept similar to <a target="_blank" href="https://getbootstrap.com/">bootstrap</a>, where you can use CSS classes and style the associated HTML element.</p>
<p>So how can we build this kind of library, and what tools do we need to use?</p>
<p>Below is a summary of what we'll build:</p>
<ul>
<li>Create a library build with Vite, not a web app build</li>
<li>Handle static assets used in your CSS file</li>
<li>Use SASS instead of CSS when building the library</li>
<li>Package the library with npm</li>
</ul>
<h2 id="heading-how-to-set-up-the-project">How to Set Up the Project</h2>
<p>We will use <a target="_blank" href="https://vitejs.dev/">Vite</a> to build our CSS library. Then we'll package it with npm, and finally use it in a new front-end project.</p>
<p>Vite is a dev server and a build tool that makes implementing web projects a fast and smooth experience.</p>
<p>Follow these steps to get started:</p>
<ul>
<li>Run <code>npm init @vitejs/app</code></li>
<li>Enter a project name</li>
<li>Select a framework (Vanilla, Vue, React, etc.) – here we will choose "vanilla" as we're focused on CSS</li>
</ul>
<p>The entry to the project is index.html. We can use this file to test what we're building. But it will not be packaged as part of the library we're creating.</p>
<h3 id="heading-how-to-update-the-boilerplate-code">How to Update the Boilerplate Code</h3>
<p>First, let us tidy up the existing boilerplate code.</p>
<p>We'll update the HTML file to include a button and a div file with a logo in the background like this:</p>
<pre><code>  &lt;!DOCTYPE html&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"icon"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"image/svg+xml"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"favicon.svg"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Vite App<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"logo"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"tomato"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/src/main.ts"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre><p>Then, under the "src" directory, delete the contents of the main.ts file, keeping the first line that imports <code>style.css</code></p>
<p>Next, in the <code>style.css</code> file, add the following code:</p>
<pre><code>  .tomato {
  background-color: tomato;
  }
  .logo {
  <span class="hljs-attr">background</span>: url(/logo.png) no-repeat;
  height: <span class="hljs-number">300</span>px;
  }
</code></pre><p>We need to copy the logo.png file under the root folder of the project (feel free to use any other image instead of logo.png and change the height accordingly).</p>
<h2 id="heading-how-to-build-our-css-library">How to Build Our CSS Library</h2>
<p>Before creating a build, let's run the app locally. In your terminal:</p>
<ul>
<li>Navigate to the root folder of your project</li>
<li>Run <code>npm install</code> to install the project dependencies</li>
<li>Run <code>npm run dev</code> to start the local server</li>
</ul>
<p>Open the app in your browser: http://localhost:3000 (usually, it's on port 3000 unless that port's already being used by another app).</p>
<p>Now it's time to build the project, so just type <code>npm run build</code>. This will create a <code>dist</code> folder with the following files:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/dist-folder-1.png" alt="dist-folder-1" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-configure-the-build">How to Configure the Build</h3>
<p>The generated folder looks like a build for a web app that needs to be hosted and served. But we're looking to build a library instead. So we need to add some configurations to achieve that:</p>
<p>At the root level of your project, create a new file <code>config.vite.js</code>:</p>
<pre><code>  <span class="hljs-keyword">import</span> { defineConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">"vite"</span>;
  <span class="hljs-keyword">import</span> path <span class="hljs-keyword">from</span> <span class="hljs-string">"path"</span>;

  <span class="hljs-built_in">module</span>.exports = defineConfig({
  <span class="hljs-attr">build</span>: {
      <span class="hljs-attr">lib</span>: {
      <span class="hljs-attr">entry</span>: path.resolve(__dirname, <span class="hljs-string">"src/main.ts"</span>),
      <span class="hljs-attr">name</span>: <span class="hljs-string">"MyCssLib"</span>,
      },
  },
  });
</code></pre><p>Run <code>npm run build</code> again. Notice the new structure of the dist folder:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/dist-folder-2.png" alt="dist-folder-2" width="600" height="400" loading="lazy"></p>
<p>In this case, we no longer have an HTML file in the bundle, and our styles are still within a styles.css file. But you'll see here that the logo file we are referencing in our CSS file is no longer there.</p>
<p>What happened here is that Vite inlined the assets as a base64 data URL. So using this new CSS file will still work properly – similar to when referencing the asset file:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/inline-css-url.png" alt="inline-css-url" width="600" height="400" loading="lazy"></p>
<p>This is cool, but it might cause a problem in larger projects where the CSS file might become very big if it had multiple referenced assets.</p>
<h3 id="heading-how-to-handle-the-assets">How to Handle the Assets</h3>
<p>Vite offers a simple way to handle assets, where you keep the same file and the path referenced in CSS still works.</p>
<p>On the root of your project, create a <code>public</code> folder and move the <code>logo.png</code> file into it. The local web app will still recognise the logo (check that this is still working on http://localhost:3000).</p>
<p>Run <code>npm run build</code> again. The new dist folder will look as follows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/dist-folder-3.png" alt="dist-folder-3" width="600" height="400" loading="lazy"></p>
<p>Notice that the logo file is still there at the root level. If you open the CSS file, it will be referencing that same logo file. </p>
<p>It's convenient here to have an assets folder to contain all of your assets. You can create this folder under the <code>public</code> directory. Remember to update the path to the assets in your CSS file (from <code>/logo.png</code> to <code>/assets/logo.png</code> in this case).</p>
<h3 id="heading-how-to-use-sass-for-styling">How to Use SASS for Styling</h3>
<p>Devs often use <a target="_blank" href="https://sass-lang.com/">SASS</a> for styling because it provides a lot of flexibility and organisation. Vite handles SASS out of the box. Let's check it out:</p>
<p>Install SASS by running <code>npm install sass</code>. Under the "src" folder, change the name of the <code>style.css</code> file to <code>style.scss</code></p>
<p>Next, add some SASS changes to the <code>style.scss</code> file. For example, use a color variable:</p>
<pre><code>  $color: tomato;

  .tomato {
  background-color: $color;
  }
</code></pre><p>Then you'll update the "main.ts" file to point to <code>style.scss</code> instead of <code>style.css</code>.</p>
<p>Run <code>npm run build</code> to create a new build, and check the "style.css" file that got generated in the "dist" folder – it has the correct CSS:</p>
<pre><code>  .tomato{background-color:tomato}
</code></pre><h2 id="heading-how-to-package-the-library">How to Package the Library</h2>
<p>Now it is time to package the library (whatever got generated in the dist folder). We will use npm to do this.</p>
<p>First, you need to update the "package.json" file to include a new property called <code>files</code>. According to the <a target="_blank" href="https://docs.npmjs.com/cli/v7/configuring-npm/package-json#files">npm documentation</a>, the <code>files</code> field is an array of file patterns that describes the entries to be included when your package is installed as a dependency. </p>
<p>We need only to package the generated CSS file, so the additional entry in the "package.json" file will be <code>files: [dist/style.css]</code>.</p>
<p>Next, you'll run <code>npm pack</code>. This will create a new file. In this case, "vite-CSS-lib-0.0.0.tgz".</p>
<h3 id="heading-how-to-use-the-package">How to Use the Package</h3>
<p>Start by creating a new project (which you can do in the same way we started with Vite). Once it's done, follow these steps:</p>
<ul>
<li>Install the newly created package: <code>npm install &lt;path-to-lib&gt;/vite-css-lib-0.0.0.tgz</code></li>
<li>In your "main.js" file, import the CSS file: <code>import 'node_modules/vite-css-lib/dist/style.css</code></li>
<li>In your "index.html" file, add a button with a "tomato" class: <code>&lt;button class="tomato"&gt;Submit&lt;/button&gt;</code></li>
</ul>
<p>Run your app. It should have a button with a tomato background colour.</p>
<h2 id="heading-things-to-improve-in-the-library">Things to Improve in the Library</h2>
<p>Of course, this isn't a finished product – it can always be improved.</p>
<p>You can start by exporting the SASS files rather than a compiled CSS file so that apps depending on your library can use SASS directly. You can do this through a Vite/Rollup plugin: <code>https://vitejs.dev/guide/api-plugin.html</code></p>
<p>Also, when you're packaging the library with npm, everything within package.json will be included in the package. You can tidy up the package.json file to stop including any unnecessary scripts/dependencies. You can read more about <a target="_blank" href="https://stackoverflow.com/questions/48802204/npm-publish-removing-scripts-from-package-json">how to do this here</a>.</p>
<p>Finally, set up a bundle with a JS file that exports the created CSS file to enable importing the library without having to reference node_modules/lib/style.css.</p>
<p>I hope this article was helpful. How would you enhance this process? How would you build a CSS library?</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 5 React Libraries Every Project Should Use in 2021 ]]>
                </title>
                <description>
                    <![CDATA[ There are literally 100s of great React libraries to choose from, but which libraries do you need most for your React projects?  In this article, we're going to break down five libraries you need for your React projects. Each of them will cover virtu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/5-react-libraries-every-project-needs/</link>
                <guid isPermaLink="false">66d03743c1024fe75b758f33</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Fri, 09 Jul 2021 20:06:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/07/5-libraries-every-react-project-needs.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>There are literally 100s of great React libraries to choose from, but which libraries do you need most for your React projects? </p>
<p>In this article, we're going to break down five libraries you need for your React projects.</p>
<p>Each of them will cover virtually every major tool you need, plus we'll cover what are the best ones to choose in 2021 and beyond. </p>
<p>Let's dive right in!</p>
<h2 id="heading-1-a-quicker-create-react-app">1.  A Quicker Create-React-App</h2>
<p>If you want to create a React project, you probably reach for a tool like Create-React-App. </p>
<p>While Create-React-App remains an amazing tool and allows you to create a React project by running a single command, there is a new competitor to it that you should know about called <strong>Vite</strong>. </p>
<p>Create-React-App uses Webpack under the hood to build our React code for development. But build tools have emerged that compete with Webpack in speed. </p>
<p>Vite is one such build tool that uses a faster bundler called esbuild. In short, it makes use of the browser's native ES modules to make for a quicker development experience. </p>
<p><em>How much faster is Vite?</em> See for yourself! </p>
<p>Here's a quick comparison of starting up a Vite project (right) versus a Create-React-App project (left). </p>

    
    Sorry, your browser doesn't support embedded videos.


<p>Vite is many times faster than Create-React-App when running React in development. </p>
<p>If you're annoyed at times with how long Create-React-App can take to start up, definitely check out Vite. </p>
<p>On top of that, I'd highly recommend the tool <strong>Create-Next-App</strong>. </p>
<p>This allows us to create a next JS project very rapidly. And yes, Next.js is a framework, but it is a React framework that needs drastically fewer dependencies. In fact, it just needs the dependencies React, React DOM, and Next.</p>
<p><em>Be sure to check out <strong>Vite</strong> and <strong>Create Next App</strong> when creating your next React project.</em></p>
<h2 id="heading-2-a-better-data-fetching-library">2. A (Better) Data Fetching Library</h2>
<p>When it comes to basically any React application, we have to manage some server state. </p>
<p>This means we're fetching data from an external server (like an API) and we're bringing that data into our app, which is then combined it with the local state that we have across our app's components. </p>
<p>Many React developers, no matter their skill level, can have a hard time figuring out how to manage server state with their local state. Most developers resort to a library like Redux as a solution.</p>
<p>In the past year, a couple of libraries have emerged that make it very easy to manage server state within our React components. These are <strong>React Query</strong> and <strong>SWR</strong>. </p>
<p>They help us with fetching data by giving us some very helpful custom hooks. But what is most important about them is that they have their own internal cache. </p>
<p>This built-in cache allows us to very easily integrate external data with our app. We assign each query to a custom key. To read or update any data we have fetched, we just need to reference that key!</p>
<p>Here is a simple example of how you can use React Query. We are fetching post data from an API, whose value we assign to the custom key "posts".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/react-query.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In addition to improve our state management, fetching data is so much easier. They include a lot of great tools that allow us to do things like refetch queries, create paginated queries, infinite queries, and much more.</p>
<p>In short, if you're fetching data in your React application across multiple components, definitely use one of these newer data fetching libraries.</p>
<p><em>If you're looking for the most in-depth and sophisticated data fetching library, use <strong>React Query</strong>. <strong>SWR</strong> is a great choice as well, albeit with a slightly smaller list of tools.</em> </p>
<h2 id="heading-3-a-dead-simple-state-management-library">3. A Dead-Simple State Management Library</h2>
<p>When it comes to managing global app state, Redux has always been the go-to choice. </p>
<p>It has helped React developers separate state values into one shared object value, which can be read and updated in any component in our application.</p>
<p>Redux, however, comes with some conceptual baggage. To properly setup Redux and manage our state, we must understand and write separate actions, reducers and selectors. </p>
<p>There are some new competitors to Redux that seek to give us virtually all of the benefits of the library with none of the difficulty. These are the libraries <strong>Zustand</strong> and <strong>Jotai</strong>. </p>
<p>They're both very similar, and what's powerful about them is that they were created with a hooks-first approach to working with state. This means that once you create your store, you can read any of its value by calling it as a hook.</p>
<p>Here's a quick example of how to create and use a Zustand store as a hook to create a simple counter application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/zustand.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Zustand and Jotai make state management simpler due to the fact that you do not need to separate your store into actions, reducers, and selectors. </p>
<p>If you want to update state, write a function in your store to do so and use it in your component. If you want to select a slice of your state, use your store as hook and grab the property of the state object you want. It's that simple!</p>
<p>Plus, you do not need any additional libraries to perform async operations (unlike Redux, which require Redux Thunk or Redux Saga). </p>
<p>Finally, you do not need to wrap your entire component tree with a context provider, so there is basically no setup required, other than creating your store and using it in your components. </p>
<p><em>In short, if you're having trouble with understanding Redux or want more freedom in your state management, check out <strong>Zustand</strong> or <strong>Jotai</strong>.</em> </p>
<h2 id="heading-4-a-powerful-component-library">4. A Powerful Component Library</h2>
<p>React was made to create impressive user interfaces. As a result, we need libraries that help us achieve that end. </p>
<p>There are tons of component libraries that give us customized well designed, components right out of the box. However, with all of this diversity which ones do you pick?</p>
<p>If you want to be able to build apps that look great and are equally functional, you can check out extensive, well-maintained libraries like <strong>Ant Design</strong>, <strong>Material UI</strong>, and <strong>Chakra UI</strong>. </p>
<p>All of these libraries have a ton of components and even dedicated icon libraries. But arguably what is most important about them is that they have an intuitive syntax that allows us to build attractive components more easily. </p>
<p>Here is a quick example of building a simple UI with Ant Design.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/antd.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Most developers pick component libraries for their appearance and what components they feature, but the best libraries also include additional tools that make our apps for functional.</p>
<p>Here is one such custom hook (<code>useClipboard</code>) from Chakra UI that allows us to copy text to our users' clipboard.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screen-Shot-2021-07-09-at-2.27.58-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>I've selected these because not only do I find them to be visually appealing but they also have a great deal of components that will suit virtually every use case you have. </p>
<p>The worst thing to happen is when you have a component library once you are midway into building your app is realizing it doesn't have all the tools that you need. </p>
<p><em>Check out the component libraries <strong>Ant Design</strong>, <strong>Material UI</strong> or <strong>Chakra UI</strong> for your next project. Or use a CSS-in-JS library like <strong>Emotion</strong> or <strong>Styled Components</strong> if you are interested in writing styles by hand.</em></p>
<h2 id="heading-5-a-hook-based-form-library">5. A Hook-Based Form Library</h2>
<p>Every React application you build will probably have a form. Needless to say, building forms are a pain!</p>
<p>Not only do you have to create the form itself, but you also have to add tricky things like input validation and error handling.</p>
<p><em>The best form libraries you can use in 2021 are <strong>React Hook Form</strong> and <strong>Formik</strong>.</em> </p>
<p>With the help of their built-in hooks, they make it incredibly easy to build reusable, functional forms. Even forms that have complex conditions, such as fields which are dependent upon one another or that require asynchronous validation. </p>
<p>It worth noting that Formik has changed in that we no longer need to use the traditional render props pattern that it previously utilized. </p>
<p>With Formic you can use a custom hook from the Formik package called <code>useFormik</code> which allows us to build our forms with the help of a custom hook of the same name.</p>
<p>Here's a basic form made with <code>useFormik</code>.</p>
<pre><code class="lang-js"> <span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
 <span class="hljs-keyword">import</span> { useFormik } <span class="hljs-keyword">from</span> <span class="hljs-string">'formik'</span>;

 <span class="hljs-keyword">const</span> SignupForm = <span class="hljs-function">() =&gt;</span> {
   <span class="hljs-keyword">const</span> formik = useFormik({
     <span class="hljs-attr">initialValues</span>: {
       <span class="hljs-attr">username</span>: <span class="hljs-string">''</span>,
       <span class="hljs-attr">email</span>: <span class="hljs-string">''</span>,
     },
     <span class="hljs-attr">onSubmit</span>: <span class="hljs-function"><span class="hljs-params">values</span> =&gt;</span> {
       alert(<span class="hljs-built_in">JSON</span>.stringify(values, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>));
     },
   });
   <span class="hljs-keyword">return</span> (
     <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{formik.handleSubmit}</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"name"</span>&gt;</span>Username<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
         <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span>
         <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span>
         <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
         <span class="hljs-attr">onChange</span>=<span class="hljs-string">{formik.handleChange}</span>
         <span class="hljs-attr">value</span>=<span class="hljs-string">{formik.values.username}</span>
       /&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"email"</span>&gt;</span>Email Address<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
         <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span>
         <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span>
         <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>
         <span class="hljs-attr">onChange</span>=<span class="hljs-string">{formik.handleChange}</span>
         <span class="hljs-attr">value</span>=<span class="hljs-string">{formik.values.email}</span>
       /&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
   );
 };
</code></pre>
<p>It's worth noting that the only thing that you might need on top of these libraries is a validation library. </p>
<p>Both Formik and React Hook Form are meant to integrate with validation libraries very easily such as the library Yup. How to do so is laid out very easily in their documentation.</p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Is React a Library or a Framework? Here's Why it Matters ]]>
                </title>
                <description>
                    <![CDATA[ Developers have spent a great deal of time talking about what React is. But they have left out why this topic matters so greatly for anyone who builds React applications. The answer to this question is essential for any React developer, regardless of... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/is-react-a-library-or-a-framework/</link>
                <guid isPermaLink="false">66d0379764be048ac359a323</guid>
                
                    <category>
                        <![CDATA[ framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Mon, 12 Apr 2021 21:29:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/04/is-react-a-library-or-framework.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Developers have spent a great deal of time talking about what React is. But they have left out why this topic matters so greatly for anyone who builds React applications.</p>
<p>The answer to this question is essential for any React developer, regardless of their skill level. This is because it indicates what they must know and how they must work in developing any React application.</p>
<p>Whether you are a new or an advanced React developer, I hope this thoughtful analysis will improve your own development process as you build your next React project.</p>
<h2 id="heading-why-is-react-a-library-and-not-a-framework">Why is React a library and not a framework?</h2>
<p>React was made to build full-fledged web applications. As a result, it's often compared with other tools that developers use to build apps, like Angular, Vue, and Svelte. </p>
<p>React is written in JavaScript and is used to make better JavaScript applications. We refer to React specifically as a <strong>library</strong>. </p>
<p><em>But what makes React a library and not a framework?</em> </p>
<p>The reason becomes clear when we look at other similar tools that are used to create complete web applications.</p>
<p>Let's look at a project like Angular, which shares the same purpose as React (to create single-page web apps). What sets it apart is the fact that when you set up an Angular project, it is bootstrapped with nearly every single thing that you'll need to make a complete, large-scale app. </p>
<blockquote>
<p>Many developers like to refer to frameworks or similar solutions as having "batteries included." </p>
</blockquote>
<p>Frameworks are a common choice for companies and anyone looking to make enterprise JavaScript applications, because they include resources that a large-scale application would likely need. This includes built-in tools for common tasks like creating forms, running automated tests, making network requests, and much more.</p>
<p>In short, everything that you need to make a complete application is included in your Angular project when it's generated. But that is not the case with React.</p>
<h2 id="heading-react-is-fundamentally-unopinionated">React is fundamentally "unopinionated"</h2>
<p>While popular tools have emerged like Create React App, which allow you to create a complete React project in a single command, React is often referred to as "unopinionated." </p>
<p><em>What does it mean for React to be unopinionated?</em></p>
<p>The React and React DOM libraries give us the means of building a user interface with the JSX syntax, plus powerful state management tools via hooks, among other things.</p>
<p>However, React itself does not include many of the React-specific libraries you're going to need for most projects. Angular and Vue, by comparison, include many more tools all bundled within the core package itself.</p>
<p>Many developers consider this discussion of what is and isn't a library to be trivial. But it has real consequences for our development process. In other words, because React is a library and not a framework, <strong>becoming a skilled React developer entails having a good knowledge of third-party React libraries</strong>.</p>
<h2 id="heading-since-react-is-a-library-you-must-choose-the-tools-on-your-own">Since React is a library, you must choose the tools on your own</h2>
<p>That means, in order to build complete React applications, you will need to choose these packages and tools on your own. </p>
<p>Here are a few examples of decisions that I often need to make when I'm building a React application myself: </p>
<p>For a form library, I have to decide whether I want to use the package React Hook Form or Formik. These are both React-specific form libraries to add important features to our forms like validation.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/react-form-libraries.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For testing my React application, I might use either React Testing Library, Jest, or some combination of the two.</p>
<p>For making network requests, I might need to choose between the Fetch API and Axios. I might also need to decide if I want to add an additional library to make managing my server state easier, such as React Query or SWR.</p>
<h2 id="heading-the-tools-you-choose-depend-on-your-app-and-knowledge-of-them">The tools you choose depend on your app and knowledge of them</h2>
<p>This question of whether React is a library or framework is important because any React developer must know what their choices are and which choice to make given the type of React application they're building.</p>
<p>If you're building an app without many forms, you might not need a form library at all. If you're more confident with the Fetch API, you might use that over something like Axios. </p>
<p>It really depends not only on what the demands of the app are, but also on what your preferences are as a developer. This is arguably an advantage that React has as a library and why I believe it's very popular among newer developers. It doesn't lock you into one choice or hold you to any specific libraries other than React itself. </p>
<p>You're able to make your own decisions, and you're able to have more freedom overall, as a developer. </p>
<p>That being said, even though React is not a framework this does not diminish its presence in the corporate realm. It's still used to build complex and impressive applications of all kinds. There are many lists of the large-scale React applications that businesses have made and which you likely use on a daily basis.</p>
<h2 id="heading-you-need-to-keep-up-with-emerging-libraries">You need to keep up with emerging libraries</h2>
<p>If we were talking about which form library to choose two years ago, I would likely have included Redux Form. As for a data fetching library, I couldn't have mentioned React Query or SWR, because they weren't created (or hadn't gained much traction), until the last year or so.</p>
<p>Because React apps are often reliant upon third-party libraries, newer libraries come about that improve upon the old ones. Individual developers and teams transition to different tools to get the job done and the ecosystem changes as a whole.</p>
<p>Like it or not, React being a library and not a framework entails a large, shifting network of other libraries we must be aware of to build our projects. Some of which may fall out of favor and be replaced by others or may become deprecated and no longer supported as open-source projects. </p>
<p>In short, React being a library may require us to pay more attention to what is going on <em>around</em> React, as compared to if it was a framework.</p>
<h2 id="heading-wish-react-was-a-framework-there-are-many">Wish React was a framework? There are many!</h2>
<p>It's worth noting that there are frameworks out there that are based upon React. </p>
<p>While React itself is just a library, many React-based frameworks have cropped up in recent years to provide developers with a more powerful set of built-in tools. These allow you to build projects faster without needing as many third-party libraries. </p>
<p>Some of the most popular of these frameworks include Next.js, Gatsby, and Redwood.js, all of which are used to create full-scale dynamic and static React applications.</p>
<p>This is, in my opinion, the great advantage of frameworks – you do not have to make as many choices throughout the development process.</p>
<h2 id="heading-use-reacts-flexibility-to-your-advantage">Use React's flexibility to your advantage</h2>
<p>Be aware that going forward, there is a robust ecosystem of React-focused libraries that you can add to your React project to achieve whatever you're looking for, from the most general tasks to the most specific. </p>
<p>This is thanks to React's popularity and widespread usage. But also note, especially if you're coming from an opinionated framework like Angular or Vue, that there are many React-based frameworks that you can rely upon and learn about to build equally functional and featureful applications as well.</p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Best React Libraries You Should Be Using Today ]]>
                </title>
                <description>
                    <![CDATA[ Let's take a look at five React libraries that serve as a great addition to any React project you're looking to build in 2021 and beyond.  I chose these libraries because not only do they help us build functional and impressive-looking applications, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-libraries-you-should-use/</link>
                <guid isPermaLink="false">66d037cdccf811d3117aeef1</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Thu, 08 Apr 2021 18:34:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/04/react-libraries-you-should-be-using.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Let's take a look at five React libraries that serve as a great addition to any React project you're looking to build in 2021 and beyond. </p>
<p>I chose these libraries because not only do they help us build functional and impressive-looking applications, but they also allow us to do so faster, easier, and with less code.</p>
<p>In this guide I'm going to show you how to get up and running with each of these libraries from scratch and integrate them into your projects today.</p>
<h2 id="heading-1-react-query">1. React Query</h2>
<p>Fetching data with React is generally a process that involves a lot of code.</p>
<p>You often need to use the <code>useEffect</code> hook in combination with <code>useState</code> to manage the fetched data. This requires a lot of boilerplate that we have to write in every component in which we want to fetch data. </p>
<p>React Query can help you cut down on the code you write when making network requests with React. All of this React code that we had to write before can be replaced with the hook <code>useQuery</code>. From it we get back all of the data that we need without having to declare a state variable:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/react-query.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>However, making data fetching easier only covers a small slice of what React Query does. What makes it a very powerful library is that it caches (saves) requests that we make. So in many cases if we've requested data before, we don't have to make another request, we can just read it from the cache. </p>
<p>This is immensely helpful because it cuts down repetition in our code, reduces the load we put on our API, and helps us manage our overall app state. If you pick any library to start adding to your projects today out of this list, make it React Query. </p>
<h2 id="heading-2-ant-design">2. Ant Design</h2>
<p>When it comes to making impressive-looking React apps, there are many helpful component libraries that allow us to quickly style our applications with the help of pre-made components. </p>
<p>There are lots of component libraries out there, but few that are as sophisticated and well designed as one called Ant Design. If you can think of a type of component to include within your React app interface and design, Ant Design almost certainly has it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/antd.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Using a component library like Ant Design speeds up our development time by reducing the amount of often unreliable styles that we have to write ourselves. </p>
<p>Additionally, these pre-made components provide functionality that would often be redundant to create ourselves, such as a common modal or tooltip. In most cases, we should opt for the reliable, proven solution rather than attempting to reinvent the wheel.</p>
<p>If you're thinking of building an application today and are looking for a solid component library, go with Ant Design. It has virtually every feature that you would need out of a component library, plus great customizability that serves any app feature you might consider implementing. </p>
<h2 id="heading-3-zustand">3. Zustand</h2>
<p>When it comes to managing state, React developers are often given two familiar choices: Redux or React Context. </p>
<p>Redux has been the go to third-party library that React developers use to manage state. But with the arrival of React Context in React version 16, we have an easier way to manage state by passing it around our component tree. </p>
<p>If you're looking for a library with all of the functionality and power of Redux, with the simplicity of React Context, look at the library Zustand. It's incredibly easy to get started with, as you can see in the example below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/zustand.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>It involves using the <code>create</code> function to make a dedicated state object that can include any state values and functions to update that state as we need. It can all be created within a few lines of code. </p>
<p>Plus, there's no need to use any context provider to pass your state to your app components. All you need to do is create a slice of state, call that created state as a hook, and receive whatever state variables and functions you've declared on the object within your React components. </p>
<p>Give Zustand a shot the next time you are looking for a more complex state solution like Redux for your application – you'll love it.</p>
<h2 id="heading-4-react-hook-form">4. React Hook Form</h2>
<p>When it comes to building forms in React, you probably know how tedious it can be to perform basic tasks like validating inputs, plus managing all the form and error state. </p>
<p>Perhaps the most user-friendly form library available today is React Hook Form. All the functionality that you need in a form library is provided in one simple hook, called <code>useForm</code>, and enables you to create forms as sophisticated as you like. </p>
<p>It takes control of managing our form state internally, gives us easy helpers to display errors for the appropriate input, and applies validation rules without any external libraries such as Yup – along with handling the submission of our form:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/react-hook-form.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>When it comes to building functional forms, you want a library that's easy to use and does not add too much code to your components. According to these two criteria, React Hook Form is arguably the best React form library out there. </p>
<h2 id="heading-5-react-responsive">5. React Responsive</h2>
<p>There's no question – every React application should be created for users on different devices and needs to be responsive. Meaning, it needs to adjust the styles and appearance according to the screen size or device that your users are on. </p>
<p>While media queries have typically been used in CSS stylesheets to hide and display different elements, the best React-based library to manage visibility or styles of React components is React Responsive. </p>
<p>It gives us a convenient <code>useMediaQuery</code> hook that enables us to pass in very precise conditions to determine whether users on a certain type of screen are using a certain device. Then they'll be able to adjust our user interface accordingly:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/react-responsive.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For making any React applications responsive without the use of CSS, be sure to check out the React Responsive library.</p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 10 Awesome JavaScript Libraries You Should Try Out ]]>
                </title>
                <description>
                    <![CDATA[ JavaScript is one of the most popular languages on the web. Even though it was initially developed just for web pages, it has seen exponential growth in the past two decades. Now, JavaScript is capable of doing almost anything and works on several pl... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/10-javascript-libraries-you-should-try/</link>
                <guid isPermaLink="false">66ba19a54a85bb09c10a6990</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh K Singh ]]>
                </dc:creator>
                <pubDate>Sun, 03 Jan 2021 17:32:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9999740569d1a4ca20a6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>JavaScript is one of the most popular languages on the web. Even though it was initially developed just for web pages, it has seen exponential growth in the past two decades.</p>
<p>Now, JavaScript is capable of doing almost anything and works on several platforms and devices including IoT. And with the recent SpaceX Dragon launch, JavaScript is even in space.</p>
<p>One of the reasons for its popularity is the availability of a large number of frameworks and libraries. They make development much easier compared to traditional Vanilla JS development.</p>
<p>There are libraries for almost anything and more are coming out almost every day. But with so many libraries to choose from it becomes difficult to keep a track of each one and how it might be tailored specifically to your needs.</p>
<p>In this article, we will discuss 10 of the most popular JS libraries which you can use to build your next project.</p>
<h1 id="heading-leaflethttpsleafletjscom"><a target="_blank" href="https://leafletjs.com/">Leaflet</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/image-17.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Leaflet</em></p>
<p>I think Leaflet is the best open source library for adding mobile-friendly interactive maps to your application.</p>
<p>Its small size (39kB) makes it a great alternative to consider over other map libraries. With cross-platform efficiency and a well-documented API, it has everything you need to make you fall in love.</p>
<p>Here is some sample code that creates a Leaflet map:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> map = <span class="hljs-keyword">new</span> L.Map(<span class="hljs-string">"map"</span>, {
    <span class="hljs-attr">center</span>: <span class="hljs-keyword">new</span> L.LatLng(<span class="hljs-number">40.7401</span>, <span class="hljs-number">-73.9891</span>),
    <span class="hljs-attr">zoom</span>: <span class="hljs-number">12</span>,
    <span class="hljs-attr">layers</span>: <span class="hljs-keyword">new</span> L.TileLayer(<span class="hljs-string">"https://tile.openstreetmap.org/{z}/{x}/{y}.png"</span>)
});
</code></pre>
<p>In Leaflet, we need to provide a tile layer since there isn't one by default. But that also means that can choose from a wide range of layers both free and premium. You can explore various free tile layers <a target="_blank" href="https://leaflet-extras.github.io/leaflet-providers/preview/">here</a>.</p>
<p>Read the <a target="_blank" href="https://leafletjs.com/reference-1.6.0.html">Docs</a> or follow the <a target="_blank" href="https://leafletjs.com/examples.html">Tutorials</a> to learn more.</p>
<h1 id="heading-fullpagejshttpsalvarotrigocomfullpage"><a target="_blank" href="https://alvarotrigo.com/fullPage/">fullPage.js</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ezgif.com-video-to-gif-1--1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This open-source library helps you create full-screen scrolling websites as you can see in the above GIF. It's easy to use and has many options to customize, so it's no surprise it is used by thousands of developers and has over 30k stars on GitHub.</p>
<p>Here is a Codepen demo that you can play with:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/lelouchb/embed/WNrLvLG" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>You can even use it with popular frameworks such as:</p>
<ul>
<li><p><a target="_blank" href="https://alvarotrigo.com/react-fullpage/">react-fullpage</a></p>
</li>
<li><p><a target="_blank" href="https://alvarotrigo.com/vue-fullpage/">vue-fullpage</a></p>
</li>
<li><p><a target="_blank" href="https://alvarotrigo.com/angular-fullpage/">angular-fullpage</a></p>
</li>
</ul>
<p>I came across this library about a year ago and since then it has become one of my favorites. This is one of the few libraries that you can use in almost every project. If you haven't already started using it then just try it, you will not be disappointed.</p>
<h1 id="heading-animejshttpsanimejscom"><a target="_blank" href="https://animejs.com/">anime.js</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/anime.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>anime.js</em></p>
<p>One of the best animation libraries out there, Anime.js is flexible and simple to use. It is the perfect tool to help you add some really cool animation to your project.</p>
<p>Anime.js works well with CSS properties, SVG, DOM attributes, and JavaScript Objects and can be easily integrated into your applications.</p>
<p>As a developer it's important to have a good portfolio. The first impression people have of your portfolio helps decide whether they will hire you or not. And what better tool than this library to bring life to your portfolio. It will not only enhance your website but will help showcase actual skills.</p>
<p>Check out this Codepen to learn more:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/lelouchb/embed/XWXoboE" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>You can also take a look at all the other cool projects on <a target="_blank" href="https://codepen.io/collection/XLebem">Codepen</a> or <a target="_blank" href="https://animejs.com/documentation/">Read the Docs here</a>.</p>
<h1 id="heading-screenfulljshttpsgithubcomsindresorhusscreenfulljs"><a target="_blank" href="https://github.com/sindresorhus/screenfull.js">Screenfull.js</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/image-29.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>screenfull.js</em></p>
<p>I came across this library while searching for a way to implement a full-screen feature in my project.</p>
<p>If you also want to have a full-screen feature, I would recommend using this library instead of <a target="_blank" href="https://developer.mozilla.org/en/DOM/Using_full-screen_mode">Fullscreen API</a> because of its cross-browser efficiency (although it is built on top of that).</p>
<p>It is so small that you won't even notice it – just about 0.7kB gzipped.</p>
<p>Try the <a target="_blank" href="https://sindresorhus.com/screenfull.js">Demo</a> or read the <a target="_blank" href="https://github.com/sindresorhus/screenfull.js">Docs</a> to learn more.</p>
<h1 id="heading-momentjshttpsmomentjscom"><a target="_blank" href="https://momentjs.com/">Moment.js</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/image-18.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Moment.js</em></p>
<p>Working with date and time can be a huge pain, especially with API calls, different Time Zones, local languages, and so on. Moment.js can help you solve all those issues whether it is manipulating, validating, parsing, or formatting dates or time.</p>
<p>There are so many cool methods that are really useful for your projects. For example, I used the <code>.fromNow()</code> method in one of my blog projects to show the time the article was published.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> moment = <span class="hljs-built_in">require</span>(<span class="hljs-string">'moment'</span>); 

relativeTimeOfPost = moment([<span class="hljs-number">2019</span>, <span class="hljs-number">07</span>, <span class="hljs-number">13</span>]).fromNow(); 
<span class="hljs-comment">// a year ago</span>
</code></pre>
<p>Although I don't use it very often, I am a fan of its support for internationalization. For example, we can customize the above result using the <code>.locale()</code> method.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// French</span>
moment.locale(<span class="hljs-string">'fr'</span>);
relativeTimeOfPostInFrench = moment([<span class="hljs-number">2019</span>, <span class="hljs-number">07</span>, <span class="hljs-number">13</span>]).fromNow(); 
<span class="hljs-comment">//il y a un an</span>

<span class="hljs-comment">// Spanish</span>
moment.locale(<span class="hljs-string">'es'</span>);
relativeTimeOfPostInSpanish = moment([<span class="hljs-number">2019</span>, <span class="hljs-number">07</span>, <span class="hljs-number">13</span>]).fromNow(); 
<span class="hljs-comment">//hace un año</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ezgif.com-video-to-gif.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Moment.js Homepage</em></p>
<p>Read the <a target="_blank" href="https://momentjs.com/">Docs here</a>.</p>
<p><strong>Update September 2020:</strong> Moment.js has entered maintenance mode. Read more about it <a target="_blank" href="https://momentjs.com/docs/#/-project-status/">here</a>. You may want to explore alternatives such as <a target="_blank" href="https://day.js.org/">Day.js</a> or <a target="_blank" href="https://date-fns.org/">date-fns</a>.</p>
<h1 id="heading-hammerjshttphammerjsgithubio"><a target="_blank" href="http://hammerjs.github.io/">Hammer.js</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ezgif.com-video-to-gif-2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Hammer.js is a lightweight JavaScript library that lets you add multi-touch gestures to your Web Apps.</p>
<p>I would recommend this library to add some fun to your components. Here is an example to play with. Just run the pen and tap or click on the grey div.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/lelouchb/embed/abdPOPj" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>It can recognize gestures made by touch, mouse and pointerEvents. For jQuery users I would recommend using the <a target="_blank" href="http://hammerjs.github.io/jquery-plugin/">jQuery plugin</a>.</p>
<pre><code class="lang-javascript">$(element).hammer(options).bind(<span class="hljs-string">"pan"</span>, myPanHandler);
</code></pre>
<p>Read the <a target="_blank" href="http://hammerjs.github.io/getting-started/">Docs here</a>.</p>
<h1 id="heading-masonryhttpsmasonrydesandrocom"><a target="_blank" href="https://masonry.desandro.com/">Masonry</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/image-20.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Masonry</em></p>
<p>Masonry is a JavaScript grid layout library. It is super awesome and I use it for many of my projects. It can take your simple grid elements and place them based on the available vertical space, sort of like how contractors fit stones or blocks into a wall.</p>
<p>You can use this library to show your projects in a different light. Use it with cards, images, modals, and so on.</p>
<p>Here is a simple example to show you the magic in action. Well, not magic exactly, but how the layout changes when you <strong>zoom in</strong> on the web page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ezgif.com-crop.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And here is the code for the above:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> elem = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.grid'</span>);
<span class="hljs-keyword">var</span> msnry = <span class="hljs-keyword">new</span> Masonry( elem, {
  <span class="hljs-attr">itemSelector</span>: <span class="hljs-string">'.grid-item'</span>,
  <span class="hljs-attr">columnWidth</span>: <span class="hljs-number">400</span>
});

<span class="hljs-keyword">var</span> msnry = <span class="hljs-keyword">new</span> Masonry( <span class="hljs-string">'.grid'</span>);
</code></pre>
<p>Here is a cool demo on Codepen:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/lelouchb/embed/qBbLdLQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>Check out these Projects</p>
<ul>
<li><p><a target="_blank" href="https://halcyon-theme.tumblr.com/">https://halcyon-theme.tumblr.com/</a></p>
</li>
<li><p><a target="_blank" href="https://tympanus.net/Development/GridLoadingEffects/index.html">https://tympanus.net/Development/GridLoadingEffects/index.html</a></p>
</li>
<li><p><a target="_blank" href="https://www.erikjo.com/work">https://www.erikjo.com/work</a></p>
</li>
</ul>
<h1 id="heading-d3jshttpsd3jsorg"><a target="_blank" href="https://d3js.org/">D3.js</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/image-30.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you are a data-obsessed developer then this library is for you. I have yet to find a library that manipulates data as efficiently and beautifully as D3. With over 92k stars on GitHub, D3 is the favorite data visualization library of many developers.</p>
<p>I recently used D3 to visualize COVID-19 data with React and the <a target="_blank" href="https://github.com/CSSEGISandData/COVID-19">Johns Hopkins CSSE Data Repository on GitHub</a>. It I was a really interesting project, and if you are thinking of doing something similar, I would suggest giving D3.js a try.</p>
<p>Read more about it <a target="_blank" href="https://github.com/d3/d3/wiki">here</a>.</p>
<h1 id="heading-slickhttpskenwheelergithubioslick"><a target="_blank" href="https://kenwheeler.github.io/slick/">slick</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/image-23.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>slick</em></p>
<p>Slick is fully responsive, swipe-enabled, infinite looping, and more. As mentioned on the homepage it truly is the last carousel you'll ever need.</p>
<p>I have been using this library for quite a while, and it has saved me so much time. With just a few lines of code, you can add so many features to your carousel.</p>
<pre><code class="lang-js">$(<span class="hljs-string">'.autoplay'</span>).slick({
  <span class="hljs-attr">slidesToShow</span>: <span class="hljs-number">3</span>,
  <span class="hljs-attr">slidesToScroll</span>: <span class="hljs-number">1</span>,
  <span class="hljs-attr">autoplay</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">autoplaySpeed</span>: <span class="hljs-number">2000</span>,
});
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ezgif.com-video-to-gif-2-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Autoplay</em></p>
<p>Check out the demos <a target="_blank" href="https://kenwheeler.github.io/slick/">here</a>.</p>
<h1 id="heading-popperjshttpspopperjsorg"><a target="_blank" href="https://popper.js.org/">Popper.js</a></h1>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/image-25.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Popper.js</em></p>
<p>Popper.js is a lightweight ~3 kB JavaScript library with zero dependencies that provides a reliable and extensible positioning engine you can use to ensure all your popper elements are positioned in the right place.</p>
<p>It may not seem important to spend time configuring popper elements, but these little things are what make you stand out as a developer. And with such small size it doesn't take up much space.</p>
<p>Read the <a target="_blank" href="https://popper.js.org/docs/v2/">Docs here</a>.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>As a developer, having and using the right JavaScript libraries is important. It will make you more productive and will make development much easier and faster. In the end, it is up to you which library to prefer based on your needs.</p>
<p>These are 10 JavaScript libraries that you can try and start using in your projects today. What other cool JavaScript libraries you use? Would you like another article like this? <a target="_blank" href="https://twitter.com/noharashutosh">Tweet</a> and let me know.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Chakra UI with Next.js and React ]]>
                </title>
                <description>
                    <![CDATA[ Building websites and applications is hard. There are a lot of things to consider to make sure our apps are usable and accessible including how our React components work.  How can we take advantage of the power of Chakra UI to build great web apps? ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-chakra-ui-with-next-js-and-react/</link>
                <guid isPermaLink="false">66b8e37147e3b55b9fb6ee47</guid>
                
                    <category>
                        <![CDATA[ components ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Wed, 21 Oct 2020 00:16:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/10/chakra.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building websites and applications is hard. There are a lot of things to consider to make sure our apps are usable and accessible including how our React components work. </p>
<p>How can we take advantage of the power of Chakra UI to build great web apps?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-chakra-ui">What is Chakra UI?</a></li>
<li><a class="post-section-overview" href="#heading-what-makes-chakra-ui-so-great">What makes Chakra UI so great?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-creating-a-new-react-project-with-nextjs">Step 0: Creating a new React project with Next.js</a></li>
<li><a class="post-section-overview" href="#heading-step-1-installing-and-configuring-chakra-ui-in-nextjs">Step 1: Installing and configuring Chakra UI in Next.js</a></li>
<li><a class="post-section-overview" href="#heading-step-2-adding-chakra-ui-components-to-a-react-app">Step 2: Adding Chakra UI components to a React app</a></li>
<li><a class="post-section-overview" href="#heading-step-3-making-responsive-components-with-chakra-ui">Step 3: Making responsive components with Chakra UI</a></li>
<li><a class="post-section-overview" href="#heading-step-4-customizing-the-default-chakra-ui-theme">Step 4: Customizing the default Chakra UI theme</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/ubB5l-HVPgY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-is-chakra-ui">What is Chakra UI?</h2>
<p><a target="_blank" href="https://chakra-ui.com/">Chakra UI</a> is a component library for React that makes it easy to build the UI of an app or website.</p>
<p>Their goal is to provide a simple, modular, and accessible set of components to get up and running quickly.</p>
<h2 id="heading-what-makes-chakra-ui-so-great">What makes Chakra UI so great?</h2>
<p>To start, by default Chakra strives to make each component accessible. It’s a critical part of application development that’s often overlooked, and the Chakra maintainers have gone out of their way to ensure the components follow the <a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/aria/">WAI-ARIA guidelines</a>.</p>
<p>Chakra also includes a simple API allowing developers to get productive. It allows people and teams to make inclusive apps without having to worry about building a bunch of components themselves.</p>
<p>For styling and customization, Chakra uses <a target="_blank" href="https://emotion.sh/">Emotion</a> under the hood to provide developers the ability to style their components right inside of their JavaScript with style props. It comes with a default theme, but allows the ability to easily override it with custom settings.</p>
<h2 id="heading-what-are-we-going-to-build">What are we going to build?</h2>
<p>To get a good idea of how Chakra works, we’re going to essentially rebuild the default Next.js template with Chakra UI components.</p>
<p>This will help us understand a few important concepts, such as how to use Chakra UI with Next.js, how to add custom styles with props, and how to customize the Chakra UI theme.</p>
<p>The concepts here can apply pretty much to any <a target="_blank" href="https://reactjs.org/">React</a> app, though the examples will be slightly specific to Next.js.</p>
<h2 id="heading-step-0-creating-a-new-react-project-with-nextjs">Step 0: Creating a new React project with Next.js</h2>
<p>To get started, we need a React app. We’re going to use Next.js as our framework which will give us the ability to easily spin up a new app.</p>
<p>Once inside the directory you want to create your project in, run:</p>
<pre><code>yarn create next-app my-chakra-app
# or
npx create-next-app my-chakra-app
</code></pre><p>Note: feel free to change <code>my-chakra-app</code> to whatever you want to name the project directory.</p>
<p>And once that’s finished, you can navigate into that directory and start the project with:</p>
<pre><code>yarn dev
# or
npm run dev
</code></pre><p>That should spin up your development server at <a target="_blank" href="http://localhost:3000">http://localhost:3000</a> and we should be ready to go!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/nextjs-default-template.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Default Next.js template</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-chakra-app/commit/01f6ec8d961eb197fe3e8a32e498d07bf0be269b">Follow along with the commit!</a></p>
<h2 id="heading-step-1-installing-and-configuring-chakra-ui-in-nextjs">Step 1: Installing and configuring Chakra UI in Next.js</h2>
<p>Next, let’s install Chakra UI.</p>
<p>Inside of your project directory, run:</p>
<pre><code>yarn add @chakra-ui/core @emotion/core @emotion/styled emotion-theming
# or 
npm install @chakra-ui/core @emotion/core @emotion/styled emotion-theming
</code></pre><p>This will install Chakra UI and its dependencies, which includes Emotion, as it relies on it for the styling.</p>
<p>To get Chakra working inside of our app, we need to configure a Provider at the root of our application. This will allow all of Chakra’s components to talk to each other and use the configuration to maintain consistent styles.</p>
<p>Inside <code>pages/_app.js</code>, first let’s import our Provider at the top:</p>
<pre><code><span class="hljs-keyword">import</span> { ThemeProvider, theme } <span class="hljs-keyword">from</span> <span class="hljs-string">'@chakra-ui/core'</span>;
</code></pre><p>Next, replace the return statement inside of the component with:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyApp</span>(<span class="hljs-params">{ Component, pageProps }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ThemeProvider</span> <span class="hljs-attr">theme</span>=<span class="hljs-string">{theme}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Component</span> {<span class="hljs-attr">...pageProps</span>} /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ThemeProvider</span>&gt;</span></span>
  )
}
</code></pre>
<p>As you’ll notice, we’re also passing a <code>theme</code> variable to our provider. We’re importing the Chakra UI default theme straight from Chakra and passing it in to our <code>ThemeProvider</code> so all of our components can get the default styles and configurations.</p>
<p>Finally, we want to add a component called <code>CSSReset</code> right as a direct child of our <code>ThemeProvider</code>.</p>
<p>First, add <code>CSSReset</code> as an import:</p>
<pre><code><span class="hljs-keyword">import</span> { ThemeProvider, theme, CSSReset } <span class="hljs-keyword">from</span> <span class="hljs-string">'@chakra-ui/core'</span>;
</code></pre><p>Then add the component right inside <code>ThemeProvider</code>:</p>
<pre><code class="lang-jsx">&lt;ThemeProvider theme={theme}&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">CSSReset</span> /&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Component</span> {<span class="hljs-attr">...pageProps</span>} /&gt;</span></span>
&lt;/ThemeProvider&gt;
</code></pre>
<p>And now if we reload the page, we can see that things are looking a little bit different!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/nextjs-chakra-ui-css-reset.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js with Chakra UI CSS Reset</em></p>
<p>The browser comes with a lot of default styles and by default, Chakra UI doesn’t override them. This includes styles like borders on a button element.</p>
<p>While we don’t necessarily need the CSS Reset here, we could override those things manually. This provides us with a foundation where we’ll know that Chakra UI is working as it’s intended to and we can start adding our components.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-chakra-app/commit/8538b3609cfac71b6ece60e36314edf9a189941b">Follow along with the commit!</a></p>
<h2 id="heading-step-2-adding-chakra-ui-components-to-a-react-app">Step 2: Adding Chakra UI components to a React app</h2>
<p>Now for the fun part. We’re going to use Chakra UI components to try to rebuild the Next.js default template. It’s not going to look 100% exactly like it, but it will carry the spirit and we can customize it as we’d like.</p>
<h3 id="heading-building-the-title-and-description">Building the Title and Description</h3>
<p>Starting from the top, let’s update our title and description.</p>
<p>At the top of the page, we need to import our <code>Heading</code> component:</p>
<pre><code><span class="hljs-keyword">import</span> { Heading, Link } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/core"</span>;
</code></pre><p>Then let’s replace the <code>&lt;h1&gt;</code> with:</p>
<pre><code class="lang-jsx">&lt;Heading <span class="hljs-keyword">as</span>=<span class="hljs-string">"h1"</span> size=<span class="hljs-string">"2xl"</span> mb=<span class="hljs-string">"2"</span>&gt;
  Welcome to Next.js!
&lt;/Heading&gt;
</code></pre>
<p>Here, we’re using the <a target="_blank" href="https://chakra-ui.com/heading">Heading</a> component which we then set “as” an <code>h1</code>. We can use any HTML heading element tag name, but since we’re replacing an h1, we want to use that.</p>
<p>We’re also setting a <code>size</code> attribute, which allows us to control how big out heading is, as well as <code>mb</code>, which stands for <code>margin-bottom</code>, allowing us to add some space below.</p>
<p>And we can already see our page is looking more like the default template.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-heading-component.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI Heading component</em></p>
<p>We also want to add back our link.</p>
<p>Add <code>Link</code> to our import statement at the top and then inside of our <code>&lt;Heading&gt;</code> component, replace the Next.js text with:</p>
<pre><code class="lang-jsx">&lt;Link color=<span class="hljs-string">"teal.500"</span> href=<span class="hljs-string">"https://nextjs.org"</span>&gt;Next.js!&lt;/Link&gt;
</code></pre>
<p>Chakra’s <a target="_blank" href="https://chakra-ui.com/link">Link</a> component creates a link as expected, but then allows us to use the style props to customize it. Here, we’re using the color variable <code>teal.500</code> that Chakra provides to change our link to Chakra’s colors.</p>
<p>And we can see that we have our Next.js link!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-heading-with-link.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI Heading with Link component</em></p>
<p>The last piece of the header is the description. For that, we want to use the Text component.</p>
<p>Add <code>Text</code>  and <code>Code</code> to the import statement and replace the description with:</p>
<pre><code class="lang-jsx">&lt;Text fontSize=<span class="hljs-string">"xl"</span> mt=<span class="hljs-string">"2"</span>&gt;
  Get started by editing &lt;Code&gt;pages/index.js&lt;/Code&gt;
&lt;/Text&gt;
</code></pre>
<p>We’re using the <a target="_blank" href="https://chakra-ui.com/text">Text</a> component to recreate a <code>&lt;p&gt;</code> tag and the <a target="_blank" href="https://chakra-ui.com/code">Code</a> component to create our <code>&lt;code&gt;</code> tag. Similar to our Heading component, we’re adding a <code>fontSize</code> to make the font bigger and <code>mt</code> which stands for <code>margin-top</code> to add some space above it.</p>
<p>And now we have our header!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-text-with-code-component.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI Text component with Code</em></p>
<h3 id="heading-replacing-info-cards-with-chakra-ui-components">Replacing info cards with Chakra UI components</h3>
<p>For each of our cards, we can use the same concepts as we did with the header to recreate each of our boxes.</p>
<p>To start, add an import for the <code>Flex</code> component and replace the tag <code>&lt;div className={styles.grid}&gt;</code> with:</p>
<pre><code class="lang-jsx">&lt;Flex flexWrap=<span class="hljs-string">"wrap"</span> alignItems=<span class="hljs-string">"center"</span> justifyContent=<span class="hljs-string">"center"</span> maxW=<span class="hljs-string">"800px"</span> mt=<span class="hljs-string">"10"</span>&gt;
  ...
&lt;/Flex&gt;
</code></pre>
<p>Make sure to leave all of the cards inside of the Flex component. The <a target="_blank" href="https://chakra-ui.com/flex">Flex</a> component will recreate our grid by adding Flexbox along with the same properties that were on the grid before.</p>
<p>At this point, it should exactly the same as it did before.</p>
<p>Next, add <code>Box</code> to the import statement and then replace the first card with:</p>
<pre><code class="lang-jsx">&lt;Box <span class="hljs-keyword">as</span>=<span class="hljs-string">"a"</span> href=<span class="hljs-string">"https://nextjs.org/docs"</span> p=<span class="hljs-string">"6"</span> m=<span class="hljs-string">"4"</span> borderWidth=<span class="hljs-string">"1px"</span> rounded=<span class="hljs-string">"lg"</span> flexBasis=<span class="hljs-string">"45%"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h3"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"lg"</span> <span class="hljs-attr">mb</span>=<span class="hljs-string">"2"</span>&gt;</span>Documentation <span class="hljs-symbol">&amp;rarr;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">fontSize</span>=<span class="hljs-string">"lg"</span>&gt;</span>Find in-depth information about Next.js features and API.<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span></span>
&lt;/Box&gt;
</code></pre>
<p>Similar to our Heading component, we’re setting our <a target="_blank" href="https://chakra-ui.com/box">Box</a> component “as” an <code>&lt;a&gt;</code> tag allowing it to serve as a link. We then configure our style props to replicate our cards.</p>
<p>Inside of that, we use the Heading and Text component to recreate the actual content of the cards.</p>
<p>And after only changing the first card, we can now see the changes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-box-component.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI Box component</em></p>
<p>Now, we can go back and replace the other three cards with the same components to finish recreating our grid.</p>
<p>For fun, we can add a 5th card that links to Chakra UI:</p>
<pre><code class="lang-jsx">&lt;Box <span class="hljs-keyword">as</span>=<span class="hljs-string">"a"</span> href=<span class="hljs-string">"https://chakra-ui.com/"</span> p=<span class="hljs-string">"6"</span> m=<span class="hljs-string">"4"</span> borderWidth=<span class="hljs-string">"1px"</span> rounded=<span class="hljs-string">"lg"</span> flexBasis=<span class="hljs-string">"45%"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h3"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"lg"</span> <span class="hljs-attr">mb</span>=<span class="hljs-string">"2"</span>&gt;</span>Chakra UI <span class="hljs-symbol">&amp;rarr;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">fontSize</span>=<span class="hljs-string">"lg"</span>&gt;</span>Build accessible React apps &amp; websites with speed.<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span></span>
&lt;/Box&gt;
</code></pre>
<p>And with all of our changes, we can now see our recreated Next.js starting template!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-nextjs-grid.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI recreating Next.js grid</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-chakra-app/commit/a324f8cd1d4120027a7f4dbcb16f45980de5495a">Follow along with the commit!</a></p>
<h2 id="heading-step-3-making-responsive-components-with-chakra-ui">Step 3: Making responsive components with Chakra UI</h2>
<p>Part of what the default Next.js grid was able to provide was the ability for the cards to expand to full width once the size of the browser becomes small enough. This is particularly relevant at <code>600px</code>, which typically means someone’s on a mobile device.</p>
<p>If we look at our page on a mobile device, we can see that our cards aren’t filling up the entire width.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-not-responsive.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI default without responsive</em></p>
<p>Chakra allows us to <a target="_blank" href="https://chakra-ui.com/responsive-styles">set responsive styles</a> with its baked in sizing, allowing us to easily recreate our responsive grid cards.</p>
<p>To do this, instead of passing in a single value to our style props, we can pass in an array.</p>
<p>For instance, on each of our Box components, let’s update the <code>flexBasis</code> prop to:</p>
<pre><code class="lang-jsx">flexBasis={[<span class="hljs-string">'auto'</span>, <span class="hljs-string">'45%'</span>]}
</code></pre>
<p>Here, according to Chakra’s <a target="_blank" href="https://chakra-ui.com/responsive-styles">default responsive breakpoints</a> , we’re saying that by default, we want our <code>flexBasis</code> to be set as <code>auto</code>. But for anything <code>480px</code> and larger, again which is Chakra’s default first breakpoint, we set it to <code>45%</code>.</p>
<p>Chakra considers its responsive styling to be mobile first, which is why you see the <code>480px</code> act as a minimum size, not a maximum size.</p>
<p>And with that change, we can now see that on a large device, we still have our grid.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-large-device.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI components on large device</em></p>
<p>But now on mobile, our cards take up the entire width!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/chakra-ui-small-device.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chakra UI components on small device</em></p>
<p>Using the array pattern works for all of the breakpoints, so if you wanted more control over your styles, Chakra lets you do that.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-chakra-app/commit/c08e80b60395aa738eaa8f8eb411ca7004ffac9d">Follow along with the commit!</a></p>
<h2 id="heading-step-4-customizing-the-default-chakra-ui-theme">Step 4: Customizing the default Chakra UI theme</h2>
<p>While Chakra provides a pretty great default theme, we also have the ability to customize it to our liking to match our brand or personal taste.</p>
<p>For instance, while the teal that we used for our Heading link is great and uses Chakra’s styles, what if I wanted to customize all links to use the purple that I <a target="_blank" href="https://colbyfayock.com/">use on my website</a>?</p>
<p>To start, Chakra comes with a default purple, so we can update our link to use that purple:</p>
<pre><code class="lang-jsx">Welcome to &lt;Link color=<span class="hljs-string">"purple.500"</span> href=<span class="hljs-string">"https://nextjs.org"</span>&gt;Next.js!&lt;/Link&gt;
</code></pre>
<p>And we see our change.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/nextjs-purple-header.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Making Next.js header link purple with color style prop</em></p>
<p>That looks great, but let’s update it to the exact purple I use.</p>
<p>Inside of <code>pages/_app.js</code>, we’re going to create a new object at the top of the page, where we spread the default theme creating a new theme object. We’ll also replace the <code>theme</code> prop with our new object:</p>
<pre><code><span class="hljs-keyword">const</span> customTheme = {
  ...theme
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyApp</span>(<span class="hljs-params">{ Component, pageProps }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ThemeProvider</span> <span class="hljs-attr">theme</span>=<span class="hljs-string">{customTheme}</span>&gt;</span></span>
</code></pre><p>If we save and reload the page, it will look exactly the same.</p>
<p>Next, we want to update the colors, so in our custom theme object, let’s add the colors property, where we can then set our custom purple:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> customTheme = {
  ...theme,
  <span class="hljs-attr">colors</span>: {
    ...theme.colors,
    <span class="hljs-attr">purple</span>: <span class="hljs-string">'#692ba8'</span>
  }
}
</code></pre>
<p>Note: you’ll see here that we’re also spreading <code>theme.colors</code>. If we don’t, we’ll be replacing the colors object with only the purple value, meaning we won’t have any other colors.</p>
<p>But if we reload the page, our link isn’t purple anymore!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/nextjs-link-no-color.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js link with no color</em></p>
<p>Chakra typically uses ranges of colors which allows us to use different shades of each of the colors. In our Link component, we’re specifying <code>purple.500</code> which we didn’t set to exist.</p>
<p>So to fix that, we can use a tool like <a target="_blank" href="https://smart-swatch.netlify.app/#692ba8">Smart Swatch</a> to get all of our color values that we need and set those in our custom theme object:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> customTheme = {
  ...theme,
  <span class="hljs-attr">colors</span>: {
    ...theme.colors,
    <span class="hljs-attr">purple</span>: {
      <span class="hljs-number">50</span>: <span class="hljs-string">'#f5e9ff'</span>,
      <span class="hljs-number">100</span>: <span class="hljs-string">'#dac1f3'</span>,
      <span class="hljs-number">200</span>: <span class="hljs-string">'#c098e7'</span>,
      <span class="hljs-number">300</span>: <span class="hljs-string">'#a571dc'</span>,
      <span class="hljs-number">400</span>: <span class="hljs-string">'#8c48d0'</span>,
      <span class="hljs-number">500</span>: <span class="hljs-string">'#722fb7'</span>,
      <span class="hljs-number">600</span>: <span class="hljs-string">'#59238f'</span>,
      <span class="hljs-number">700</span>: <span class="hljs-string">'#3f1968'</span>,
      <span class="hljs-number">800</span>: <span class="hljs-string">'#260f40'</span>,
      <span class="hljs-number">900</span>: <span class="hljs-string">'#10031a'</span>,
    }
  }
}
</code></pre>
<p>Tip: Smart Swatch actually lets you copy those values as a JavaScript object, making it easier to paste into our theme!</p>
<p>And now if we reload the page, we can see our purple!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/nextjs-custom-purple.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js with custom purple</em></p>
<p>While we used a range value here, we can also specify color variables without a range.</p>
<p>Say I wanted to leave the default Chakra purple “as is” but provide a way for me to reference my purple.</p>
<p>To do that, I could remove those purple values and add a new custom variable:</p>
<pre><code><span class="hljs-keyword">const</span> customTheme = {
  ...theme,
  <span class="hljs-attr">colors</span>: {
    ...theme.colors,
    <span class="hljs-attr">spacejelly</span>: <span class="hljs-string">'#692ba8'</span>
  }
}
</code></pre><p>Then update my Link to use that color:</p>
<pre><code class="lang-jsx">Welcome to &lt;Link color=<span class="hljs-string">"spacejelly"</span> href=<span class="hljs-string">"https://nextjs.org"</span>&gt;Next.js!&lt;/Link&gt;
</code></pre>
<p>And we can see that we’re now using our purple without overriding the original:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/nextjs-spacejelly-purple.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js with custom color variable</em></p>
<p>We can apply this to most parts of the styles of Chakra, including Typography and setting custom Breakpoints. It’s another way to make our project custom to our own while still taking advantage of the power of Chakra!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-chakra-app/commit/b9d707ce3324207c25c2348934ca0c506402bd2f">Follow along with the commit!</a></p>
<h2 id="heading-what-else-can-you-do-with-chakra-ui">What else can you do with Chakra UI?</h2>
<p>While we went through some simpler examples, it really opens the door to more complex style changes and controls that Chakra provides with its component APIs.</p>
<p>There are also a whole lot of awesome components that you can use to transform your website or application and make development fast and easy!</p>
<p>They even <a target="_blank" href="https://chakra-ui.com/recipes">provide recipes</a> that have some examples of how you can combine the components resulting in powerful functionality. This includes a responsive header and even adding animations with Framer Motion.</p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">? Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
    <li>
      <a href="https://github.com/sponsors/colbyfayock">? Sponsor Me</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ COM Interface API Tutorial: Java Spring Boot + JACOB Library ]]>
                </title>
                <description>
                    <![CDATA[ By Serhii Povisenko In this article, I will show you how to embed the JACOB library into your Spring Boot application. This will help you call a COM interface API via the DLL library in your web application. Also, for illustrative purposes, I will pr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/interface-in-java-tutorial-how-to-call-the-com-interface-spring-boot-jacob-library/</link>
                <guid isPermaLink="false">66d4608bd1ffc3d3eb89de36</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spring-boot ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 30 Sep 2020 05:07:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/09/Screenshot-2020-09-29-at-15.49.33.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Serhii Povisenko</p>
<p>In this article, I will show you how to embed the <a target="_blank" href="https://sourceforge.net/projects/jacob-project/">JACOB library</a> into your <a target="_blank" href="https://spring.io/projects/spring-boot">Spring Boot</a> application. This will help you call a <a target="_blank" href="https://en.wikipedia.org/wiki/Component_Object_Model">COM interface API</a> via the <a target="_blank" href="https://en.wikipedia.org/wiki/Dynamic-link_library">DLL</a> library in your web application.</p>
<p>Also, for illustrative purposes, I will provide a description of a COM API so you can build your application on top of it. You can find all the code snippets in this <a target="_blank" href="https://github.com/povisenko/jacob-within-spring-boot-2">GitHub repo</a>.</p>
<p>But first, a quick note: at <a target="_blank" href="https://cthesigns.co.uk">C the Signs</a> we deployed this solution that allowed us to integrate with <a target="_blank" href="https://www.emishealth.com">EMIS Health</a>. It is an electronic patient record system used in primary care in the United Kingdom. For integration we used their provided DLL library.</p>
<p>The approach that I'll show you here (sanitised to avoid leaking any sensitive information) rolled out to production more than two years ago, and has since proven its durability.</p>
<p>Since we recently employed a brand new approach to integrating with EMIS, the old system is going to be shut down in a month or two. So this tutorial is its swan song. Sleep, my little prince.</p>
<h2 id="heading-what-is-the-dll-api">What is the DLL API?</h2>
<p>First, let's start with a clear description of the DLL library. To do this, I prepared a short mock-up of the original technical documentation.</p>
<p>Let's take a look through it to see what the three methods of a COM interface are.</p>
<h3 id="heading-initialisewithid-method">InitialiseWithID Method</h3>
<p>This method is a security feature required on-site that lets us obtain a connection to an API server that we want to integrate with the library.</p>
<p>It requires the <code>AccountID</code> (GUID) of the current API user (to access the server) and some other initialization arguments that are listed below.</p>
<p>This function also supports an auto-login feature. If a client has a logged-in version of the running system (the library is a part of that system) and calls the method on the same host, the API will automatically complete the login under that user's account. Then it'll return the <code>SessionID</code> for subsequent API calls. </p>
<p>Otherwise, the client needs to continue with the <code>Logon</code> function (see the next part) using the returned <code>LoginID</code>.</p>
<p>To call the function, use the name <code>InitialiseWithID</code> with the following arguments:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Name</td><td>In/out</td><td>Type</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>address</td><td>In</td><td>String</td><td>provided integration server IP</td></tr>
<tr>
<td>AccountID</td><td>In</td><td>String</td><td>provided unique GUID string</td></tr>
<tr>
<td>LoginID</td><td>Out</td><td>String</td><td>GUID string used for Logon API call</td></tr>
<tr>
<td>Error</td><td>Out</td><td>String</td><td>Error description</td></tr>
<tr>
<td>Outcome</td><td>Out</td><td>Integer</td><td>-1 = Refer to error<br>1 = Successful initialise awaiting logon<br>2 = Unable to connect to server due to absent server, or incorrect details<br>3 = Unmatched AccountID<br>4 = Autologon successful</td></tr>
<tr>
<td>SessionID</td><td>Out</td><td>String</td><td>GUID used for subsequent interactions (if auto log in successful)</td></tr>
</tbody>
</table>
</div><h3 id="heading-logon-method">Logon Method</h3>
<p>This method determines the authority of the user. The username here is the ID used to log in to the system. The password is the API password set for that username. </p>
<p>In the success scenario, the call returns a <code>SessionID</code> string (GUID) that must be passed into other subsequent calls to authenticate them.</p>
<p>To call the function, use the name <code>Logon</code> with the following arguments:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Name</td><td>In/out</td><td>Type</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>LoginID</td><td>In</td><td>String</td><td>The login id returned by the initialization method Initialise with ID</td></tr>
<tr>
<td>username</td><td>In</td><td>String</td><td>provided API username</td></tr>
<tr>
<td>password</td><td>In</td><td>String</td><td>provided API password</td></tr>
<tr>
<td>SessionID</td><td>Out</td><td>String</td><td>GUID used for subsequent interactions (if logon successful)</td></tr>
<tr>
<td>Error</td><td>Out</td><td>String</td><td>Error description</td></tr>
<tr>
<td>Outcome</td><td>Out</td><td>Integer</td><td>-1 = Technical error<br>1 = Successful<br>2 = Expired<br>3 = Unsuccessful<br>4 = Invalid login ID or login ID does not have access to this product</td></tr>
</tbody>
</table>
</div><h3 id="heading-getmatchedusers-method">getMatchedUsers Method</h3>
<p>This call lets you find user data records that match specific criteria. The search term can only refer to one field at a time such as last name, first name, or date of birth. </p>
<p>A successful call returns an XML string with the data in it.</p>
<p>To call the function, use the name <code>getMatchedUsers</code> with the following arguments:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Name</td><td>In/out</td><td>Type</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>SessionID</td><td>In</td><td>String</td><td>The session id returned by the logon  method</td></tr>
<tr>
<td>MatchTerm</td><td>In</td><td>String</td><td>Search term</td></tr>
<tr>
<td>MatchedList</td><td>Out</td><td>String</td><td>XML conforming to provided corresponding XSD scheme</td></tr>
<tr>
<td>SessionID</td><td>Out</td><td>String</td><td>GUID used for subsequent interactions (if logon successful)</td></tr>
<tr>
<td>Error</td><td>Out</td><td>String</td><td>Error description</td></tr>
<tr>
<td>Outcome</td><td>Out</td><td>Integer</td><td>-1 = Technical error<br>1 =  Users found<br>2 = Access denied<br>3 = No users</td></tr>
</tbody>
</table>
</div><h2 id="heading-dll-library-application-flow">DLL Library Application Flow</h2>
<p>To make it easier to grasp what we want to implement, I decided to create a simple flow diagram. </p>
<p>It describes a step-by-step scenario of how a web client can interact with our server-based application using its API. It encapsulates interaction with the DLL Library and allows us to get hypothetical users with the provided match term (search criteria):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/JACOB_DLL_FLOW-5.png" alt="Image" width="600" height="400" loading="lazy">
<em>Application Flow Diagram</em></p>
<h2 id="heading-registering-com">Registering COM</h2>
<p>Now let's learn how we can access the DLL library. To be able to interact with a 3rd party COM interface, it <a target="_blank" href="https://docs.microsoft.com/en-us/windows/win32/com/registering-com-applications">needs to be added to the registry</a>. </p>
<p>Here's what the docs say:</p>
<blockquote>
<p>The registry is a system database that contains information about the configuration of system hardware and software as well as about users of the system. Any Windows-based program can add information to the registry and read information back from the registry. Clients search the registry for interesting components to use.  </p>
<p>The registry maintains information about all the COM objects installed in the system. Whenever an application creates an instance of a COM component, the registry is consulted to resolve either the CLSID or ProgID of the component into the pathname of the server DLL or EXE that contains it.  </p>
<p>After determining the component's server, Windows either loads the server into the process space of the client application (in-process components) or starts the server in its own process space (local and remote servers).  </p>
<p>The server creates an instance of the component and returns to the client a reference to one of the component's interfaces.</p>
</blockquote>
<p>To learn how to do that, the official Microsoft documentation <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/framework/interop/registering-assemblies-with-com">says</a>:</p>
<blockquote>
<p>You can run a command-line tool called the <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/framework/tools/regasm-exe-assembly-registration-tool">Assembly Registration Tool (Regasm.exe)</a> to register or unregister an assembly for use with COM.  </p>
<p>Regasm.exe adds information about the class to the system registry so COM clients can use the .NET Framework class transparently.  </p>
<p>The <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.registrationservices">RegistrationServices</a> class provides the equivalent functionality. A managed component must be registered in the Windows registry before it can be activated from a COM client</p>
</blockquote>
<p>Make sure that your host machine has installed the required <code>.NET Framework</code> components. After that, you can execute the following CLI command:</p>
<pre><code class="lang-shell">C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe {PATH_TO_YOUR_DLL_FILE} /codebase
</code></pre>
<p>A message will display indicating whether the file was successfully registered. Now we're ready for the next step.</p>
<h2 id="heading-defining-the-backbone-of-the-application">Defining the Backbone of the Application</h2>
<h3 id="heading-dllapiservice">DllApiService</h3>
<p>First of all, let's define the interface that describes our DLL library as it is:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">DllApiService</span> </span>{

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@param</span> accountId identifier for which we trigger initialisation
     * <span class="hljs-doctag">@return</span> Tuple3 from values of Outcome, SessionID/LoginID, error
     * where by the first argument you can understand what is the result of the API call
     */</span>
    Mono&lt;Tuple3&lt;Integer, String, String&gt;&gt; initialiseWithID(String accountId);

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@param</span> loginId  is retrieved before using {<span class="hljs-doctag">@link</span> DllApiService#initialiseWithID(String)} call
     * <span class="hljs-doctag">@param</span> username
     * <span class="hljs-doctag">@param</span> password
     * <span class="hljs-doctag">@return</span> Tuple3 from values of Outcome, SessionID, Error
     * where by the first argument you can understand what is the result of the API call
     */</span>
    Mono&lt;Tuple3&lt;Integer, String, String&gt;&gt; logon(String loginId, String username, String password);

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@param</span> sessionId is retrieved before using either
     *                  {<span class="hljs-doctag">@link</span> DllApiService#initialiseWithID(String)} or
     *                  {<span class="hljs-doctag">@link</span> DllApiService#logon(String, String, String)} calls
     * <span class="hljs-doctag">@param</span> matchTerm
     * <span class="hljs-doctag">@return</span> Tuple3 from values of Outcome, MatchedList, Error
     * where by the first argument you can understand what is the result of the API call
     */</span>
    Mono&lt;Tuple3&lt;Integer, String, String&gt;&gt; getMatchedUsers(String sessionId, String matchTerm);

    <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">COM_API_Method</span> </span>{
        InitialiseWithID, Logon, getMatchedUsers
    }
}
</code></pre>
<p>As you might have noticed, all the methods map with the definition of the COM Interface described above, except for the <code>initialiseWithID</code> function.</p>
<p>I decided to omit the <code>address</code> variable in the signature (the IP of the integration server) and inject it as an environment variable which we will be implementing.</p>
<h3 id="heading-sessionidservice-explained">SessionIDService Explained</h3>
<p>To be able to retrieve any data using the library, first we need to get the <code>SessionID</code>. </p>
<p>According to the flow diagram above, this involves calling the <code>initialiseWithID</code> method first. After that, depending on the result, we will get either the SessionID or <code>LoginID</code> to use in subsequent <code>Logon</code> calls. </p>
<p>So basically this is a two-step process behind the scenes. Now, let's create the interface, and after that, the implementation:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">SessionIDService</span> </span>{

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@param</span> accountId identifier for which we retrieve SessionID
     * <span class="hljs-doctag">@param</span> username
     * <span class="hljs-doctag">@param</span> password
     * <span class="hljs-doctag">@return</span> Tuple3 containing the following values:
     * result ( Boolean), sessionId (String) and status (HTTP Status depending on the result)
     */</span>
    Mono&lt;Tuple3&lt;Boolean, String, HttpStatus&gt;&gt; getSessionId(String accountId, String username, String password);
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-meta">@Service</span>
<span class="hljs-meta">@RequiredArgsConstructor</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SessionIDServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">SessionIDService</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> DllApiService dll;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-keyword">public</span> Mono&lt;Tuple3&lt;Boolean, String, HttpStatus&gt;&gt; getSessionId(String accountId, String username, String password) {
        <span class="hljs-keyword">return</span> dll.initialiseWithID(accountId)
                  .flatMap(t4 -&gt; {
                      <span class="hljs-keyword">switch</span> (t4.getT1()) {
                          <span class="hljs-keyword">case</span> -<span class="hljs-number">1</span>:
                              <span class="hljs-keyword">return</span> just(of(<span class="hljs-keyword">false</span>, t4.getT3(), SERVICE_UNAVAILABLE));

                          <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>: {

                              <span class="hljs-keyword">return</span> dll.logon(t4.getT2(), username, password)
                                        .map(t3 -&gt; {
                                            <span class="hljs-keyword">switch</span> (t3.getT1()) {
                                                <span class="hljs-keyword">case</span> -<span class="hljs-number">1</span>:
                                                    <span class="hljs-keyword">return</span> of(<span class="hljs-keyword">false</span>, t3.getT3(), SERVICE_UNAVAILABLE);
                                                <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>:
                                                    <span class="hljs-keyword">return</span> of(<span class="hljs-keyword">true</span>, t3.getT2(), OK);
                                                <span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:
                                                <span class="hljs-keyword">case</span> <span class="hljs-number">4</span>:
                                                    <span class="hljs-keyword">return</span> of(<span class="hljs-keyword">false</span>, t3.getT3(), FORBIDDEN);
                                                <span class="hljs-keyword">default</span>:
                                                    <span class="hljs-keyword">return</span> of(<span class="hljs-keyword">false</span>, t3.getT3(), BAD_REQUEST);

                                            }
                                        });

                          }

                          <span class="hljs-keyword">case</span> <span class="hljs-number">4</span>:
                              <span class="hljs-keyword">return</span> just(of(<span class="hljs-keyword">true</span>, t4.getT2(), OK));

                          <span class="hljs-keyword">default</span>:
                              <span class="hljs-keyword">return</span> just(of(<span class="hljs-keyword">false</span>, t4.getT3(), BAD_REQUEST));
                      }
                  });

    }
}
</code></pre>
<h3 id="heading-api-facade">API Facade</h3>
<p>The next step is to design our web application API. It should represent and encapsulate our interaction with the COM Interface API:</p>
<pre><code class="lang-java"><span class="hljs-meta">@Configuration</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DllApiRouter</span> </span>{

    <span class="hljs-meta">@Bean</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> RouterFunction&lt;ServerResponse&gt; <span class="hljs-title">dllApiRoute</span><span class="hljs-params">(DllApiRouterHandler handler)</span> </span>{
        <span class="hljs-keyword">return</span> RouterFunctions.route(GET(<span class="hljs-string">"/api/sessions/{accountId}"</span>), handler::sessionId)
                              .andRoute(GET(<span class="hljs-string">"/api/users/{matchTerm}"</span>), handler::matchedUsers);
    }
}
</code></pre>
<p>Besides the <code>Router</code> class, let's define an implementation of its handler with logic for retrieving the SessionID and the user records data. </p>
<p>For the second scenario, to be able to make a DLL <code>getMatchedUsers</code> API call according to the design, let's use the mandatory header <code>X-SESSION-ID</code>:</p>
<pre><code class="lang-java"><span class="hljs-meta">@Slf4j</span>
<span class="hljs-meta">@Component</span>
<span class="hljs-meta">@RequiredArgsConstructor</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DllApiRouterHandler</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String SESSION_ID_HDR = <span class="hljs-string">"X-SESSION-ID"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> DllApiService service;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> AccountRepo accountRepo;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> SessionIDService sessionService;

    <span class="hljs-function"><span class="hljs-keyword">public</span> Mono&lt;ServerResponse&gt; <span class="hljs-title">sessionId</span><span class="hljs-params">(ServerRequest request)</span> </span>{
        <span class="hljs-keyword">final</span> String accountId = request.pathVariable(<span class="hljs-string">"accountId"</span>);

        <span class="hljs-keyword">return</span> accountRepo.findById(accountId)
                          .flatMap(acc -&gt; sessionService.getSessionId(accountId, acc.getApiUsername(), acc.getApiPassword()))
                          .doOnEach(logNext(t3 -&gt; {
                              <span class="hljs-keyword">if</span> (t3.getT1()) {
                                  log.info(format(<span class="hljs-string">"SessionId to return %s"</span>, t3.getT2()));
                              } <span class="hljs-keyword">else</span> {
                                  log.warn(format(<span class="hljs-string">"Session Id could not be retrieved. Cause: %s"</span>, t3.getT2()));
                              }
                          }))
                          .flatMap(t3 -&gt; status(t3.getT3()).contentType(APPLICATION_JSON)
                                                           .bodyValue(t3.getT1() ? t3.getT2() : Response.error(t3.getT2())))

                          .switchIfEmpty(Mono.just(<span class="hljs-string">"Account could not be found with provided ID "</span> + accountId)
                                             .doOnEach(logNext(log::info))
                                             .flatMap(msg -&gt; badRequest().bodyValue(Response.error(msg))));
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> Mono&lt;ServerResponse&gt; <span class="hljs-title">matchedUsers</span><span class="hljs-params">(ServerRequest request)</span> </span>{

        <span class="hljs-keyword">return</span> sessionIdHeader(request).map(sId -&gt; Tuples.of(sId, request.queryParam(<span class="hljs-string">"matchTerm"</span>)
                                                                         .orElseThrow(() -&gt; <span class="hljs-keyword">new</span> IllegalArgumentException(
                                                                                 <span class="hljs-string">"matchTerm query param should be specified"</span>))))
                                       .flatMap(t2 -&gt; service.getMatchedUsers(t2.getT1(), t2.getT2()))
                                       .flatMap(<span class="hljs-keyword">this</span>::handleT3)
                                       .onErrorResume(IllegalArgumentException.class, <span class="hljs-keyword">this</span>::handleIllegalArgumentException);

    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> Mono&lt;String&gt; <span class="hljs-title">sessionIdHeader</span><span class="hljs-params">(ServerRequest request)</span> </span>{
        <span class="hljs-keyword">return</span> Mono.justOrEmpty(request.headers()
                                       .header(SESSION_ID_HDR)
                                       .stream()
                                       .findFirst()
                                       .orElseThrow(() -&gt; <span class="hljs-keyword">new</span> IllegalArgumentException(SESSION_ID_HDR + <span class="hljs-string">" header is mandatory"</span>)));
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> Mono&lt;ServerResponse&gt; <span class="hljs-title">handleT3</span><span class="hljs-params">(Tuple3&lt;Integer, String, String&gt; t3)</span> </span>{
        <span class="hljs-keyword">switch</span> (t3.getT1()) {
            <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>:
                <span class="hljs-keyword">return</span> ok().contentType(APPLICATION_JSON)
                           .bodyValue(t3.getT2());
            <span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:
                <span class="hljs-keyword">return</span> status(FORBIDDEN).contentType(APPLICATION_JSON)
                                        .bodyValue(Response.error(t3.getT3()));
            <span class="hljs-keyword">default</span>:
                <span class="hljs-keyword">return</span> badRequest().contentType(APPLICATION_JSON)
                                   .bodyValue(Response.error(t3.getT3()));
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> Mono&lt;ServerResponse&gt; <span class="hljs-title">handleIllegalArgumentException</span><span class="hljs-params">(IllegalArgumentException e)</span> </span>{
        <span class="hljs-keyword">return</span> Mono.just(Response.error(e.getMessage()))
                   .doOnEach(logNext(res -&gt; log.info(String.join(<span class="hljs-string">","</span>, res.getErrors()))))
                   .flatMap(res -&gt; badRequest().contentType(MediaType.APPLICATION_JSON)
                                               .bodyValue(res));
    }

    <span class="hljs-meta">@Getter</span>
    <span class="hljs-meta">@Setter</span>
    <span class="hljs-meta">@NoArgsConstructor</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Response</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Serializable</span> </span>{

        <span class="hljs-keyword">private</span> String message;

        <span class="hljs-keyword">private</span> Set&lt;String&gt; errors;

        <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">Response</span><span class="hljs-params">(Set&lt;String&gt; errors)</span> </span>{
            <span class="hljs-keyword">this</span>.errors = errors;
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Response <span class="hljs-title">error</span><span class="hljs-params">(String error)</span> </span>{
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Response(singleton(error));
        }
    }
}
</code></pre>
<h3 id="heading-account-entity">Account Entity</h3>
<p>As you might have noticed, we've imported <code>AccountRepo</code> in the router's handler to find the entity in a database by the provided <code>accountId</code>. This lets us get the corresponding API user credentials and use all three in the DLL <code>Logon</code> API call. </p>
<p>To get a clearer picture, let's define the managed <code>Account</code> entity as well:</p>
<pre><code class="lang-java"><span class="hljs-meta">@TypeAlias("Account")</span>
<span class="hljs-meta">@Document(collection = "accounts")</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Account</span> </span>{

    <span class="hljs-meta">@Version</span>
    <span class="hljs-keyword">private</span> Long version;

    <span class="hljs-comment">/**
     * unique account ID for API, provided by supplier
     * defines restriction for data domain visibility
     * i.e. data from one account is not visible for another
     */</span>
    <span class="hljs-meta">@Id</span>
    <span class="hljs-keyword">private</span> String accountId;

    <span class="hljs-comment">/**
     * COM API username, provided by supplier
     */</span>
    <span class="hljs-keyword">private</span> String apiUsername;

    <span class="hljs-comment">/**
     * COM API password, provided by supplier
     */</span>
    <span class="hljs-keyword">private</span> String apiPassword;


    <span class="hljs-meta">@CreatedDate</span>
    <span class="hljs-keyword">private</span> Date createdAt;

    <span class="hljs-meta">@LastModifiedDate</span>
    <span class="hljs-keyword">private</span> Date updatedOn;
}
</code></pre>
<h2 id="heading-the-jacob-library-setup">The JACOB Library Setup</h2>
<p>All parts of our application are ready now except the core – the configuration and use of the JACOB library. Let's start with setting up the library.</p>
<p>The library is distributed via <a target="_blank" href="https://sourceforge.net/projects/jacob-project/">sourceforge.net</a>. I did not find it available anywhere on either the Central Maven Repo or any other repositories online. So I decided to import it manually into our project as a local package. </p>
<p>To do that, I downloaded it and put it in the root folder under <code>/libs/jacob-1.19</code>. </p>
<p>After that, put the following <a target="_blank" href="https://maven.apache.org/plugins/maven-install-plugin/">maven-install-plugin</a> configuration into <code>pom.xml</code>. This will add the library to the local repository during Maven's <code>install</code> build phase:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>maven-install-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>install-jacob<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">phase</span>&gt;</span>validate<span class="hljs-tag">&lt;/<span class="hljs-name">phase</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">file</span>&gt;</span>${basedir}/libs/jacob-1.19/jacob.jar<span class="hljs-tag">&lt;/<span class="hljs-name">file</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">repositoryLayout</span>&gt;</span>default<span class="hljs-tag">&lt;/<span class="hljs-name">repositoryLayout</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>net.sf.jacob-project<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>jacob<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.19<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">packaging</span>&gt;</span>jar<span class="hljs-tag">&lt;/<span class="hljs-name">packaging</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">generatePom</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-name">generatePom</span>&gt;</span>
         <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">goals</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>install-file<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span>
         <span class="hljs-tag">&lt;/<span class="hljs-name">goals</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span>
</code></pre>
<p>That will let you easily add the dependency as usual:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>net.sf.jacob-project<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>jacob<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.19<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<p>The library import is finished. Now let's get it ready to use it.</p>
<p>To interact with the COM component, JACOB provides a wrapper called an <code>ActiveXComponent</code> class (as I mentioned before). </p>
<p>It has a method called <code>invoke(String function, Variant... args)</code> that lets us make exactly what we want. </p>
<p>Generally speaking, our library is set up to create the <code>ActiveXComponent</code> bean so we can use it anywhere we want in the app (and we want it in the implementation of <code>DllApiService</code>). </p>
<p>So let's define a separate Spring <code>@Configuration</code> with all the essential preparations:</p>
<pre><code class="lang-java"><span class="hljs-meta">@Slf4j</span>
<span class="hljs-meta">@Configuration</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JacobCOMConfiguration</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String COM_INTERFACE_NAME = <span class="hljs-string">"NAME_OF_COM_INTERFACE_AS_IN_REGISTRY"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String JACOB_LIB_PATH = System.getProperty(<span class="hljs-string">"user.dir"</span>) + <span class="hljs-string">"\\libs\\jacob-1.19"</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String LIB_FILE = System.getProperty(<span class="hljs-string">"os.arch"</span>)
                                                 .equals(<span class="hljs-string">"amd64"</span>) ? <span class="hljs-string">"\\jacob-1.19-x64.dll"</span> : <span class="hljs-string">"\\jacob-1.19-x86.dll"</span>;

    <span class="hljs-keyword">private</span> File temporaryDll;

    <span class="hljs-keyword">static</span> {
        log.info(<span class="hljs-string">"JACOB lib path: {}"</span>, JACOB_LIB_PATH);
        log.info(<span class="hljs-string">"JACOB file lib path: {}"</span>, JACOB_LIB_PATH + LIB_FILE);
        System.setProperty(<span class="hljs-string">"java.library.path"</span>, JACOB_LIB_PATH);
        System.setProperty(<span class="hljs-string">"com.jacob.debug"</span>, <span class="hljs-string">"true"</span>);
    }

    <span class="hljs-meta">@PostConstruct</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException </span>{
        InputStream inputStream = <span class="hljs-keyword">new</span> FileInputStream(JACOB_LIB_PATH + LIB_FILE);

        temporaryDll = File.createTempFile(<span class="hljs-string">"jacob"</span>, <span class="hljs-string">".dll"</span>);
        FileOutputStream outputStream = <span class="hljs-keyword">new</span> FileOutputStream(temporaryDll);
        <span class="hljs-keyword">byte</span>[] array = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">8192</span>];
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = inputStream.read(array); i != -<span class="hljs-number">1</span>; i = inputStream.read(array)) {
            outputStream.write(array, <span class="hljs-number">0</span>, i);
        }
        outputStream.close();

        System.setProperty(LibraryLoader.JACOB_DLL_PATH, temporaryDll.getAbsolutePath());
        LibraryLoader.loadJacobLibrary();
        log.info(<span class="hljs-string">"JACOB library is loaded and ready to use"</span>);
    }

    <span class="hljs-meta">@Bean</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> ActiveXComponent <span class="hljs-title">dllAPI</span><span class="hljs-params">()</span> </span>{
        ActiveXComponent activeXComponent = <span class="hljs-keyword">new</span> ActiveXComponent(COM_INTERFACE_NAME);
        log.info(<span class="hljs-string">"API COM interface {} wrapped into ActiveXComponent is created and ready to use"</span>, COM_INTERFACE_NAME);
        <span class="hljs-keyword">return</span> activeXComponent;
    }

    <span class="hljs-meta">@PreDestroy</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">clean</span><span class="hljs-params">()</span> </span>{
        temporaryDll.deleteOnExit();
        log.info(<span class="hljs-string">"Temporary DLL API library is cleaned on exit"</span>);
    }
}
</code></pre>
<p>It's worth mentioning that, besides defining the bean, we initialize the library components based on the host machine's ISA (instruction set architecture).</p>
<p>Also, we follow some common recommendations to make a copy of the corresponding library's file. This avoids any potential corruption of the original file during runtime. We also need to cleanup all allocated resources when the applications terminates.</p>
<p>Now the library is set up and ready to use. Finally, we can implement our last main component that helps us interact with the DLL API:  <code>DllApiServiceImpl</code>.</p>
<h2 id="heading-how-to-implement-a-dll-library-api-service">How to Implement a DLL Library API Service</h2>
<p>As all COM API calls are going to be cooked using a common approach, let's implement <code>InitialiseWithID</code> first. After that, all other methods can be implemented easily in a similar way.</p>
<p>As I mentioned before, to interact with the COM interface, JACOB provides us with the <code>ActiveXComponent</code> class that has the <code>invoke(String function, Variant... args)</code> method. </p>
<p>If you want to know more about the <code>Variant</code> class, the JACOB documentation says the following (you can find it in the <a target="_blank" href="https://sourceforge.net/projects/jacob-project/">archive</a> or under <code>/libs/jacob-1.19</code> in the <a target="_blank" href="https://github.com/povisenko/jacob-within-spring-boot-2">project</a>):</p>
<blockquote>
<p>The multi-format data type used for all call backs and most communications between Java and COM. It provides a single class that can handle all data types.</p>
</blockquote>
<p>This means that all arguments defined in the <code>InitialiseWithID</code> signature should be wrapped with <code>new Variant(java.lang.Object in)</code> and passed to the <code>invoke</code> method. Use the same order as specified in the interface description at the beginning of this article.</p>
<p>The only other important thing we haven't touched on yet is how to distinguish <code>in</code> and <code>out</code> type arguments. </p>
<p>For that purpose, <code>Variant</code> provides a constructor that accepts the data object and information about whether this is by reference or not. This means that after <code>invoke</code> is called, all variants that were initialized as references can be accessed after the call. So we can extract the results from <code>out</code> arguments. </p>
<p>To do that, just pass an extra boolean variable to the constructor as the second parameter: <code>new Variant(java.lang.Object pValueObject, boolean fByRef)</code>. </p>
<p>Initializing the <code>Variant</code> object as reference puts an additional requirement on the client to decide when to release the value (so it can be scrapped by the garbage collector). </p>
<p>For that purpose, you have the <code>safeRelease()</code> method that is supposed to be called when the value is taken from the corresponding <code>Variant</code> object.  </p>
<p>Putting all the pieces together gives us the following service's implementation:</p>
<pre><code class="lang-java"><span class="hljs-meta">@RequiredArgsConstructor</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DllApiServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">DllApiService</span> </span>{

    <span class="hljs-meta">@Value("${DLL_API_ADDRESS}")</span>
    <span class="hljs-keyword">private</span> String address;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ActiveXComponent dll;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-keyword">public</span> Mono&lt;Tuple3&lt;Integer, String, String&gt;&gt; initialiseWithID(<span class="hljs-keyword">final</span> String accountId) {

        <span class="hljs-keyword">return</span> Mono.just(format(<span class="hljs-string">"Calling %s(%s, %s, %s, %s, %s, %s)"</span>,<span class="hljs-comment">//</span>
                                InitialiseWithID, address, accountId, <span class="hljs-string">"loginId/out"</span>, <span class="hljs-string">"error/out"</span>, <span class="hljs-string">"outcome/out"</span>, <span class="hljs-string">"sessionId/out"</span>))
                   .doOnEach(logNext(log::info))
                   <span class="hljs-comment">//invoke COM interface method and extract the result mapping it onto corresponding *Out inner class</span>
                   .map(msg -&gt; invoke(InitialiseWithID, vars -&gt; InitialiseWithIDOut.builder()
                                                                                   .loginId(vars[<span class="hljs-number">3</span>].toString())
                                                                                   .error(vars[<span class="hljs-number">4</span>].toString())
                                                                                   .outcome(valueOf(vars[<span class="hljs-number">5</span>].toString()))
                                                                                   .sessionId(vars[<span class="hljs-number">6</span>].toString())
                                                                                   .build(), <span class="hljs-comment">//</span>
                                      <span class="hljs-keyword">new</span> Variant(address), <span class="hljs-keyword">new</span> Variant(accountId), initRef(), initRef(), initRef(), initRef()))
                   <span class="hljs-comment">//Handle the response according to the documentation</span>
                   .map(out -&gt; {

                       <span class="hljs-keyword">final</span> String errorVal;

                       <span class="hljs-keyword">switch</span> (out.outcome) {
                           <span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:
                               errorVal = <span class="hljs-string">"InitialiseWithID method call failed. DLL API request outcome (response code from server via DLL) = 2 "</span> +<span class="hljs-comment">//</span>
                                       <span class="hljs-string">"(Unable to connect to server due to absent server, or incorrect details)"</span>;
                               <span class="hljs-keyword">break</span>;
                           <span class="hljs-keyword">case</span> <span class="hljs-number">3</span>:
                               errorVal = <span class="hljs-string">"InitialiseWithID method call failed. DLL API request outcome (response code from server via DLLe) = 3 (Unmatched AccountID)"</span>;
                               <span class="hljs-keyword">break</span>;
                           <span class="hljs-keyword">default</span>:
                               errorVal = handleOutcome(out.outcome, out.error, InitialiseWithID);
                       }

                       <span class="hljs-keyword">return</span> of(out, errorVal);
                   })
                   .doOnEach(logNext(t2 -&gt; {
                       InitialiseWithIDOut out = t2.getT1();
                       log.info(<span class="hljs-string">"{} API call result:\noutcome: {}\nsessionId: {}\nerror: {}\nloginId: {}"</span>,<span class="hljs-comment">//</span>
                                InitialiseWithID, out.outcome, out.sessionId, t2.getT2(), out.loginId);
                   }))
                   .map(t2 -&gt; {
                       InitialiseWithIDOut out = t2.getT1();
                       <span class="hljs-comment">//out.outcome == 4 auto-login successful, SessionID is retrieved</span>
                       <span class="hljs-keyword">return</span> of(out.outcome, out.outcome == <span class="hljs-number">4</span> ? out.sessionId : out.loginId, t2.getT2());
                   });
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Variant <span class="hljs-title">initRef</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Variant(<span class="hljs-string">""</span>, <span class="hljs-keyword">true</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">handleOutcome</span><span class="hljs-params">(Integer outcome, String error, COM_API_Method method)</span> </span>{
        <span class="hljs-keyword">switch</span> (outcome) {
            <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>:
                <span class="hljs-keyword">return</span> <span class="hljs-string">"no error"</span>;
            <span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:
                <span class="hljs-keyword">return</span> format(<span class="hljs-string">"%s method call failed. DLL API request outcome (response code from server via DLL) = 2 (Access denied)"</span>, method);
            <span class="hljs-keyword">default</span>:
                <span class="hljs-keyword">return</span> format(<span class="hljs-string">"%s method call failed. DLL API request outcome (response code from server via DLL) = %s (server technical error). "</span> + <span class="hljs-comment">//</span>
                                      <span class="hljs-string">"DLL API is temporary unavailable (server behind is down), %s"</span>, method, outcome, error);
        }

    }

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@param</span> method     to be called in COM interface
     * <span class="hljs-doctag">@param</span> returnFunc maps Variants (references) array onto result object that is to be returned by the method
     * <span class="hljs-doctag">@param</span> vars       arguments required for calling COM interface method
     * <span class="hljs-doctag">@param</span> &lt;T&gt;        type of the result object that is to be returned by the method
     * <span class="hljs-doctag">@return</span> result of the COM API method invocation in defined format
     */</span>
    <span class="hljs-keyword">private</span> &lt;T extends Out&gt; <span class="hljs-function">T <span class="hljs-title">invoke</span><span class="hljs-params">(COM_API_Method method, Function&lt;Variant[], T&gt; returnFunc, Variant... vars)</span> </span>{
        dll.invoke(method.name(), vars);
        T res = returnFunc.apply(vars);
        asList(vars).forEach(Variant::safeRelease);
        <span class="hljs-keyword">return</span> res;
    }

    <span class="hljs-meta">@SuperBuilder</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Out</span> </span>{
        <span class="hljs-keyword">final</span> Integer outcome;
        <span class="hljs-keyword">final</span> String error;
    }

    <span class="hljs-meta">@SuperBuilder</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InitialiseWithIDOut</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Out</span> </span>{
        <span class="hljs-keyword">final</span> String loginId;
        <span class="hljs-keyword">final</span> String sessionId;
}
</code></pre>
<p>Two other methods, <code>Logon</code> and <code>getMatchedUsers</code>, are implemented accordingly. You can refer to my <a target="_blank" href="https://github.com/povisenko/jacob-within-spring-boot-2/blob/master/src/main/java/me/povisenko/jacob_within_spring_boot_2/services/impl/DllApiServiceImpl.java">GitHub</a> repo for a complete version of the service if you want to check it out.</p>
<h2 id="heading-congratulations-youve-learned-a-few-things">Congratulations – You've Learned a Few Things</h2>
<p>We've gone through a step by step scenario that showed us how a hypothetical COM API could be distributed and called in Java. </p>
<p>We also learned how the JACOB library can be configured and effectively used to interact with a DDL library within your Spring Boot 2 application.</p>
<p>A small improvement would be to cache the retrieved SessionID which could improve the general flow. But that's a bit outside the scope of this article. </p>
<p>If you want to investigate further, you can find that on GitHub where it's implemented using Spring's caching mechanism.</p>
<p>Hope you enjoyed going through everything with me and found this tutorial helpful!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Storybook and How Can I Use It to Create a Component Library in React? ]]>
                </title>
                <description>
                    <![CDATA[ Frameworks like React, Vue, and Angular all help developers create modular systems using components, but that doesn't usually include a good way to see them all from a higher point of view.  So how can we use Storybook to build libraries and design s... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-storybook-and-how-can-i-use-it-to-create-a-component-libary-in-react/</link>
                <guid isPermaLink="false">66b8e39c68c5b9f37d1d1af1</guid>
                
                    <category>
                        <![CDATA[ components ]]>
                    </category>
                
                    <category>
                        <![CDATA[ create-react-app ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Storybook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tools ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 09 Jun 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/storybook.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Frameworks like React, Vue, and Angular all help developers create modular systems using components, but that doesn't usually include a good way to see them all from a higher point of view. </p>
<p>So how can we use Storybook to build libraries and design systems that self-document as we build them?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-storybook">What is Storybook?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-bootstrapping-an-app">Step 0: Bootstrapping an app</a></li>
<li><a class="post-section-overview" href="#heading-step-1-installing-storybook">Step 1: Installing Storybook</a></li>
<li><a class="post-section-overview" href="#heading-step-2-creating-a-new-button">Step 2: Creating a new button</a></li>
<li><a class="post-section-overview" href="#heading-step-3-using-our-new-button-component">Step 3: Using our new Button component</a></li>
<li><a class="post-section-overview" href="#heading-repeat-creating-a-new-header-component">Repeat: Creating a new Header component</a></li>
<li><a class="post-section-overview" href="#heading-more-storybook-features">More Storybook features</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/VApXDsYO5Gg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-is-storybook">What is Storybook?</h2>
<p><a target="_blank" href="https://storybook.js.org/">Storybook</a> is a JavaScript tool that allows developers to create organized UI systems making both the building process and documentation more efficient and easier to use.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/loneley-planet-storybook-example.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://lonelyplanet.github.io/backpack-ui/?path=/story/cards--card-basic">Lonely Planet's Backpack UI</a></em></p>
<p>Once you build out a component, Storybook lets you create a "story" file where you can then import your component and create various use case examples in an iFramed sandbox using that component.</p>
<p>This provides an organized and focused environment to build new components and work on existing ones.</p>
<h2 id="heading-what-are-we-going-to-build">What are we going to build?</h2>
<p>We're going to bootstrap a new <a target="_blank" href="https://reactjs.org/">React JS</a> app using <a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">Create React App</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/storybook-component-example.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Inside that app, we're going to install Storybook and create a few new components that will help us learn how to create new components that we can work on in a story and then use it in a React app.</p>
<h2 id="heading-step-0-bootstrapping-an-app">Step 0: Bootstrapping an app</h2>
<p>To get started, we're going to start from scratch with <a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">Create React App</a>. This will help us focus on getting productive in Storybook rather than walking through integrating it into a current app.</p>
<p>That said, if you're already working with an app created using Create React App that's not ejected, you should be able to still follow on with Part 1 and beyond just the same!</p>
<p>So let's get started by navigating to where we want to create our new app and run the Create React App command:</p>
<pre><code class="lang-shell">npx create-react-app my-storybook
</code></pre>
<p><em>Note: feel free to replace <code>my-storybook</code> with the directory name of your choice.</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/create-new-react-app.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Bootstrapping with Create React App</em></p>
<p>Once that's finished running, you can navigate to the directory:</p>
<pre><code class="lang-shell">cd my-storybook
</code></pre>
<p>And we're ready to go!</p>
<h2 id="heading-step-1-installing-storybook">Step 1: Installing Storybook</h2>
<p>Storybook luckily makes it really easy to get started with a standard installation of React. Particularly with Create React App, Storybook automatically detects that we're using an app created using CRA and installs the dependencies and scaffolds everything for us.</p>
<h3 id="heading-initializing-storybook">Initializing Storybook</h3>
<p>To get started installing Storybook, run:</p>
<pre><code class="lang-shell">npx -p @storybook/cli sb init
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/initializing-storybook.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Initializing Storybook in a React app</em></p>
<p>If you aren't using Create React App or it didn't work, you can check out their <a target="_blank" href="https://storybook.js.org/docs/guides/guide-react/">available guides in their docs</a>.</p>
<p>After that's finished, all of our Storybook dependencies should be installed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/storybook-finished-installing.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Finished installing Storybook</em></p>
<h3 id="heading-starting-up-storybook">Starting up Storybook</h3>
<p>So now we're ready to get moving! Finally, run:</p>
<pre><code class="lang-shell">yarn storybook
# or
npm run storybook
</code></pre>
<p>And once everything finishes loading, Storybook will open a new tab in your browser and you should now see a welcome message inside of your new Storybook dashboard!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/storybook-welcome-page.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Storybook welcome page</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-storybook/commit/3e994096384e31cb540150c9f14f41758ef3a746">Follow along with the commit!</a></p>
<h2 id="heading-step-2-creating-a-new-button">Step 2: Creating a new button</h2>
<p>If you took a second to poke around the dashboard, you might have noticed that it comes pre-loaded with a Button that's available as a demo.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/storybook-demo-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Storybook demo button</em></p>
<p>You should also notice if you click the button, you actually see an action print out inside of the Actions tab at the bottom. This shows the event that's captured from the button click.</p>
<p>It's simple, but this is great to get a nice feel about what to expect in storybook. The only issue is, this is meant purely for demonstration purposes, so let's build our own button to replace it.</p>
<h3 id="heading-creating-a-new-button-component">Creating a new Button component</h3>
<p>To get started, let's first create a few directories:</p>
<ul>
<li>Under <code>src</code>, create a new folder called <code>components</code></li>
<li>Under <code>components</code>, create a new folder called <code>Button</code></li>
</ul>
<p>Once you create those folders, create a new file called <code>index.js</code> inside of your <code>src/components/Button</code> folder and inside add:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Inside src/components/Button/index.js</span>

<span class="hljs-keyword">export</span> { <span class="hljs-keyword">default</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./Button'</span>;
</code></pre>
<p>This will import the next file we created called <code>Button.js</code> which will allow us to more easily import our files with <code>src/components/Button</code> instead of <code>/src/components/Button/Button</code>.</p>
<p>Next, let's create <code>Button.js</code> right next to our <code>index.js</code> file with the following content:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Inside src/components/Button/Button.js</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> Button = <span class="hljs-function">(<span class="hljs-params">{ children, ...rest }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"button"</span> {<span class="hljs-attr">...rest</span>}&gt;</span>
      { children }
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Button;
</code></pre>
<p>Here, we're creating a new component called Button that adds a class of <code>button</code> to the element and passes through the <code>children</code>. We're a additionally <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destructuring</a> the rest of the props into the <code>rest</code> variable and <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spreading</a> that value into the <code>&lt;button&gt;</code> element.</p>
<p>If you've followed along, your files should now look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/button-reaect-component.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Button component in React</em></p>
<h3 id="heading-using-our-new-button-component">Using our new Button component</h3>
<p>So now that we have our Button component, let's use it!</p>
<p>Open up the file <code>src/stories/1-Button.stories.js</code> and replace the line that's importing <code>Button</code> with:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/updating-button-storybook-story.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Updating the Button Storybook story</em></p>
<p>And once you hit save, you can open back up your browser tab with your Storybook dashboard, and you can now see a button that looks mostly similar, but it uses the browser's default styles for the <code>&lt;button&gt;</code> element. You'll even notice that if you click it, the event will still be logged under the Actions tab.</p>
<h3 id="heading-styling-our-button-component">Styling our Button component</h3>
<p>Finally, we probably don't want to use the browser default styles, so let's make it look nice.</p>
<p>In our <code>src/components/Button</code> directory, add a new file <code>Button.css</code> and add the following content:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Inside src/components/Button/Button.css */</span>

<span class="hljs-selector-class">.button</span> {
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">font-weight</span>: bold;
  <span class="hljs-attribute">background-color</span>: blueviolet;
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">padding</span>: .<span class="hljs-number">8em</span> <span class="hljs-number">1em</span>;
  <span class="hljs-attribute">border-radius</span>: .<span class="hljs-number">2rem</span>;
}
</code></pre>
<p>This applies a few styles to our <code>.button</code> class like adding a background color and changing the font color to white.</p>
<p>But if you open Storybook, you'll notice it didn't do anything. To use it, we need to import it into our component.</p>
<p>Inside <code>src/components/Button/Button.js</code> add the following at the top under the React import:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./Button.css'</span>;
</code></pre>
<p>And once you save that and open up your browser, you should now see our new button with our updated styles!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/new-button-storybook.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Button in Storybook</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-storybook/commit/e71e0e9e666adee0455b0b69118053c2f551ab68">Follow along with the commit!</a></p>
<h2 id="heading-step-3-using-our-new-button-component">Step 3: Using our new Button component</h2>
<p>The ultimate goal of our component is to use it right? So let's add it to our app.</p>
<h3 id="heading-switching-over-to-the-react-app">Switching over to the React app</h3>
<p>First we'll need to either start our React app in a new terminal tab or kill the Storybook process and start the React process there. To start the React app using Create React App, run:</p>
<pre><code class="lang-shell">yarn start
# or
npm run start
</code></pre>
<p>Once that loads, we should have our standard Create React App if you're following along with me:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/new-create-react-app.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Create React App</em></p>
<h3 id="heading-importing-and-using-the-new-button">Importing and using the new button</h3>
<p>Next, inside of <code>src/App.js</code>, let's import our new Button at the top of the page:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Button'</span>;
</code></pre>
<p>With Button imported, we can use it. Here, we can simply add it anywhere we want in the page. I'm going to replace the Learn React link with:</p>
<pre><code class="lang-jsx">&lt;p&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Button</span>&gt;</span>Hello, Storybook!<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span></span>
&lt;/p&gt;
</code></pre>
<p>And if we save and reload the page, we should now see our Button on the page!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/create-react-app-with-new-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Button in Create React App</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-storybook/commit/e6071aae5be281101d486c4cc7664bf6cacb4028">Follow along with the commit</a></p>
<h2 id="heading-repeat-creating-a-new-header-component">Repeat: Creating a new Header component</h2>
<p>The great thing about Storybook and React (or any of the supported frameworks) is that this process scales to as many components as you want.</p>
<p>So let's build another component!</p>
<h3 id="heading-creating-our-header-component">Creating our Header component</h3>
<p>Similar to our Button, let's start off by creating the set of directories and files that give us our component.</p>
<p>Since we already did this once, I'm going to provide the code without walking through what's going on.</p>
<p>Let's start off by spinning back up our Storybook server with:</p>
<pre><code>yarn storybook
# or 
npm run storybook
</code></pre><p>Create a <code>Header</code> directory inside the <code>src/components</code> directory.</p>
<p>Create an <code>index.js</code> file inside of <code>src/components/Header</code> with the following content:</p>
<pre><code class="lang-js"><span class="hljs-comment">// In src/components/Header/index.js</span>

<span class="hljs-keyword">export</span> { <span class="hljs-keyword">default</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./Header'</span>;
</code></pre>
<p>Create a <code>Header.js</code> file inside of <code>src/components/Header</code> with the following content:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// In src/components/Header/Header.js</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./Header.css'</span>;

<span class="hljs-keyword">const</span> Header = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"header"</span>&gt;</span>
      { children }
    <span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Header;
</code></pre>
<p>Create a <code>Header.css</code> file inside of <code>src/components/Header</code> with the following content:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* In src/components/Header/Header.css */</span>

<span class="hljs-selector-class">.header</span> {
  <span class="hljs-attribute">font-family</span>: sans-serif;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2.5em</span>;
  <span class="hljs-attribute">color</span>: blueviolet;
  <span class="hljs-attribute">border-bottom</span>: solid <span class="hljs-number">5px</span> aqua;
  <span class="hljs-attribute">padding-bottom</span>: .<span class="hljs-number">2em</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">5px</span> <span class="hljs-number">0</span> blueviolet;
}
</code></pre>
<p>Now if you notice, if you try to open up Storybook, again, nothing will happen. This time we need to create a new story file.</p>
<h3 id="heading-creating-a-new-story-file">Creating a new Story file</h3>
<p>Inside <code>src/stories</code>, add a new file called <code>2-Header.stories.js</code>:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Inside src/stories/2-Header.stories.js</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> Header <span class="hljs-keyword">from</span> <span class="hljs-string">'../components/Header'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">title</span>: <span class="hljs-string">'Header'</span>,
  <span class="hljs-attr">component</span>: Header,
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Text = <span class="hljs-function">() =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span>Hello Header<span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span></span>;
</code></pre>
<p>Here's a breakdown of our story file:</p>
<ul>
<li>First, we import our component – this is pretty standard any time we want to use it</li>
<li>The first thing we export is a <code>default</code> object. With Storybook, it expects the default export to be the configuration of our story, so here we provide it with a title and we pass in the component that we're using for this story</li>
<li>The second and last thing we export is the <code>Text</code> constant. With Storybook, any non-default export will be considered a variation that will get nested under the title that you provide in the default export</li>
</ul>
<p>And if you save this file and open up your Storybook dashboard in the browser, you should now see the new header!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/new-header-storybook-story.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Header component in Storybook</em></p>
<h3 id="heading-using-the-header-component">Using the Header component</h3>
<p>Using our component is just the same as our Button component, so inside of <code>src/App.js</code>, let's add our Header.</p>
<p>After starting your React server, first import our new Header:</p>
<pre><code class="lang-js"><span class="hljs-comment">// In src/App.js</span>

<span class="hljs-keyword">import</span> Header <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Header'</span>;
</code></pre>
<p>Then add it to the top of the page:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// In src/App.js</span>

&lt;Header&gt;My App&lt;/Header&gt;
</code></pre>
<p>And if you open the page, we'll see our new Header!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/create-react-app-with-header-and-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Create React App with new Header and Button components</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-storybook/commit/e1c59eccaf5f4146a2fe039dca8874609d615194">Follow along with the commit!</a></p>
<h2 id="heading-adding-more-components">Adding more components</h2>
<p>As you've noticed with our second Repeat step – adding a new component is pretty much the same process for any type of component we want to add. Once we have it in our library, we can develop it in a focused environment and then import it to our app to use.</p>
<p>You can now use this to manage your library of components and better maintain an entire system for your project!</p>
<h2 id="heading-more-storybook-features">More Storybook features</h2>
<p>Storybook doesn't stop with just adding components, it provides the ability to configure <a target="_blank" href="https://storybook.js.org/addons/">Addons</a> that enhance the core capabilities opening up a lot of possibilities.</p>
<p>Here are some of my favorites...</p>
<h3 id="heading-story-source">Story Source</h3>
<p>When building a component system, the hope is that people can easily use these components. But if you don't have documentation, someone would have to open up the file or try to find another use example.</p>
<p>Instead, <a target="_blank" href="https://github.com/storybookjs/storybook/tree/master/addons/storysource">Story Source</a> shows the code source of the story file you created allowing someone browsing your Storybook dashboard to get an example right along with the component output!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/storybook-source-demo.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Storybook Story Source demo</em></p>
<h3 id="heading-storyshots">Storyshots</h3>
<p>If you're a fan of automated testing, you might have heard of using <a target="_blank" href="https://jestjs.io/">Jest</a> or another tool for adding snapshot testing to your app.</p>
<p><a target="_blank" href="https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core">StoryShots</a> is a way to easily add Jest snapshot testing to your component system. It creates snapshots based off of the stories you create so you can make sure that your components aren't fundamentally changing (or breaking) during development.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/storybook-snapshot-example.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Snapshot example with StoryShots</em></p>
<h2 id="heading-whats-your-favorite-part-of-storybook">What's your favorite part of Storybook?</h2>
<p><a target="_blank" href="https://twitter.com/colbyfayock">Share with me on Twitter!</a></p>
<h2 id="heading-continue-the-conversation">Continue the conversation!</h2>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/colbyfayock/status/1270392710260719616"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Native – Touchables and Screen Dimensions ]]>
                </title>
                <description>
                    <![CDATA[ React Native makes the process of developing an application that works on both Android and iOS devices much easier than it once was. While before you had to work with at least two programming languages and vastly different APIs, React Native includes... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-native-touchables-and-screen-dimensions/</link>
                <guid isPermaLink="false">66c35d76ee410eea7c0987ed</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                    <category>
                        <![CDATA[ responsive design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 08 Jan 2020 19:44:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/02/daniel-korpai-8GDCzWrcE3M-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>React Native makes the process of developing an application that works on both Android and iOS devices much easier than it once was. While before you had to work with at least two programming languages and vastly different APIs, React Native includes some helpful ones out of the box.</p>
<p>Here's a rundown of two that will help you build your next app.</p>
<h2 id="heading-touchables">Touchables</h2>
<p>Some of the main features of mobile devices revolve around user touch interactions. How a mobile app handles and responds to these interactions can make or break the user’s experience.</p>
<p>React Native ships with a <code>Button</code> component which works for many standard <code>onPress</code> interactions. By default, it will give the user feedback by changing the opacity to show the button was pressed. Usage:</p>
<pre><code class="lang-js">&lt;Button onPress={handlePress} title=<span class="hljs-string">"Submit"</span> /&gt;
</code></pre>
<p>For more complex use cases, React Native has APIs build in to handle press interactions called <code>Touchables</code>.</p>
<pre><code class="lang-text">TouchableHighlight
TouchableNativeFeedback
TouchableOpacity
TouchableWithoutFeedback
</code></pre>
<p>Each of these Touchable components can be styled and used with a library, like the built-in <code>Animated</code>, allowing you to make your own types of custom user feedback.</p>
<p>Some examples of using these components:</p>
<pre><code class="lang-js"><span class="hljs-comment">// with images</span>
&lt;TouchableHighlight onPress={<span class="hljs-built_in">this</span>.handlePress}&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
    <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.button}</span>
    <span class="hljs-attr">source</span>=<span class="hljs-string">{require(</span>'<span class="hljs-attr">.</span>/<span class="hljs-attr">logo.png</span>')}
  /&gt;</span></span>
&lt;/TouchableHighlight&gt;

<span class="hljs-comment">// with text</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">TouchableHighlight</span> <span class="hljs-attr">onPress</span>=<span class="hljs-string">{this.handlePress}</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">TouchableHighlight</span>&gt;</span></span>
</code></pre>
<p>You can handle different types of button presses as well. By default, buttons and touchables are configured to handle regular taps, but you can also denote a function to call for press and hold interactions for example.</p>
<pre><code class="lang-js">&lt;TouchableHighlight onPress={<span class="hljs-built_in">this</span>.handlePress} onLongPress={<span class="hljs-built_in">this</span>.handleLongPress}&gt;
</code></pre>
<p>To see all of the available props and how these components work, you can look at <a target="_blank" href="https://github.com/facebook/react-native/tree/master/Libraries/Components/Touchable">the JavaScript source code for Touchables here</a>.</p>
<h2 id="heading-screen-dimensions">Screen Dimensions</h2>
<p>React Native uses Dots Per Inch (DPI) to measure the sizing of the User Interface (UI) and anything displayed on the UI. This type of measurement allows an application to look uniform across various screen sizes and pixel densities.</p>
<p>For standard use cases, applications can be developed without having to know the specifics of the user’s device (for example, pixel density) since the UI elements will scale automatically. </p>
<p>When it is required, there are APIs available such as <code>PixelRatio</code> to help you find out the pixel density of the user's device.</p>
<p>To get the window or screen height/width of a user's device, React Native has an API called <code>Dimensions</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Dimensions } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
</code></pre>
<p>Here are the methods that the <code>Dimensions</code> API provides:</p>
<pre><code class="lang-js">Dimensions.get(<span class="hljs-string">'window'</span>).height;
Dimensions.get(<span class="hljs-string">'window'</span>).width;
Dimensions.get(<span class="hljs-string">'screen'</span>).height;
Dimensions.get(<span class="hljs-string">'screen'</span>).width;
</code></pre>
<p><strong>Note:</strong> There have been some known issues in the past with the Dimensions API such as not returning the correct information when a user rotates their device. It’s best to make sure you test this on actual devices before deploying an application.</p>
<h3 id="heading-more-info-on-responsive-design">More info on responsive design:</h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/master-responsive-website-design/">Free responsive design course</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/p/f401cbed-6c27-46e5-a56f-c9853b87e244/freecodecamp.org/news/best-bootstrap-tutorial-responsive-web-design/">Best Bootstrap tutorials for responsive web design</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-start-thinking-responsively/">How to think responsively</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/your-complete-guide-to-truly-responsive-images/">Guide to responsive images</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/learn-responsive-web-design-in-5-minutes/">Learn responsive design in 5 minutes</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
