DEV Community

Cover image for Publishing a React Hooks Library using Typescript and TSDX
Julian Garamendy
Julian Garamendy

Posted on • Edited on • Originally published at juliangaramendy.dev

Publishing a React Hooks Library using Typescript and TSDX

I started my personal hooks library and decided to publish it as an npm package. Doing this in TypeScript was not straightforward, until: palmerhq/tsdx.

Here's what I did. Step by step.

Step 1: Creating the project

$ npx tsdx create bananahooks
Enter fullscreen mode Exit fullscreen mode

The command is interactive and asks you to choose a template.

? Choose a template …
  basic
❯ react
Enter fullscreen mode Exit fullscreen mode

I selected the react template, and TSDX installed everything for me.

✔ Choose a template · react
✔ Created bananahooks
✔ Installed dependecines

  Awesome! You're now ready to start coding.

  I already ran yarn install for you, so your next steps are:
    cd bananahooks

  To start developing (rebuilds on changes):
    yarn start

  To build for production:
    yarn build

  To test your library with Jest:
    yarn test

  Questions? Feedback? Please let me know!
  https://github.com/jaredpalmer/tsdx/issues
Enter fullscreen mode Exit fullscreen mode

Step 2: Adding code and tests

TSDX generates an index.tsx file a test file, and an example folder.

I deleted the example folder, added my own code and tests.

bananahooks                      bananahooks
└─ examples                      └─ src
└─ src                              └─ index.tsx
   └─ index.tsx                     └─ use-promise.tsx
└─ test                          └─ test
   └─ blah.test.tsx     ==>         └─ use-promise.test.tsx
└─ .gitignore                    └─ .gitignore
└─ package.json                  └─ package.json
└─ README.md                     └─ README.md
└─ tsconfig.json                 └─ tsconfig.json
└─ yarn.lock                     └─ yarn.lock
Enter fullscreen mode Exit fullscreen mode

Because my library consists of only functions, I decided to delete the example folder, and I relied on tests instead. You can see how I test my custom hook in use-promise.test.tsx. I'm using react-testing-library.

Step 4: Testing the package locally

To make sure my package would work as expected I imported it to a new React project:

yarn add ../path/to/bananahooks
Enter fullscreen mode Exit fullscreen mode

But there was a problem!

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
Enter fullscreen mode Exit fullscreen mode

There's a known issue when installing local packages with yarn or npm. Everything is copied to the project's node_modules folder instead of just the files that would eventually be packaged. This means there's now two node_modules and therefore, two copies of React. It doesn't matter if it's the exact same version.

The workaround is to yarn remove bananahooks, then delete the node_modules folder from the library project, then run yarn add ../path/to/bananahooks again. It's annoying.

Step 5: Publishing to NPM

TSDX generated a package.json file with my package name: bananahooks, but I had to add the author, license and repository keys to it:

  "author": {
    "name": "Julian Garamendy",
    "email": "me@juliangaramendy.dev",
    "url": "https://juliangaramendy.dev"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/JulianG/hooks"
  },
  "license": "MIT",
Enter fullscreen mode Exit fullscreen mode

I ran the npm pack command which generates a .tgz file with the package that would be uploaded to the registry. I find this useful to inspect and make sure I'm including the right files. The .tgz file can be deleted afterwards; it's not needed for publishing.

Then I ran npm publish and (because I'm already logged in to npm) my package was uploaded and added to the registry.

I can later increase the version number either by manually editing the package.json file or by running npm version.

Conclusion

TSDX makes creating TypeScript libraries really easy. I'll sure be using it a lot in the future.

You can see my hooks repository on GitHub, and the published bananahooks package on NPM.

I hope this was useful.

Top comments (6)

Collapse
 
devhammed profile image
Hammed Oyedele

I will prefer to use create-react-hook instead because it will setup an example folder that you can deploy to GitHub pages. I once use it for a React hook for manipulating browser cookies.

GitHub logo devhammed / use-cookie

Get, Set, Update and Delete Cookie using React Hooks.

@devhammed/use-cookie

Get, Set, Update and Delete Cookie using React Hooks.

NPM JavaScript Style Guide

Install

npm install --save @devhammed/use-cookie

Usage

import React from 'react'
import ReactDOM from 'react-dom'
import useCookie from '@devhammed/use-cookie'
const App = () => {
  const [username, setUsername, deleteUsername] = useCookie('username', 'User')
  return (
    <section&gt
      <h1>Hello {username}!</h1&gt
      <p>Edit below input, Your name will be stored in a cookie. you can refresh this page to see how it persists.</p&gt
      <input
        type='text'
        value={username}
        onChange={(e) => setUsername(e.target.value)}
      />
      <button
        onClick={() => deleteUsername()}
      >
        Delete Cookie
      </button>
    </section>
  )
}

ReactDOM.render(<App />, 

GitHub logo Hermanya / create-react-hook

🎣CLI for easily creating reusable react hooks.

create-react-hook

CLI for creating reusable React hooks using Rollup and create-react-app Inspired by the amazing create-react-library

NPM Build Status JavaScript Style Guide

How and why I made this tool.

Features

  • Easy-to-use CLI
  • Handles all modern JS features
  • Bundles cjs and es module formats
  • create-react-app for example usage and local dev
  • Rollup for bundling
  • Babel for transpiling
  • Jest for testing
  • Supports complicated peer-dependencies
  • Optional support for TypeScript
  • Sourcemap creation

Install

This package requires node >= 4, but we recommend node >= 8.

npm install -g create-react-hook

Creating a New Hook

create-react-hook

Answer some basic prompts about your module, and then the CLI will perform the following steps:

  • copy over the template
  • install dependencies via yarn or npm
  • link packages together for local development
  • initialize local git repo

Development

Local development is broken into two parts (ideally using two tabs).

First, run rollup to watch your src/ module and automatically recompile it into dist/ whenever you…

Collapse
 
juliang profile image
Julian Garamendy

Awesome! I didn't know create-react-hook. Thank you!

Collapse
 
petyosi profile image
Petyo Ivanov

Had the same issue while developing react-virtuoso with tsdx. Came up with a very crude hack, described in this issue.

Ultimately, however, I switched to storybook - it lives inside the project directory and works with the same React instance.

Collapse
 
juliang profile image
Julian Garamendy • Edited

Thank you! I can't believe I haven't tried storybook yet.

Collapse
 
mlaopane profile image
Mickaël

Thanks for the article.

I'm dealing with the same issue except it happens even when publicly deployed on npm.

I've been using Parcel but I may give a try to create-react-hook instead

Collapse
 
scriptkavi profile image
ScriptKavi

You can also use scriptkavi/hooks

It is easy to use and pattern is similar to shadcn/ui.