{"id":7804,"date":"2015-10-16T12:15:34","date_gmt":"2015-10-16T09:15:34","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=7804"},"modified":"2015-10-12T14:54:03","modified_gmt":"2015-10-12T11:54:03","slug":"release-libs-like-pro","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/","title":{"rendered":"Release your libs like a pro"},"content":{"rendered":"<p>Automate, automate, automate. That&#8217;s what ultimately is our job, right? We automate the tedious processes of our end-users.<\/p>\n<p>So why don&#8217;t we do it for ourselves as well? This guide quickly illustrates how to setup fully automated releases to Bower and NPM.<\/p>\n<p>And they&#8217;re even automatically semantic versioned.<\/p>\n<blockquote><p>Bower, NPM, semantic versioning?? Sounds strange? Check out my article <a href=\"\/blog\/2014\/08\/node-grunt-yeoman-bower\/\">Node, Grunt, Bower and Yeoman &#8211; A Modern web dev&#8217;s Toolkit<\/a>.<\/p><\/blockquote>\n<p>I <a href=\"\/blog\/2015\/06\/github-social-contribute-learn\/\">love to contribute to Open Source libraries on GitHub<\/a> and so should you!. You learn a lot, it&#8217;s coding as a hobby (not for being payed) and finally it&#8217;s also rewarding, especially when you then see people use your stuff, discuss with them etc. Most of the projects that get shared on GitHub are utility libraries that are designed to be highly reusable across projects. As such (for being discovered and used), they should follow a series of good practices like<\/p>\n<ul>\n<li>have good documentation (gosh! <img decoding=\"async\" title=\":unamused:\" src=\"https:\/\/assets.github.com\/images\/icons\/emoji\/unicode\/1f612.png\" alt=\"\" width=\"20\" height=\"20\" align=\"absmiddle\" \/> )<\/li>\n<li>CONTRIBUTING.md<\/li>\n<li>automated tests<\/li>\n<li>&#8230;<\/li>\n<li><strong>have automated builds in place<\/strong><\/li>\n<li><strong>be released on package managers<\/strong> to be easily discoverable<\/li>\n<li><strong>follow the semver specs<\/strong><\/li>\n<li><strong>have a changelog<\/strong><\/li>\n<\/ul>\n<p>The last points are the ones I&#8217;d like to address with this article as they&#8217;re something I see devs and library publishers often struggle with.<\/p>\n<h2>Issue 1: Have automated builds<\/h2>\n<p>You certainly already have your build scripts in place. Like a Grunt, Gulp, Webpack script or whatever of the currently fancy build tools you&#8217;re using. When you have that (and you definitely should), then you&#8217;re only steps away from a full blown automated build. Such a continuous integration server is extremely valuable as it builds your code, maybe lints it, executes your tests, frankly, it helps you keep your code working. This becomes even more important when other developers start to contribute to your library (which is the goal after all).<\/p>\n<p>As we will see, it&#8217;s super easy to setup such a CI server and it&#8217;s even totally free.<\/p>\n<h2>Issue 2: Releasing on package repositories<\/h2>\n<p>I&#8217;m mainly talking about JavaScript here as it is currently the prevalent language on GitHub, but it can be easily generalised to other languages as well. When you develop a library and you share it on GitHub, you want it to be used by others. Thus, installing your lib has to be as easy and straightforward as possible. This can be achieved by deploying your lib&#8217;s distribution files to so-called package managers. Currently the most used ones are <a href=\"https:\/\/www.npmjs.com\/\">NPM<\/a> and <a href=\"http:\/\/bower.io\/\">Bower<\/a>. There are other package managers on the way like <a href=\"http:\/\/jspm.io\/\">JSPM<\/a> as well. Deployment is done similarly as with Bower, though.<\/p>\n<blockquote><p>With distribution or &#8220;dist&#8221; files I intend the compiled, minified and packaged version of library that will be included in other projects.<\/p><\/blockquote>\n<h2>Issue 3: Follow the semver spec<\/h2>\n<p>When you release a new version of your library, it is important to communicate your changes. Did you add new features? Just patched some bugs? Are changes breaking? These are important things for a developer in order to know whether it is safe to upgrade. Package managers like Bower and NPM provide even mechanisms to perform automatic upgrades to the next &#8220;safe&#8221; version. Obviously this only works if you properly follow the <a href=\"http:\/\/semver.org\/\">semver spec<\/a>.<\/p>\n<p>Sadly, that&#8217;s where most libs fail. Should we increment the patch? The minor? Well, we did add some features, but hey&#8230;they aren&#8217;t thaaat huge.. maybe we should just increase the patch.<br \/>\nThese are the kind of thoughts going on&#8230;worse: increase the minor even if it&#8217;s a breaking change. You won&#8217;t believe, but popular libraries like Angular v1.x do that!!<\/p>\n<p>It doesn&#8217;t have to be like that, though. The semver spec is quite clear and should not leave any doubts: machines can do it for us! That&#8217;s probably what <a href=\"https:\/\/twitter.com\/boennemann\">Stephan B\u00f6nnemann<\/a> thought as well and started to automate the whole stuff. We&#8217;ll shortly see how.<\/p>\n<h2>Issue 4: Changelog<\/h2>\n<p>Finally, the change log. 95% of the time absent, 5% of the time hand written and often very flaky. It&#8217;s like everyone wants to have one, but it&#8217;s hard work to get it right.<\/p>\n<p>As someone recently said to me: &#8220;work smart, not hard&#8221; <img decoding=\"async\" title=\":smiley:\" src=\"https:\/\/assets.github.com\/images\/icons\/emoji\/unicode\/1f603.png\" alt=\"\" width=\"20\" height=\"20\" align=\"absmiddle\" \/>. Heard about <strong>&#8220;conventional commits&#8221;<\/strong>?? If I&#8217;m not wrong, the Angular team first introduced them: <a href=\"https:\/\/docs.google.com\/document\/d\/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y\/edit#\">read here<\/a>.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/changelog.png\"><img decoding=\"async\" class=\"aligncenter size-large wp-image-7833\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/changelog-1024x619.png\" alt=\"changelog\" width=\"620\" height=\"375\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/changelog-1024x619.png 1024w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/changelog-300x181.png 300w\" sizes=\"(max-width: 620px) 100vw, 620px\" \/><\/a><\/p>\n<p><strong>tl;dr:<\/strong> It&#8217;s basically a convention to write your commit messages in a structured way such that can then be easily parsed by a program into a change log. Like..<\/p>\n<ul>\n<li><strong>chore()<\/strong>:\n<p>&#8211;<\/p>\n<p>for housekeeping stuff<\/li>\n<li><strong>fix()<\/strong>:\n<p>&#8211;<\/p>\n<p>when fixing a bug<\/li>\n<li><strong>feat()<\/strong>:\n<p>&#8211;<\/p>\n<p>when adding a new feature<\/li>\n<li>&#8230;<\/li>\n<\/ul>\n<p>Examples:<\/p>\n<pre class=\" brush:php\">feat(core): add undo\/redo functionality\r\n\r\nIt is now possible to undo\/redo changes applied to the model. Simply invoke...<\/pre>\n<p>or a breaking change<\/p>\n<pre class=\" brush:php\">feat(..): bla bla\r\n\r\nbla bla\r\n\r\nBREAKING CHANGE:\r\nThis is a breaking change. Before you did... now you have to ....<\/pre>\n<p>Takes a bit of time to get accustomed, but once you have it, you get nicely readable commit messages.<\/p>\n<blockquote><p>You know about <a href=\"\/blog\/2013\/04\/git-explained\/#Polishingyourfeaturebranchcommits\">how to polish your git commit messages, don&#8217;t you?<\/a><\/p><\/blockquote>\n<h2>Love it! Show me how to get it for my lib!<\/h2>\n<p>Ok, glad you&#8217;re interested. Let&#8217;s get started.<\/p>\n<h3>Get your build scripts ready<\/h3>\n<p>You might use different tools for building your project: grunt, gulp, webpack or even just npm. I&#8217;ve found that the most convenient way is to hook your scripts directly into the <code>package.json<\/code> file s.t. Travis (we&#8217;ll see later) can invoke them simply by using npm.<\/p>\n<p>Assume you use <code>grunt<\/code> and your build command is <code>grunt build<\/code>. Then open your <code>package.json<\/code> and add a &#8220;scripts&#8221; section if there isn&#8217;t one already.<\/p>\n<pre class=\" brush:php\">...\r\n\"scripts\": {\r\n  \"build\": \"grunt build\",\r\n  \"test\": \"grunt karma:ci\",\r\n    ...\r\n},\r\n...<\/pre>\n<p>You can now run your build also through npm itself using <code>npm run build<\/code> or <code>npm run test<\/code>. This is required for later hooking everything up with Travis. Moreover it is nice as you can easily change your build and test commands from within this single file.<\/p>\n<h3>Setup Travis<\/h3>\n<p><a href=\"https:\/\/travis-ci.org\/\">Travis<\/a> is <strong>the<\/strong> continuous integration server for GitHub based projects. It has quite good docs, so you should find everything you need to get started. For JavaScript based projects start here: <a href=\"http:\/\/docs.travis-ci.com\/user\/languages\/javascript-with-nodejs\/\">http:\/\/docs.travis-ci.com\/user\/languages\/javascript-with-nodejs\/<\/a>.<\/p>\n<p>What it&#8217;ll ask you is to create a &#8220;.travis.yml&#8221; file. Here&#8217;s an example:<\/p>\n<pre class=\" brush:php\">sudo: false\r\nlanguage: node_js\r\ncache:\r\n  directories:\r\n    - node_modules\r\nbranches:\r\n  only:\r\n    - master\r\nnotifications:\r\n  email: false\r\nnode_js:\r\n  - '4.1'\r\nbefore_install:\r\n  - npm i -g npm@^2.0.0\r\n  - npm install -g grunt\r\n  - npm install -g bower\r\n  - npm install\r\n  - bower install\r\n...<\/pre>\n<p>The important things to grasp here are:<\/p>\n<ul>\n<li><code>branches:<\/code> this setting makes sure that only pushes to the master are being build. You can also blacklist your branches, just have a look at the official docs. Note, <em>PR<\/em> will be build anyway, so you don&#8217;t loose that comfort.<\/li>\n<li><code>before_script:<\/code> a series of commands to run before Travis starts building your project. In this section here you have to make sure you setup the build environment, like installing tools such as Grunt, Gulp or whatever you need.<\/li>\n<\/ul>\n<p>Moreover for Travis to work properly, you have to add the <code>prepublish<\/code> hook point.<\/p>\n<pre class=\" brush:php\">...\r\n\"scripts\": {\r\n  \"build\": \"grunt build\",\r\n  \"test\": \"grunt karma:ci\",\r\n  \"prepublish\": \"npm run build\",\r\n    ...\r\n},\r\n...<\/pre>\n<h3>semantic-release to the help<\/h3>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/semanticrelease.png\"><img decoding=\"async\" class=\"aligncenter wp-image-7834\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/semanticrelease.png\" alt=\"semanticrelease\" width=\"860\" height=\"339\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/semanticrelease.png 988w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/semanticrelease-300x118.png 300w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Finally, <a href=\"https:\/\/github.com\/semantic-release\/semantic-release\">semantic-release<\/a>. This is an awesome library that automates<\/p>\n<ul>\n<li>the determining of the correct semantic version based on your commits<\/li>\n<li>creation of a GitHub release (including setting the tag to the correct version, generating a changelog)<\/li>\n<li>release on npm<\/li>\n<li><em>&#8230; (more plugins on the way) &#8230;<\/em><\/li>\n<\/ul>\n<p>Just go to the <a href=\"https:\/\/github.com\/semantic-release\/semantic-release\">main repository<\/a>. There are a couple of introductory videos, linked articles and obviously all of the instructions on how to get it up and running.<\/p>\n<p>In the end, what you need to do is to <strong>run the semantic-release cli<\/strong> which will do the job of authorizing Travis to publish to your GitHub and npm repo and to properly setup your <code>package.json<\/code> file. It&#8217;ll also add a <code>semantic-release<\/code> step in the <code>scripts<\/code> section of the <code>package.json<\/code>.<\/p>\n<pre class=\" brush:php\">...\r\n\"scripts\": {\r\n  \"build\": \"grunt build\",\r\n  \"test\": \"grunt karma:ci\",\r\n  \"prepublish\": \"npm run build\",\r\n  \"semantic-release\": \"semantic-release pre &amp;&amp; npm publish &amp;&amp; semantic-release post\"\r\n},\r\n...<\/pre>\n<h3>Bower support<\/h3>\n<p>When you succeed to setup the before mentioned setups, you should now have<\/p>\n<ul>\n<li>automated build by Travis<\/li>\n<li>automated release on GitHub<\/li>\n<li>automated releases on npm<\/li>\n<\/ul>\n<p>The last step that&#8217;s missing is to release on Bower (if you want to support that). To be honest, the fame of Bower is decreasing. People are favouring npm as most probably they&#8217;re already using it anyway for some NodeJS based backend or at least for the tooling. Nevertheless, Bower is still a reality and people <a href=\"https:\/\/github.com\/openlayers\/ol3\/issues\/3119\">are demanding for it<\/a>.<\/p>\n<p>The problem is that Bower is not so easy to setup as NPM. It doesn&#8217;t allow to publish your binaries to a registry, but rather it works directly off your git repository.<br \/>\nBower requires you to<\/p>\n<ol>\n<li>have a <code>bower.json<\/code> file (just like <code>package.json<\/code>)<\/li>\n<li>create a semantic git tag on the repository<\/li>\n<li>publish your built-files to your repository.<\/li>\n<\/ol>\n<p>Point 1 and 2 shouldn&#8217;t be that hard to satisfy. Creating a <code>bower.json<\/code> is as simple as invoking <code>bower init<\/code> and semantic-release will take care of creating the correct git tag.<\/p>\n<p>The critical point is to push the built-files, that is, your compiled and minified JavaScript code, CSS etc., to the repository. Why&#8217;s that? Well, first of all, having generated files on master is a mess, with PR, commits and much more. Kent C. Dodds recently published a nice article on <a href=\"https:\/\/medium.com\/@kentcdodds\/why-i-don-t-commit-generated-files-to-master-a4d76382564\">why he doesn&#8217;t commit generated files to master any more<\/a>.<\/p>\n<p>What would have to happen is the following:<\/p>\n<ol>\n<li>You push a new release on master<\/li>\n<li>Travis starts building<\/li>\n<li>Travis generates the build files<\/li>\n<li>Semantic release creates a proper tag<\/li>\n<li>Travis pushes back to master with the new dist files<\/li>\n<li>(that would trigger another Travis build?..)<\/li>\n<\/ol>\n<p>It&#8217;s a mess. Mostly I don&#8217;t like the idea of having an automated machine push to master. Kent C. Dodds <a href=\"https:\/\/github.com\/semantic-release\/semantic-release\/issues\/75\">had the same issue<\/a> and decided to solve and automate it: <a href=\"https:\/\/www.npmjs.com\/package\/publish-release\">publish-release<\/a><\/p>\n<p>Install the library and add it as <code>postpublish<\/code> task in the <code>package.json<\/code> file:<\/p>\n<pre class=\" brush:php\">...\r\n\"scripts\": {\r\n  \"build\": \"grunt build\",\r\n  \"prepublish\": \"npm run build\",\r\n  \"postpublish\": \"publish-latest\",\r\n  \"test\": \"grunt karma:ci\",\r\n  \"semantic-release\": \"semantic-release pre &amp;&amp; npm publish &amp;&amp; semantic-release post\"\r\n},\r\n...<\/pre>\n<p>He has an interesting solution: <code>publish-latest<\/code> creates (if it doesn&#8217;t exist) a new <code>latest<\/code> branch where the distribution files will be placed (usually in a <code>dist<\/code> folder). That branch will be tagged by semantic-release and then <code>publish-latest<\/code> pushes that branch back to your GitHub repo. Hence, you&#8217;ll end up having your <code>master<\/code> clean with just the source code and a <code>latest<\/code> branch containing the latest, compiled and minified files to be distributed. Since the tag is on that branch, Bower will also find it easily and your users will be able to install it from there without any issues.<\/p>\n<h2>Conclusion<\/h2>\n<p>You know what&#8217;s best of all this. Whenever now someone sends you a PR, Travis executes the tests against the new contribution, does all the checks you&#8217;ve setup (linting whatever..) and if everything is fine, you are <strong>1 click away from merging and releasing a new version with the new contribution<\/strong>.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/githubmerge.png\"><img decoding=\"async\" class=\"aligncenter size-large wp-image-7835\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/githubmerge-1024x178.png\" alt=\"githubmerge\" width=\"620\" height=\"108\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/githubmerge-1024x178.png 1024w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/githubmerge-300x52.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/10\/githubmerge.png 1600w\" sizes=\"(max-width: 620px) 100vw, 620px\" \/><\/a><\/p>\n<p>Here are some of my repositories where I&#8217;ve already set this up, as well as others which you can use as an example to get started.<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Swimlane\/angular-model-factory\">angular-model-factory<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/juristr\/angular-translate-loader-pluggable\">angular-translate-loader-pluggable<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/tombatossals\/angular-openlayers-directive\">angular-openlayers-directive<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/formly-js\/angular-formly\">angular-formly<\/a><\/li>\n<li><em>feel free to let me know about others<\/em><\/li>\n<\/ul>\n<p>Besides the article I mentioned above, <a href=\"https:\/\/twitter.com\/kentcdodds\">Kent C. Dodds<\/a> has done a lot of research on how to best create an Open Source JavaScript library and shares his knowledge <a href=\"https:\/\/egghead.io\/series\/how-to-write-an-open-source-javascript-library\">in this series of Egghead.io videos<\/a>. Definitely worth watching (I&#8217;ve not done it yet&#8230; <img decoding=\"async\" title=\":flushed:\" src=\"https:\/\/assets.github.com\/images\/icons\/emoji\/unicode\/1f633.png\" alt=\"\" width=\"20\" height=\"20\" align=\"absmiddle\" \/>).<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/juristr.com\/blog\/2015\/10\/release-like-a-pro\/\">Release your libs like a pro<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/wcg\/\">WCG partner<\/a> Juri Strumpflohner at the <a href=\"http:\/\/juristr.com\/blog\/\">Juri Strumpflohner&#8217;s TechBlog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Automate, automate, automate. That&#8217;s what ultimately is our job, right? We automate the tedious processes of our end-users. So why don&#8217;t we do it for ourselves as well? This guide quickly illustrates how to setup fully automated releases to Bower and NPM. And they&#8217;re even automatically semantic versioned. Bower, NPM, semantic versioning?? Sounds strange? Check &hellip;<\/p>\n","protected":false},"author":5,"featured_media":929,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[36],"class_list":["post-7804","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-npm"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Release your libs like a pro - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Automate, automate, automate. That&#039;s what ultimately is our job, right? We automate the tedious processes of our end-users. So why don&#039;t we do it for\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Release your libs like a pro - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Automate, automate, automate. That&#039;s what ultimately is our job, right? We automate the tedious processes of our end-users. So why don&#039;t we do it for\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-10-16T09:15:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Juri Strumpflohner\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/juristr\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Juri Strumpflohner\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/\"},\"author\":{\"name\":\"Juri Strumpflohner\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/33d3ee7edb105a80f1ff7199925b3060\"},\"headline\":\"Release your libs like a pro\",\"datePublished\":\"2015-10-16T09:15:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/\"},\"wordCount\":1798,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg\",\"keywords\":[\"NPM\"],\"articleSection\":[\"Web Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/\",\"name\":\"Release your libs like a pro - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg\",\"datePublished\":\"2015-10-16T09:15:34+00:00\",\"description\":\"Automate, automate, automate. That's what ultimately is our job, right? We automate the tedious processes of our end-users. So why don't we do it for\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Dev\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/web-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Release your libs like a pro\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/33d3ee7edb105a80f1ff7199925b3060\",\"name\":\"Juri Strumpflohner\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/45338315375849845e4c4b30f52cb417221e2d9a7e688785e4dd2af0e624a260?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/45338315375849845e4c4b30f52cb417221e2d9a7e688785e4dd2af0e624a260?s=96&d=mm&r=g\",\"caption\":\"Juri Strumpflohner\"},\"description\":\"Juri Strumpflohner mainly operates in the web sector developing rich applications with HTML5 and JavaScript. Beside having a Java background and developing Android applications he currently works as a software architect in the e-government sector. When he\u2019s not coding or blogging about his newest discoveries, he is practicing Yoseikan Budo where he owns a 2nd DAN.\",\"sameAs\":[\"http:\/\/juristr.com\/blog\/\",\"http:\/\/linkedin.com\/in\/juristr\/\",\"https:\/\/x.com\/http:\/\/twitter.com\/juristr\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/juri-strumpflohner\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Release your libs like a pro - Web Code Geeks - 2026","description":"Automate, automate, automate. That's what ultimately is our job, right? We automate the tedious processes of our end-users. So why don't we do it for","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/","og_locale":"en_US","og_type":"article","og_title":"Release your libs like a pro - Web Code Geeks - 2026","og_description":"Automate, automate, automate. That's what ultimately is our job, right? We automate the tedious processes of our end-users. So why don't we do it for","og_url":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2015-10-16T09:15:34+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg","type":"image\/jpeg"}],"author":"Juri Strumpflohner","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/juristr","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Juri Strumpflohner","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/"},"author":{"name":"Juri Strumpflohner","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/33d3ee7edb105a80f1ff7199925b3060"},"headline":"Release your libs like a pro","datePublished":"2015-10-16T09:15:34+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/"},"wordCount":1798,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg","keywords":["NPM"],"articleSection":["Web Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/","url":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/","name":"Release your libs like a pro - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg","datePublished":"2015-10-16T09:15:34+00:00","description":"Automate, automate, automate. That's what ultimately is our job, right? We automate the tedious processes of our end-users. So why don't we do it for","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/npm-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/web-development\/release-libs-like-pro\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Web Dev","item":"https:\/\/www.webcodegeeks.com\/category\/web-development\/"},{"@type":"ListItem","position":3,"name":"Release your libs like a pro"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/33d3ee7edb105a80f1ff7199925b3060","name":"Juri Strumpflohner","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/45338315375849845e4c4b30f52cb417221e2d9a7e688785e4dd2af0e624a260?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/45338315375849845e4c4b30f52cb417221e2d9a7e688785e4dd2af0e624a260?s=96&d=mm&r=g","caption":"Juri Strumpflohner"},"description":"Juri Strumpflohner mainly operates in the web sector developing rich applications with HTML5 and JavaScript. Beside having a Java background and developing Android applications he currently works as a software architect in the e-government sector. When he\u2019s not coding or blogging about his newest discoveries, he is practicing Yoseikan Budo where he owns a 2nd DAN.","sameAs":["http:\/\/juristr.com\/blog\/","http:\/\/linkedin.com\/in\/juristr\/","https:\/\/x.com\/http:\/\/twitter.com\/juristr"],"url":"https:\/\/www.webcodegeeks.com\/author\/juri-strumpflohner\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/7804","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=7804"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/7804\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/929"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=7804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=7804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=7804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}