<?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[ npm scripts - 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[ npm scripts - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 24 Jun 2026 17:36:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/npm-scripts/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ The React Scripts Start Command – Create-React-App NPM scripts explained ]]>
                </title>
                <description>
                    <![CDATA[ Creating a React application requires you to set up build tools such as Babel and Webpack. These build tools are required because React's JSX syntax is a language that the browser doesn't understand.  To run your React application, you need to turn y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-react-app-npm-scripts-explained/</link>
                <guid isPermaLink="false">66bd914dabf0ccf74f1ce9b0</guid>
                
                    <category>
                        <![CDATA[ create-react-app ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm scripts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathan Sebhastian ]]>
                </dc:creator>
                <pubDate>Mon, 04 Jan 2021 16:15:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/12/cra-npm-scripts-explained.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Creating a React application requires you to set up build tools such as Babel and Webpack. These build tools are required because React's JSX syntax is a language that the browser doesn't understand. </p>
<p>To run your React application, you need to turn your JSX into plain JavaScript, which browsers understand.</p>
<p><a target="_blank" href="https://github.com/facebook/create-react-app">Create React App (CRA)</a> is a tool to create single-page React applications that is officially supported by the React team. </p>
<p>The script generates the required files and folders to start the React application and run it on the browser. This allows you to focus on coding your application without having to bother with build configurations.</p>
<h2 id="heading-the-dependencies-that-create-react-app-uses">The dependencies that create-react-app uses</h2>
<p>Although you can't see Babel or Webpack listed as dependencies in the generated <code>package.json</code> file, CRA still uses Babel and Webpack under the hood. It's just that the configurations are hidden from you inside the <a target="_blank" href="https://github.com/facebook/create-react-app/tree/master/packages/react-scripts"><code>react-scripts</code> package</a>.</p>
<p>When you look into the <code>package.json</code> file of react-scripts, you'll see all the packages needed to make React works in the browser. It has 58 packages, from line 31 to 88:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/package.json#L30">https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/package.json#L30</a></div>
<p>That's a lot of packages! Let's break it down a little to understand what these packages are used for.</p>
<p><em>Please note that this article was written using Create React App version 4.0.1 as the reference. This article will help you understand what happens under the hood when you use Create React App NPM scripts.</em></p>
<h3 id="heading-babel">Babel</h3>
<p>The main purpose of Babel is to make your code readable by older browsers. Since the release of ES 2015, browsers have seen slow but steady progress to implement new JavaScript APIs and features. </p>
<p>The most advanced browsers like Chrome and Safari may support new JavaScript versions, but JSX is a React-only feature that's not a part of ES versions.</p>
<p>Babel transforms your modern JavaScript code into the older version, and then adds <em>polyfills</em>, a piece of code that implements features missing in the browser but needed by your app.</p>
<h3 id="heading-eslint">ESLint</h3>
<p>ESLint is a JavaScript linter that will scan your code and flag any code errors. The library will warn you from the console if you have any errors. It also plays well with a modern code editor like VSCode.</p>
<h3 id="heading-jest">Jest</h3>
<p>Jest is a testing library by Facebook that plays very well with React. The dependencies for Jest allow you to write test scripts for your application without having to install another testing library.</p>
<h3 id="heading-postcss">PostCSS</h3>
<p>PostCSS is a JavaScript plugin to transform your CSS. PostCSS plugins can lint your CSS, support variables and mixins syntax, transpile future CSS syntax, and many more things depending on its configs.</p>
<h3 id="heading-webpack">Webpack</h3>
<p>Webpack is a module bundler for JavaScript that puts everything needed by your application together. This library can also run tasks like running Babel, Jest, ESLint, and PostCSS on top of your code.</p>
<p>Now that you have an idea what the dependencies are used for, let's continue with understanding what <code>react-scripts</code> really do behind the scene.</p>
<h2 id="heading-what-react-scripts-do">What react-scripts do</h2>
<p>react-scripts are simply scripts to run the build tools required to transform React JSX syntax into plain JavaScript programmatically. </p>
<p>There are four scripts provided by this package:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts: {
  "</span>start<span class="hljs-string">": "</span>react-scripts start<span class="hljs-string">",
  "</span>build<span class="hljs-string">": "</span>react-scripts build<span class="hljs-string">",
  "</span>test<span class="hljs-string">": "</span>react-scripts test<span class="hljs-string">",
  "</span>eject<span class="hljs-string">": "</span>react-scripts eject<span class="hljs-string">"
},</span>
</code></pre>
<p>When you run one of the scripts, the <a target="_blank" href="https://github.com/facebook/create-react-app/tree/master/packages/react-scripts/bin">/bin/react-scripts.js</a> will be executed to start the process. This script will look into the arguments that you passed into the call. It only accepts start, build, test, and eject arguments.</p>
<p>Any other argument you passed will cause the script to return an unknown script to the log:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/cra-unknown-script-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>CRA unknown script console output</em></p>
<p>When you pass a valid argument, it will run the scripts located inside the <a target="_blank" href="https://github.com/facebook/create-react-app/tree/master/packages/react-scripts/scripts"><code>/scripts</code> folder</a>. Let's start by looking at the <code>start.js</code> script.</p>
<h2 id="heading-how-the-react-scripts-start-process-works">How the react-scripts start process works</h2>
<p>With the <code>start</code> argument, NPM will begin the process to make a development server available for your React application. Here's a list of tasks for this script:</p>
<ul>
<li>Set the build environment into <code>development</code> for Node and Babel</li>
<li>Ensure environment variables are read for the build process </li>
<li>Verify the packages installed in your project are not outdated</li>
<li>Check whether the code is in TypeScript or not</li>
<li>Import required packages for the process, mostly Webpack-related modules</li>
<li>Check for available port and host IP, defaults to 0.0.0.0:3000</li>
<li>Run the compiler and listen for any messages from Webpack. Webpack will take care of using Babel, ESLint, and any other tools to prepare your code</li>
<li>While Webpack is running, the script will open your browser and start the development server</li>
</ul>
<p>The development server created by <a target="_blank" href="https://github.com/facebook/create-react-app/blob/8bf050aa7c16078fed5e51ac8388d6100c29e105/packages/react-scripts/scripts/start.js#L37">WebpackDevServer</a> will also create a listener for changes in your JavaScript file. When you make changes and save your JavaScript file, the development server will recompile your code and quickly refresh the browser.</p>
<h2 id="heading-how-to-use-the-react-scripts-build-command">How to use the react-scripts build command</h2>
<p>The <code>build</code> command will start the process of creating a production-ready React app for you. Mostly, it does the same step as a <code>start</code> command, except that it sets the build environment to <code>production</code>.</p>
<p>Instead of checking for available ports and running a development server, the script will run the <a target="_blank" href="https://github.com/facebook/create-react-app/blob/8bf050aa7c16078fed5e51ac8388d6100c29e105/packages/react-scripts/scripts/build.js#L152"><code>build</code></a> <a target="_blank" href="https://github.com/facebook/create-react-app/blob/8bf050aa7c16078fed5e51ac8388d6100c29e105/packages/react-scripts/scripts/build.js#L152">function</a>, which will bundle all your separate files into one <code>bundle.js</code> file. The production build will also ensure that your code is optimized and minified to make sure it has the best performance.</p>
<p>If you've already run the <code>build</code> command before, the script will take your current file size and compare it with the next build. It will show you how much the file size has changed:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/cra-build-result.png" alt="Image" width="600" height="400" loading="lazy">
<em>React shows comparison after gzip in the console</em></p>
<p>The final output of this command can be found in the <code>build/</code> folder, which is generated at your project's root.</p>
<h2 id="heading-how-to-use-the-react-scripts-test-command">How to use the react-scripts test command</h2>
<p>The <code>test</code> command will run any test scripts that you've written using <a target="_blank" href="https://jestjs.io/">Jest</a>. Your tests will be run under a Node environment. Jest will run under the interactive watch mode, which means every time you save a file, it will re-run the tests, like how the <code>start</code> command recompiles the code.</p>
<p>You can save your test files anywhere inside the <code>src/</code> folder, and the script will find and execute any file with <code>.test.js</code> or <code>.spec.js</code> extensions. It will also run any <code>.js</code> file under the <code>__tests__/</code> folder.</p>
<p>You can see the test result from the terminal:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/cra-test-result-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Console log of react-scripts test command result</em></p>
<p>Keep in mind that CRA's test command only covers testing your component and business logic under a stable environment. To run an end-to-end test in the browser, you need to use another testing library.</p>
<h2 id="heading-how-to-use-the-react-scripts-eject-command">How to use the react-scripts eject command</h2>
<p>The last command, <code>eject</code>, is used to remove the dependency on <code>react-scripts</code> and expose the build tools and configurations for you to modify. </p>
<p>All the configuration files from <code>react-scripts</code> will be copied into your project root's <code>config/</code> folder, and the scripts to run the build will be copied into the <code>scripts/</code> folder. The dependencies will also be moved into your root's <code>package.json</code> file.</p>
<p>This command is a one-way operation. Once you have ejected from CRA set up, you can't undo it. If you have committed your code into a source code management system like Git, you can undo the changes with <code>git checkout</code> or <code>git reset</code>.</p>
<p>Generally, you don't need to run this command because CRA has already provided sensible configurations suitable for small and mid-sized projects. If you're interested to learn more, I have written a post about ejecting your React App here:</p>
<p><a target="_blank" href="https://sebhastian.com/create-react-app-eject/">Should you eject your Create React App?</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As more people use CRA, the development team will receive more feedback about how the tool is used in real projects. The insights gained by the development team will ensure that CRA will stay updated with the latest tools and has best practices for building React apps.</p>
<p>If you enjoyed this article and want to take your JavaScript skills to the next level, I recommend you check out my new book <em>Beginning Modern JavaScript</em> <a target="_blank" href="https://www.amazon.com/dp/B0CQXHMF8G">here</a>.</p>
<p><a target="_blank" href="https://www.amazon.com/dp/B0CQXHMF8G"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" alt="beginning-js-cover" width="600" height="400" loading="lazy"></a></p>
<p>The book is designed to be easy to understand and accessible to anyone looking to learn JavaScript. It provides a step-by-step gentle guide that will help you understand how to use JavaScript to create a dynamic application.</p>
<p>Here's my promise: <em>You will actually feel like you understand what you're doing with JavaScript.</em></p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Custom React Hook and Publish it to npm ]]>
                </title>
                <description>
                    <![CDATA[ Hooks are a handy addition to the React API that allow us to organize some of our logic and state in function components. How can we build a custom hook and share it with the rest of the world? What are hooks? Why are custom hooks cool? What are we ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-custom-react-hook-and-publish-it-to-npm/</link>
                <guid isPermaLink="false">66b8e34f682e4a25eed261a0</guid>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm scripts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Yarn ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 14 Apr 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Custom-React-Hooks-Book-Cover--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hooks are a handy addition to the React API that allow us to organize some of our logic and state in function components. How can we build a custom hook and share it with the rest of the world?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-hooks">What are hooks?</a></li>
<li><a class="post-section-overview" href="#heading-why-are-custom-hooks-cool">Why are custom hooks cool?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-make">What are we going to make?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-naming-your-hook">Step 0: Naming your hook</a></li>
<li><a class="post-section-overview" href="#heading-step-1-setting-up-your-project">Step 1: Setting up your project</a></li>
<li><a class="post-section-overview" href="#heading-step-2-writing-your-new-react-hook">Step 2: Writing your new React Hook</a></li>
<li><a class="post-section-overview" href="#heading-step-3-using-your-react-hook-in-an-example">Step 3: Using your React hook in an example</a></li>
<li><a class="post-section-overview" href="#heading-step-4-compiling-your-react-hook-and-example">Step 4: Compiling your React hook and Example</a></li>
<li><a class="post-section-overview" href="#heading-step-5-publishing-your-react-hook-to-npm">Step 5: Publishing your React hook to npm</a></li>
<li><a class="post-section-overview" href="#heading-more-resources-about-hooks">More resources about hooks</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Q0xVnRanXVk" 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-are-hooks">What are hooks?</h2>
<p>React <a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">hooks</a> in simple terms are functions. When you include them in your component or within another hook, they allow you to make use of React internals and parts of the React lifecycle with native hooks like <code>useState</code> and <code>useEffect</code>.</p>
<p>I don’t plan on doing a deep dive about hooks, but you can <a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">check out a quick introduction</a> with an example of <code>useState</code> as well as <a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">the intro from the React team</a>.</p>
<h2 id="heading-why-are-custom-hooks-cool">Why are custom hooks cool?</h2>
<p>The great thing about creating custom hooks is they allow you to abstract logic for your components making it easier to reuse across multiple components in your app.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/hook-example-use-counter-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Hook diagram example for useCounter</em></p>
<p>For instance, if you wanted to create a simple counter where you use React’s state to manage the current count. Instead of having the same <code>useState</code> hook in each component file, you can create that logic once in a <code>useCounter</code> hook, making it easier to maintain, extend, and squash bugs if they come up.</p>
<h2 id="heading-what-are-we-going-to-make">What are we going to make?</h2>
<p>For the purposes of this article, we’re going to keep it simple with a basic hook. Typically, you might use a hook because rather than a typical function, you use other native hooks that are required to be used within React function components. We’re going to stick with some basic input and output to keep things simple.</p>
<p>We’re going to recreate this custom <a target="_blank" href="https://github.com/colbyfayock/use-placecage">Placecage hook</a> I made, that allows you to easily generate image URLs that you can use as placeholder images.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/nic-cage-excited.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Nic Cage excited</em></p>
<p>If you’re not familiar, <a target="_blank" href="https://www.placecage.com/">Placecage</a> is an API that allows you to generate pictures of Nic Cage as placeholder images for your website. Silly? Yes. Fun? Absolutely!</p>
<p>But if you’re not a fan of Nic's work, you can just as easily swap in the URL for <a target="_blank" href="https://placeholder.com/">Fill Murray</a> which uses pictures of Bill Murray or <a target="_blank" href="https://placeholder.com/">placeholder.com</a> which generates simple solid color background with text that shows the size of the image.</p>
<h2 id="heading-step-0-naming-your-hook">Step 0: Naming your hook</h2>
<p>Before we jump in to our actual code, our ultimate goal is to publish this hook. If that’s not your goal, you can skip this step, but for publishing, we’ll want to create a name for our hook.</p>
<p>In our case, our hook name will be <code>usePlaceCage</code>. Now with that in mind, we have 2 formats of our name — one in camelCase format and one in snake-case format.</p>
<ul>
<li><strong>camelCase:</strong> usePlaceCage</li>
<li><strong>snake-case:</strong> use-placecage</li>
</ul>
<p>The camelCase format will be used for the actual hook function, where the snake-case name will be used for the package name and some of the folders. When creating the name, keep in mind that the package name must be unique. If a package with the same name exists on <a target="_blank" href="https://www.npmjs.com/">npmjs.com</a> already, you won't be able to use it.</p>
<p>If you don’t already have a name, it's okay! You can just use your own name or something you can think of, it doesn’t really matter too much as really we're just trying to learn how to do this. If it were me for instance, I would use:</p>
<ul>
<li><strong>camelCase:</strong> useColbysCoolHook</li>
<li><strong>snake-case:</strong> use-colbyscoolhook</li>
</ul>
<p>But just to clarify, for the rest of our example, we’re going to stick with <code>usePlaceCage</code> and <code>use-placecage</code>.</p>
<h2 id="heading-step-1-setting-up-your-project">Step 1: Setting up your project</h2>
<p>Though you can set up your project however you’d like, we’re going to walk through building a new hook from <a target="_blank" href="https://github.com/colbyfayock/use-custom-hook">this template</a> I created.</p>
<p>The hope here, is that we can take out some of the painful bits of the process and immediately get productive with our custom hook. Don’t worry though, I’ll explain what’s going on along the way.</p>
<p>The requirements here are <a target="_blank" href="https://git-scm.com/">git</a> and <a target="_blank" href="https://yarnpkg.com/">yarn</a> as it helps provide tools that make it easy to scaffold this template, such as using the workspaces feature to allow easy npm scripts to manage the code from the root of the project. If either of those are a dealbreaker, you can try downloading the repo via the download link and update it as needed.</p>
<h3 id="heading-cloning-the-hook-template-from-git">Cloning the hook template from git</h3>
<p>To start, let’s clone the repository from Github. In the command below, you should replace <code>use-my-custom-hook</code> with the name of your hook, such as <code>use-cookies</code> or <code>use-mooncake</code>.</p>
<pre><code class="lang-shell">git clone https://github.com/colbyfayock/use-custom-hook use-my-custom-hook
cd use-my-custom-hook
</code></pre>
<p>Once you clone and navigate to that folder, you should now see 2 directories – an <code>example</code> directory and a <code>use-custom-hook</code> directory.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/cloning-use-custom-hook-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Cloning use-custom-hook</em></p>
<p>This will give you a few things to get started:</p>
<ul>
<li>A hook directory that will include the source for our hook</li>
<li>Build scripts that compile our hook with <a target="_blank" href="https://babeljs.io/">babel</a></li>
<li>An example page that imports our hook and creates a simple demo page with <a target="_blank" href="https://nextjs.org/">next.js</a></li>
</ul>
<h3 id="heading-running-the-hook-setup-scripts">Running the hook setup scripts</h3>
<p>After we successfully clone the repo, we want to run the setup scripts which install dependencies and update the hook to the name we want.</p>
<pre><code class="lang-shell">yarn install &amp;&amp; yarn setup
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/setting-up-new-hook-template.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Setting up a new hook from the use-custom-hook template</em></p>
<p>When the setup script runs, it will do a few things:</p>
<ul>
<li>It will ask you for your name – this is used to update the LICENSE and the package's author name</li>
<li>It will ask you for your hook's name in 2 variations – camelCase and snake-case - this will be used to update the name of the hook throughout the template and move files with that name to the correct location</li>
<li>It will reset git – it will first remove the local .git folder, which contains the history from my template and reinitialize git with a fresh commit to start your new history in</li>
<li>Finally, it will remove the setup script directory and remove the package dependencies that were only being used by those scripts</li>
</ul>
<h3 id="heading-starting-the-development-server">Starting the development server</h3>
<p>Once the setup scripts finish running, you'll want to run:</p>
<pre><code class="lang-shell">yarn develop
</code></pre>
<p>This runs a watch process on the hook source, building the hook locally each time a source file is changed, and running the example app server, where you can test the hook and make changes to the example pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/custom-hook-development-server.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Starting up the use-custom-hook development server</em></p>
<p>With this all ready, we can get started!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commits/master">Follow along with the commit!</a></p>
<h2 id="heading-step-2-writing-your-new-react-hook">Step 2: Writing your new React Hook</h2>
<p>At this point, you should now have a new custom hook where you can make it do whatever you'd like. But since we're going to walk through rebuilding the <a target="_blank" href="https://github.com/colbyfayock/use-placecage">usePlaceCage</a> hook, let's start there.</p>
<p>The usePlaceCage hook does 1 simple thing from a high level view – it takes in a configuration object and returns a number of image URLs that you can then use for your app.</p>
<p>Just as a reminder, any time I mention <code>usePlaceCage</code> or <code>use-placecage</code>, you should use the hook name that you set up before.</p>
<h3 id="heading-a-little-bit-about-placecagecom">A little bit about placecage.com</h3>
<p>Placecage.com is a placeholder image service that does 1 thing. It takes a URL with a simple configuration and returns an image... of Nic Cage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/placecage-website.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>placecage.com</em></p>
<p>From the simplest use, the service uses a URL pattern as follows:</p>
<pre><code>https:<span class="hljs-comment">//www.placecage.com/200/300</span>
</code></pre><p>This would return an image with a width of 200 and height of 300.</p>
<p>Optionally, you can pass an additional URL parameter that defines the type of image:</p>
<pre><code>https:<span class="hljs-comment">//www.placecage.com/gif/200/300</span>
</code></pre><p>In this particular instance, our type is <code>gif</code>, so we'll receive a gif.</p>
<p>The different types available to use are:</p>
<ul>
<li>Nothing: calm</li>
<li><code>g</code>: gray</li>
<li><code>c</code>: crazy</li>
<li><code>gif</code>: gif</li>
</ul>
<p>We'll use this to define how we set up configuration for our hook.</p>
<h3 id="heading-defining-our-core-generator-function">Defining our core generator function</h3>
<p>To get started, we're going to copy over a function at the bottom of our <code>use-placecage/src/usePlaceCage.js</code> file, which allows us to generate an image URL, as well as a few constant definitions that we'll use in that function.</p>
<p>First, let's copy over our constants to the top of our <code>usePlaceCage.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PLACECAGE_HOST = <span class="hljs-string">'https://www.placecage.com/'</span>;
<span class="hljs-keyword">const</span> TYPES = {
  <span class="hljs-attr">calm</span>: <span class="hljs-literal">null</span>,
  <span class="hljs-attr">gray</span>: <span class="hljs-string">'g'</span>,
  <span class="hljs-attr">crazy</span>: <span class="hljs-string">'c'</span>,
  <span class="hljs-attr">gif</span>: <span class="hljs-string">'gif'</span>
};
<span class="hljs-keyword">const</span> DEFAULT_TYPE = <span class="hljs-string">'calm'</span>;
<span class="hljs-keyword">const</span> ERROR_BASE = <span class="hljs-string">'Failed to place Nick'</span>;
</code></pre>
<p>Here we:</p>
<ul>
<li>Define a host, which is the base URL of our image service.</li>
<li>Define the available types, which we'll use in the configuration API. We set <code>calm</code> to <code>null</code>, because it's the default value which you get by not including it at all</li>
<li>Our default type will be <code>calm</code></li>
<li>And we set an error base which is a consistent message when throwing an error</li>
</ul>
<p>Then for our function, let's copy this at the bottom of our <code>usePlaceCage.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateCage</span>(<span class="hljs-params">settings</span>) </span>{
  <span class="hljs-keyword">const</span> { type = DEFAULT_TYPE, width = <span class="hljs-number">200</span>, height = <span class="hljs-number">200</span>, count = <span class="hljs-number">1</span> } = settings;
  <span class="hljs-keyword">const</span> config = [];

  <span class="hljs-keyword">if</span> ( type !== DEFAULT_TYPE &amp;&amp; TYPES[type] ) {
    config.push(TYPES[type]);
  }

  config.push(width, height);

  <span class="hljs-keyword">if</span> ( <span class="hljs-built_in">isNaN</span>(count) ) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`<span class="hljs-subst">${ERROR_BASE}</span>: Invalid count <span class="hljs-subst">${count}</span>`</span>);
  }

  <span class="hljs-keyword">return</span> [...new <span class="hljs-built_in">Array</span>(count)].map(<span class="hljs-function">() =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${PLACECAGE_HOST}</span><span class="hljs-subst">${config.join(<span class="hljs-string">'/'</span>)}</span>`</span>);
}
</code></pre>
<p>Walking through this code:</p>
<ul>
<li>We define a <code>generateCage</code> function which we'll use to generate our image URL</li>
<li>We take in a settings object as an argument, which defines the configuration of our image URL. We'll be using the same parameters as we saw in our placecage.com URL</li>
<li>We destructure those settings to make them available for us to use</li>
<li>We have a few defaults here just to make it easier. Our default <code>type</code> will be defined by <code>DEFAULT_TYPE</code> along with a default width, height, and number of results we want to return</li>
<li>We create a <code>config</code> array. We'll use this  to append all of the different configuration objects in our URL and finally join them together with a <code>/</code> essentially making a URL</li>
<li>Before we push our config to that array, we check if it's a valid argument, by using the <code>TYPES</code> object to check against it. If it's valid, we push it to our config array</li>
<li>We then push our width and height</li>
<li>We do some type checking, if we don't have a valid number as the <code>count</code>, we throw an error, otherwise we'll get incorrect results</li>
<li>Finally, we return a new array with the number of results requested, mapped to a URL creator, which uses <code>PLACECAGE_HOST</code> as our defined base URL, and with our config array joined by <code>/</code></li>
</ul>
<p>And if we were to test this function, it would look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> cage = generateCage({
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
});

<span class="hljs-built_in">console</span>.log(cage); <span class="hljs-comment">// ['https://www.placecage.com/gif/500/500', 'https://www.placecage.com/gif/500/500']</span>
</code></pre>
<h3 id="heading-using-our-function-in-the-hook">Using our function in the hook</h3>
<p>So now that we have our generator function, let's actually use it in our hook!</p>
<p>Inside of the <code>usePlaceCage</code> function in the <code>use-placecage/src/usePlaceCage.js</code> file, we can add:</p>
<pre><code class="lang-js"><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">usePlaceCage</span> (<span class="hljs-params">settings = {}</span>) </span>{
  <span class="hljs-keyword">return</span> generateCage(settings);
}
</code></pre>
<p>What this does it uses our generator function, takes in the settings that were passed into the hook, and returns that value from the hook.</p>
<p>Similar to our previous use example, if we were to use our hook, it would look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> cage = usePlaceCage({
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
});

<span class="hljs-built_in">console</span>.log(cage); <span class="hljs-comment">// ['https://www.placecage.com/gif/500/500', 'https://www.placecage.com/gif/500/500']</span>
</code></pre>
<p>At this point, it does the same thing!</p>
<p>So now we have our hook, it serves as a function to generate image URLs for the placecage.com service. How can we actually use it?</p>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commit/a4d4d3c3565759031c29d00faf731ac4c236a1fd">Follow along with the commit!</a></p>
<h2 id="heading-step-3-using-your-react-hook-in-an-example">Step 3: Using your React hook in an example</h2>
<p>The good news about our template, is it already includes an example app that we can update to easily make use of our hook to both test and provide documentation for those who want to use it.</p>
<h3 id="heading-setting-up-the-hook">Setting up the hook</h3>
<p>To get started, let's open up our <code>example/pages/index.js</code> file. Inside of this file you'll see the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> hookSettings = {
  <span class="hljs-attr">message</span>: <span class="hljs-string">'Hello, custom hook!'</span>
}

<span class="hljs-keyword">const</span> { message } = usePlaceCage(hookSettings);
</code></pre>
<p>This snippet is what was used by default in the template just for a proof of concept, so let's update that. We're going to use the same exact configuration as we did in Step 2:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> hookSettings = {
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
}

<span class="hljs-keyword">const</span> cage = usePlaceCage(hookSettings);
</code></pre>
<p>Again, we set up our settings object with the configuration for our hook and invoke our hook and set the value to the <code>cage</code> constant.</p>
<p>If we now console log that value our to our dev tools, we can see it working!</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'cage'</span>, cage);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/console-log-cage-array.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Using console.log to show the cage value</em></p>
<p><em>Note: If you get an error here about <code>message</code>, you  can comment that our or remove it under the Examples section.</em></p>
<h3 id="heading-updating-the-example-with-our-new-hook-configuration">Updating the example with our new hook configuration</h3>
<p>If you scroll down to the Examples section, you'll notice that we have the same default <code>hookSettings</code> as above, so let's update that again to make sure our example is accurate.</p>
<pre><code class="lang-jsx">{<span class="hljs-string">`const hookSettings = {
  type: 'gif',
  width: 500,
  height: 500,
  count: 2
}

const cage = usePlaceCage(hookSettings);`</span>}
</code></pre>
<p>You'll also notice that we're no longer using the <code>message</code> variable. If you didn't remove it in the last step, we can now replace it under the Output heading with:</p>
<pre><code class="lang-jsx">&lt;p&gt;
  { <span class="hljs-built_in">JSON</span>.stringify(cage) }
&lt;/p&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
  { cage.map((img, i) =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">img-</span>${<span class="hljs-attr">i</span>}`} <span class="hljs-attr">width</span>=<span class="hljs-string">{200}</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{img}</span> /&gt;</span>)}
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre>
<p>We're doing 2 things here:</p>
<ul>
<li>Instead of showing the variable itself, we wrap it with <code>JSON.stringify</code> so that we can show the contents of the array</li>
<li>We also use the <code>map</code> function to loop over our image URLs in the <code>cage</code> constant and create a new image element for each. This let's us preview the output instead of just seeing the values</li>
</ul>
<p>And once you save and open your browser, you should now see your updated examples and output!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/custom-hook-example-page.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Custom hook example page</em></p>
<h3 id="heading-other-things-you-can-do-on-that-page">Other things you can do on that page</h3>
<p>Before moving on, you can also update a few other things that will be important for your hooks page:</p>
<ul>
<li>Update the <strong>How to use</strong> section with instructions</li>
<li>Add additional examples to make it easier for people to know what to do</li>
</ul>
<p>A  few things are also automatically pulled in from the <code>use-placecage/package.json</code> file. You can either update them there to make it easier to maintain or you can replace them in the example page:</p>
<ul>
<li><code>name</code>: Is used at the <code>&lt;h1&gt;</code> of the page</li>
<li><code>description</code>: Is used at the description under the <code>&lt;h1&gt;</code></li>
<li><code>repository.url</code>: Used to include a link to the repository</li>
<li><code>author</code>: The <code>name</code> and <code>url</code> are used to include a link at the bottom of the page</li>
</ul>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commit/71ae57b562ad814d0ce862c22e247aa8c450b6cf">Follow along with the commit!</a></p>
<h2 id="heading-step-4-compiling-your-react-hook-and-example">Step 4: Compiling your React hook and Example</h2>
<p>The way we can make our hook work easily as an npm module is to compile it for others to use. We're using babel to do this.</p>
<p>Though the publish process already does this for us automatically with the <code>prepublishOnly</code> script in <code>use-placecage/package.json</code>, we can manually compile our hook using the <code>yarn build</code> command from the root of the project.</p>
<p>Along with compiling the hook, running <code>yarn build</code> will also compile the example page, allowing you to upload it wherever you'd like. After running that command, you should see an output of static HTML files in the <code>example/out</code> directory.</p>
<p>If you're looking for a recommendation, <a target="_blank" href="https://www.netlify.com/">Netlify</a> makes it easy to connect your <a target="_blank" href="https://github.com/">Github</a> account and deploy the static site.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/netlify-deployment-setup.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Deployment setup in Netlify</em></p>
<p><a target="_blank" href="https://use-my-custom-hook.netlify.com/">See the demo site deployed to Netlify!</a></p>
<h2 id="heading-step-5-publishing-your-react-hook-to-npm">Step 5: Publishing your React hook to npm</h2>
<p>Finally, if you're happy with your hook, it's time to publish!</p>
<p>npm makes this part really easy. The only prerequisite you need to have an npm account. With that account, let's log in:</p>
<pre><code class="lang-shell">npm login
</code></pre>
<p>Which will prompt you for your login credentials.</p>
<p>Next, let's navigate to our hook's directory, as our package configuration is there under <code>use-placecage/package.json</code>:</p>
<pre><code class="lang-shell">cd use-placecage
</code></pre>
<p>Then, we can simply publish!</p>
<pre><code class="lang-shell">npm publish
</code></pre>
<p>Keep in mind, that each package name needs to be unique. If you used <code>use-placecage</code>, it's already taken... by me. ?</p>
<p>But if you're successful, npm should build your hook and upload it to the package registry!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/publishing-npm-package.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Publishing an npm package</em></p>
<p>It will then be available on npm with the following pattern:</p>
<pre><code>https:<span class="hljs-comment">//www.npmjs.com/package/[package-name]</span>
</code></pre><p>So for <code>use-placeage</code>, it's available here: <a target="_blank" href="https://www.npmjs.com/package/use-placecage">https://www.npmjs.com/package/use-placecage</a></p>
<h2 id="heading-we-now-have-a-custom-hook">We now have a custom hook!</h2>
<p>Yay ? if you followed along, you should now have created a custom hook and published it to npm.</p>
<p>Though this was a silly example using placecage.com, it gives us a good idea of how we can easily set this up.</p>
<p>You'll also notice that this specific example wasn't the best use case for a hooks, where we could have simply used a function. Typically, we'll want to use custom hooks to wrap functionality that can only live inside a React component, such as <code>useState</code>. To learn more about that, you can read one of my other <a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">articles about custom hooks</a>.</p>
<p>However, this gave us a good basis to talk through the creation and configuration of our new hook!</p>
<h2 id="heading-more-resources-about-hooks">More resources about hooks</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">How to destructure the fundamentals of React Hooks</a> (freecodecamp.org)</li>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">Introducing Hooks</a> (reactjs.org)</li>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-reference.html">Hooks API Reference</a> (reactjs.org)</li>
</ul>
<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>
        
    </channel>
</rss>
