<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Remi Guan</title>
    <description>The latest articles on Forem by Remi Guan (@remi-guan).</description>
    <link>https://forem.com/remi-guan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1794843%2F4f3b7c08-25b1-4464-99c4-1909997712e9.jpeg</url>
      <title>Forem: Remi Guan</title>
      <link>https://forem.com/remi-guan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/remi-guan"/>
    <language>en</language>
    <item>
      <title>Create and publish an npm library, with TypeScript and Semantic Versioning</title>
      <dc:creator>Remi Guan</dc:creator>
      <pubDate>Fri, 13 Sep 2024 05:45:15 +0000</pubDate>
      <link>https://forem.com/remi-guan/create-and-publish-an-npm-library-with-typescript-and-semantic-versioning-9l</link>
      <guid>https://forem.com/remi-guan/create-and-publish-an-npm-library-with-typescript-and-semantic-versioning-9l</guid>
      <description>&lt;h1&gt;
  
  
  🚀 Write and publish a minimal code
&lt;/h1&gt;

&lt;p&gt;To publish a library on npm, you'll need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;npm account&lt;/strong&gt;; you can &lt;a href="https://www.npmjs.com/signup" rel="noopener noreferrer"&gt;sign up here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your code as a project; i.e., you have a &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt; in your code directory, which has &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt; specified. Note that you can generate this file via:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;An &lt;strong&gt;&lt;code&gt;index.js&lt;/code&gt;&lt;/strong&gt; in your project. Remember, you need to export your function to allow users to import it.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your script isn't named &lt;code&gt;index.js&lt;/code&gt; and placed in the project root, you need to specify the &lt;code&gt;"main"&lt;/code&gt; property in &lt;code&gt;package.json&lt;/code&gt;. See &lt;a href="https://stackoverflow.com/a/22513200/5299236" rel="noopener noreferrer"&gt;this answer&lt;/a&gt; for more info.&lt;/p&gt;

&lt;p&gt;And if the name has been taken on npm, you can add a prefix like &lt;code&gt;@name-or-org/your-lib&lt;/code&gt;; that's what most other libraries do nowadays.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can check my minimal example for reference, but I believe you can write something cooler than this.&lt;/p&gt;

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

&lt;p&gt;Finally, publish it with the CLI command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note to people setting the package name with a prefix:&lt;/strong&gt; It &lt;strong&gt;MUST&lt;/strong&gt; be your npm username or organization name you registered on npm. For example, I can use &lt;code&gt;@remi_guan&lt;/code&gt; as my prefix but not others.&lt;/p&gt;

&lt;p&gt;Also, you need to run &lt;code&gt;npm publish --access public&lt;/code&gt;, because npm thinks you want to publish a private package, which is a paid feature.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This output means it has been successful. However, if you ran into some trouble, you can search on Google to troubleshoot. And here's how you can use your own library:&lt;/p&gt;

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

&lt;p&gt;If you've been following this guide, please try your own library instead.&lt;/p&gt;

&lt;p&gt;I've also found &lt;a href="https://dev.to/backendbro/a-step-by-step-guide-how-to-create-and-publish-an-npm-package-2off?ref=dailydev"&gt;@backendbro has a much detailed guide than this&lt;/a&gt;, if you would like to know more.&lt;/p&gt;

&lt;p&gt;After you have published your code, when you want to update the code, can run &lt;code&gt;npm publish&lt;/code&gt; again. However, before publish you should update the &lt;code&gt;version&lt;/code&gt; property of &lt;code&gt;package.json&lt;/code&gt;, and please comply with &lt;a href="https://docs.npmjs.com/about-semantic-versioning" rel="noopener noreferrer"&gt;Semantic Versioning&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I suggest you try it! Can you publish your library's &lt;code&gt;v1.0.1&lt;/code&gt; or &lt;code&gt;v1.1.0&lt;/code&gt;, and use it in another project like what I've just done? Can you figure out how to update your npm library's version?&lt;/p&gt;

&lt;h1&gt;
  
  
  💖 Use TypeScript
&lt;/h1&gt;

