Gradually using TypeScript in Your React Project

How to safely build and introduce React TypeScript components into your React JS project

Why would you want to migrate from JS to TS? There can be an infinite amount of reasons but that’s not the point. The (hypothetical) fact is: you need to start using TypeScript and you need an easy way to introduce it into your project. Not only that but you have to do it without breaking your already working code and somehow convincing the rest of your team.

Here we will show a gradual refactoring approach: Build React TS components in another codebase, then use Bit to safely introduce them into your already-working React JavaScript application.

Safely introducing TS components into a JS project with Bit

*

There are many ways to make the transition from React JS to React TS. The point of this article is to show how you can do this migration gradually. The same method works in other use cases too.

The basic idea is to leverage React’s components + Bit’s ability to isolate each of them in its own dev environment. Together, this lets us build TS components and safely introduce them into a fully-working React JS app.

Bit is an open-source tool for decoupling components from Git repositories. Using Bit you can build TS components outside of your JS project, while giving each a standalone isolated dev environment that can run in other projects regardless of its configurations. Then you can simply version and “bit import” these components into the JS project- and they will work.

Alongside Bit there’s Bit.dev- a remote component hub where you can host these components for future reuse. In Bit.dev we will host the TS components, and from there we will introduce them into the React JS project.

Example: searching for shared React components in bit.dev

The use case

For the purpose of this article, let’s go with the “hello world” of front-end development: a To-Do app.

Don’t worry, I’m not going to tell you how to write a To-Do app with React, I’m assuming you already know how to do that and let’s be honest, I’m really late to that party, so no.

Instead, I’m going to be using this app as an example, so feel free to fork it or at least open up the link to review the full code.

The components in the codebase are:

TodoList: This is the main component, which is rendered in the form of a text input field and a simple button. Everything inside a form, which once submitted adds the text to a list maintained by the main app. The code for this component is very simple:

TodoItems: A very basic list-component used to render the internal list of items added using the previous component. Each item can be clicked and once clicked, it’ll be removed from the list. The code is also, quite simple:

In both cases, the relevant methods are received as Props from the main App component. You can see the full code of that component over here.

The app is very basic, I give you that, but then again, the point here is that this could potentially be any React app that you might be working on and suddenly, you get the task of start migrating it to TypeScript, what do you do?

Option #1: After wiping out your tears, you set out to the task of re-writing your entire source code.

Option #2: You rename all your .js file into .ts and set up the proper steps on your build process and call it a day.

Option #3: You actually decide to start progressively migrating the old code while writing all new code in TypeScript directly.

I want to explore option #3, essentially allowing you to have both pure JavaScript and TypeScripts components coexisting in the same app.

Enter TypeScript

So, for the sake of providing an example, let’s pretend you’re tasked to adding a toggle button to each item on your To-Do list. Once clicked, the background of the item needs to be toggled.

Nothing too fancy, but remember, the focus here is the process, not the actual code.

So instead of trying to add TypeScript to your already existing project setup and, potentially, break your build for a couple of days, we’ll create a brand new project directly using TypeScript:

Note that in order to use npx you only need a recent version of NPM, it’s been included as part of the installation process since version 5.2.0.

Just like before, this will create a template project, although this time, using TypeScript as a base language.

And a simple toggle component that’s meant to be inserted into a different project, without bringing extra dependencies to the table. If you’re curious about doing just that, please check out: how to write reusable components.

Now, with that component written, we can use Bit (which is an open-source tool for versioning and publishing individual components) to individually extract and share that component so that we can import it later on from our JavaScript-based project.

// install Bit & initialize a workspace in the project's directory

$ yarn global add bit-bin

$ bit init --package-manager yarn // login (after creating an account and collection in bit.dev)

$ bit login // add all components

$ bit add src/components/Toggle.tsx // configure a compiler (to decouple the components from your env)

$ bit import bit.envs/compilers/react-typescript --compiler // tag & export

$ bit tag --all

With that, you’ve configured your project and you’ve set up the new Toggle component to be shared, but before you can actually do so, you need to log-in to Bit.dev (which is a component hub — a registry and a documentation site that compliments Bit by providing a place to publish and preview the components).

Once logged in, just create a new collection called “toggler”, make sure it’s public and then, from your terminal window, run the following command:

$ bit export user-name.toggler

With “user-name” being your actual username, this will export the component and you should be able to see it on Bit.dev. It should look somewhat similar to this:

Notice how by default, the platform creates a sample index.js file to test the component. That being said, the default content for it might not be ideal, however, the platform allows you to easily add extra code which can help others understand how to use your public component in their code.

For instance, here I updated my own sample file to explain how to use the Toggler component (just remember to hit the “Save” button after you’re done!):

Let’s now take a look at how to import this new component into your own, JS-based React app.

Importing external component

Bit takes care of compiling your TypeScript code into JavaScript thanks to the compiler we’ve added. This solves all your problems, all that’s left for you to do is to add the component into your project as a dependency.

I’ve been using Yarn for everything here, but you could potentially be using NPM just as easily, all you need to do is:

$ yarn add @bit/your-username.your-collection.your-component

In my case, that translates to:

$ yarn add @bit/deleteman.toggler.toggle

Notice you will not be able to install components if you're not logged in (remember the $ bit login part of our tutorial?). If you’d like to install components from Bit’s registry without logging in, you would need to configure the registry manually like so:

$ npm config set '@bit:registry' https://node.bit.dev

This will include your TypeScript (now compiled into JavaScript) component which you can the reference from your code as follows:

Notice line 2, that’s where I’m importing the external component which I’m using as part of the return statement. Nothing complicated, no need for extra configuration changes on your project or anything.

Congrats, you now have a working project using both, TypeScript and JavaScript, potentially without you even knowing about it!

As I’ve said before, you can read the full code on GitHub!

Conclusion

If you’re interested in migrating to TypeScript or if you’re interested in starting to dabble with it and see if it works for you, this way of gradually introducing the language into an existing project without the risk of breaking all the build process is perfect.

Give Bit a look and check out Bit.dev for more components written both, in JavaScript and TypeScript to understand how others do it as well!

Leave a comment below if you have another way of integrating TypeScript into your JS-based projects without affecting it and your entire team.

See you at the next one!

Learn More