Probot 7.0: Moving to TypeScript to Help the Developer Experience

Migrating a NodeJS Framework to TypeScript with the help of our community

Tommy Byrd
Probot
6 min readJun 29, 2018

--

👋 🤖 We have some big news for this release! The Probot core library has been rewritten in TypeScript to help improve the experience of writing GitHub Apps in NodeJS. You can continue writing your apps in JavaScript, but by adding types you can get some nice improvements. If you haven’t used a typed language before, to put it into GIF form, it can take your development experience from this:

No type declarations, lots of time switching between documentation and your IDE, manually typing methods and parameters

To this:

Intellisense with inline documentation and autocomplete

Along with this change, we’ve added a new —-typescript option to create-probot-app that will generate a new starter project in TypeScript. We’ve also updated the normal template so you can get the benefits of type hints in your IDE even without having to write your app in TypeScript! This is done by using a nice little feature that allows you to use JSDoc style comments to import the TypeScript types:

Read our documentation to get started building your own Probot App, or check out the existing Apps you can install on your repositories right now!

Read on to learn more about why we made this change…

The Backstory

Since Probot launched over 2 years ago, we’ve learned a lot about how people are building Apps and custom workflows for their projects on GitHub. There are dozens of apps featured on our website, over 100 repositories in the Topic on GitHub, and almost 500 projects that list Probot as a dependency. Some are simple yet incredibly useful, like WIP. Others manage their community with the help of Probot, like Apollo and Angular. At GitHub, we’ve even built a couple of new products using Probot! The new Slack integration and Learning Lab are both running Probot under the hood to make it easier for these external systems to interact with GitHub.

As the Probot library has evolved, so too has the GitHub API. Even with the launch of GraphQL, new REST endpoints are added all the time. Almost every new feature of GitHub gets an API, so knowing what endpoints you can use, what parameters they take, and the types of those parameters can be a challenge. Also, we ❤️ modern JavaScript. Since Probot makes heavy use of network calls to GitHub, using async/await syntax makes writing GitHub Apps so much cleaner. Most Probot apps are deployed to services like Heroku, Glitch, and Zeit’s Now.sh, and we’ve been successfully running dozens of apps on these services without introducing any kind of build tooling.

Last summer a few of us in the Probot community started to experiment with serverless deployment options. Apps like WIP, TODO, and others are written to be stateless functions that listen for a webhook event, process that event (sometimes using other 3rd party services), and return a response to GitHub. These kinds of apps are perfect candidates for Functions-as-a-Service solutions like AWS Lambda and Google Cloud Functions, but neither of those were able to use all the modern syntax we were writing! After experimenting with a solution using Webpack and talking to some members of the community (shout out to @ocombe), we realized we could solve this problem using TypeScript and improve the experience for writing GitHub Apps in regular JavaScript at the same time.

Using TypeScript to Compile to ES5

One of the more powerful things about TypeScript is that it treats different versions of JavaScript as a compile target, similar to how compiled languages can target different Operating Systems. With one change to a compiler option, you could turn on support for ES3, or deprecate older versions and target ES2017. In the client-side JavaScript world, this is a huge benefit for being able to write modern syntax that targets older browsers. This typically isn’t an issue on a server where you have control over the NodeJS runtime, but on a FaaS provider you don’t have this kind of control. AWS Lambda just recently updated to Node 8.10, but other providers are still on the 6.x release. It will probably be another year or so before you can use Node 10 in Lambda, and by then we’ll probably want to use features in Node 12. TypeScript helps with this by allowing developers to write in a more modern syntax if they want while continuing to support older runtimes using compilation targets. TypeScript tends to track Stage-3 proposals for decisions on new features to add to the language, so this means you can start using features of JavaScript that aren’t even in the standard yet while knowing that your code will still work on older runtimes.

The Next Challenge

TypeScript seemed like a great solution, but we had another problem. None of the core maintainers for Probot knew TypeScript very well! The next challenge, then, was to dive in and type all the things…

Me when I discovered types in JavaScript

A few of us had experimented with TypeScript but were not well versed enough to tackle the project alone. After some discussions with the community about moving forward with this, we decided to open a Pull Request and see where it went.

More than just renaming index.js to index.ts

Since all valid JavaScript is also valid TypeScript, you can technically just rename your files from *.js to *.ts to start compiling to JavaScript, but to get the benefits of the type system and help improve and refactor your code, there are a few more steps involved. Luckily, shortly after we opened that PR, members of the Probot community started submitting their own contributions and reviewing the types the maintainers were adding. For details on the exact steps, just follow along in our quite lengthy PR.

But TypeScript can help JavaScript developers as well! How does it do that? Enter declaration files. If you’ve seen any packages with files ending in *.d.ts, those are declaration files. They are what makes it possible to use types in libraries compiled to JavaScript. Over 6,400 developers have contributed type declarations to DefinitelyTyped, making it one of the largest repos on GitHub.

This is helpful for the developer experience, because with auto completion features that support fuzzy searches like IntelliSense in VS Code, when working with the GitHub API in Probot 7.0, you can now let your IDE guide you to the right method:

And not only will it tell you what types you need to provide for the various properties, but also which ones are optional (note the ? after “role”), and what kind of data is returned from that API call.

TS + JS = ❤️

This doesn’t mark the end of JavaScript for Probot, though. We still use it all the time in the Probot Apps we deploy. However, we have found that moving the core library to TypeScript has improved the quality of our code, made it easier to write apps that use the GitHub API, and allowed developers to deploy their apps to any platform, even if that platform doesn’t yet support the latest NodeJS runtime.

We’re still developing the best practices for writing Probot Apps in TypeScript and will be releasing several new templates over the coming weeks to make it even easier to get started building GitHub Apps for various tasks.

If you’d like to help with this, join the open source community or come work for us and do it full-time. We’re hiring for both teams that built products using Probot:

Ecosystem Integration Engineer — The ones who built slack.github.com Learning Engineer — The ones who built lab.github.com

--

--