&lt;p&gt;This library we've created so far is not modern, it lacks type declaration so people who use your library can't get highlighted with typing. Also, people commonly use TypeScript with ECMAScript syntax. To learn about the difference: &lt;a href="https://dev.to/saisathish/nodejs-modules-commonjs-vs-ecmascript-28da"&gt;Node.js Modules: CommonJS vs. ECMAScript by Saisathish&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But I'm going to skip the detailed setup of TypeScript in this post. There are many good tutorials to learn how to initialize a TypeScript project, like &lt;a href="https://medium.com/@rifantechguy55/how-to-develop-a-typescript-library-ade8d329636" rel="noopener noreferrer"&gt;“How to develop a Typescript Library” by inapeace0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even further, you can use a template TypeScript repository like &lt;a href="https://github.com/alexjoverm/typescript-library-starter/tree/master" rel="noopener noreferrer"&gt;alexjoverm/typescript-library-starter&lt;/a&gt; that has already integrated many modern tools, best practices, etc.&lt;/p&gt;

&lt;p&gt;I'm just going to mention some important notes if you're publishing a TypeScript library:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build before you publish.&lt;/strong&gt; If you need to publish it to the public, people with the most common Node.js environment can only execute &lt;code&gt;.js&lt;/code&gt; files. So you need to compile your code with &lt;code&gt;tsc&lt;/code&gt;, &lt;code&gt;rollup&lt;/code&gt; (or &lt;code&gt;vite&lt;/code&gt;, which uses rollup), or &lt;code&gt;webpack&lt;/code&gt;; any one is okay.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You need to correctly point to the compiled file by using &lt;code&gt;module&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, or &lt;code&gt;entry&lt;/code&gt; properties in &lt;code&gt;package.json&lt;/code&gt;. Using a template and learning them one by one is a good choice. Again, &lt;a href="https://github.com/alexjoverm/typescript-library-starter/blob/master/package.json#L6" rel="noopener noreferrer"&gt;alexjoverm/typescript-library-starter specified them nicely&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Include a &lt;code&gt;.d.ts&lt;/code&gt; file.&lt;/strong&gt; For the same reason, the user also needs access to the type signatures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But if you're sure your library will run on Deno, Bun, or ts-node, you can ignore my above guidelines because they support running TypeScript code natively.&lt;/p&gt;

&lt;p&gt;Please try to follow a guide to create a TypeScript library and publish it to npm. It's still easy, like the first example. You should test it with another project using &lt;code&gt;import&lt;/code&gt; syntax, and you can see type hints with an IDE.&lt;/p&gt;

&lt;p&gt;With TypeScript, I can write my library in this syntax:&lt;/p&gt;

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

&lt;p&gt;And after publishing, I can install and import it, and see the type hints thanks to TypeScript.&lt;/p&gt;

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

&lt;h1&gt;
  
  
  ✨ Semantic Versioning
&lt;/h1&gt;

&lt;p&gt;There's a common but slightly advanced problem waiting to be solved: Each time we update our package, we need to edit the version code.&lt;/p&gt;

&lt;p&gt;That's annoying, especially if you're frequently updating your code.&lt;/p&gt;

&lt;p&gt;However, there are tools to help you out.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/semantic-release/semantic-release" rel="noopener noreferrer"&gt;semantic-release&lt;/a&gt;: Fully automatic; you can integrate it into GitHub CI to automatically update the version code and publish to npm each time you update your code on GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/release-it/release-it" rel="noopener noreferrer"&gt;release-it&lt;/a&gt;: Also helps you bump the version, but it's simple to use (no need for CI knowledge); meanwhile, you don't configure it as fully automated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta2ab6qqhpgnwqdw64u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta2ab6qqhpgnwqdw64u2.png" alt="Pros and Cons between semantic-release and release-it" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used ChatGPT to generate this summary comparing the two tools. For new coders, I'd suggest you try release-it, but semantic-release is also convenient if you know how to integrate it with CI.&lt;/p&gt;

&lt;p&gt;In this post I'm going to show you how to use release-it, well, after you have made change to the project, simply run this in your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx release-it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And choose is it a minor change or major change, then you're done!&lt;/p&gt;

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




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

&lt;p&gt;So there you have it! We've walked through publishing a simple npm library, updating it, and even using TypeScript to make it more modern and robust. Remember to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Export your functions properly&lt;/strong&gt; so others can use them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update your version numbers&lt;/strong&gt; following Semantic Versioning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consider using TypeScript&lt;/strong&gt; for better type safety and developer experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate your releases&lt;/strong&gt; with tools like &lt;code&gt;release-it&lt;/code&gt; or &lt;code&gt;semantic-release&lt;/code&gt; to save time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give it a try! Publish your own library, update it, and see how it feels to contribute to the npm ecosystem. Happy coding!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>npm</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
