Introduction
We announced about a month ago that we revived our Google Chrome extension project and made some major improvements—user interface makeover, React migration, Firefox support, and going open source. It’s a great start, but we don’t stop there.
New changes
Since the announcement, we’ve implemented bug fixes and further codebase improvements. The asset metadata (i.e., asset ID, whether to save cookies and/or to bypass asset verification) that’s being persisted client-side isn’t being wiped out anymore when the user signs out. New assets are now being persisted in local storage properly. We also fixed the issue where the browser extension shows that it’s an existing asset even though that asset was removed via the Screenly web interface or via the REST API. To summarize, we applied fixes related to synchronizing browser storage with Screenly.
Regarding open source, we’ve now added a prerequisites section in the documentation so that users and potential contributors can get started with less hassle. We also added documentation on how developers can start making contributions to the project. Some parts of the new contribution docs were already in the main README, but having separate documentation for that makes it clearer.
We also migrated the codebase to TypeScript, which we’ll elaborate on in the next section.
Why migrate to TypeScript?
Our decision to migrate to TypeScript wasn’t easy or straightforward. We researched other developers’ stories about migrating to TypeScript, reverting to JavaScript, and other approaches. There’s no silver bullet for every problem. Every approach has its own benefits and trade-offs.
When we first migrated to TypeScript, we used any
everywhere. While this is a neat feature that TypeScript offers (to allow a smooth transition from JavaScript), it’s not a good practice as it defeats the purpose of moving to a strongly-typed programming language.
Introducing type systems in the project has its pros and cons. With typing, it becomes easier to debug code. It also acts as documentation, alongside code comments. To justify this statement, we’ll demonstrate code snippets from our project. Here’s what our function createWebAsset
looks like before TypeScript:
export function createWebAsset(user, url, title, headers, disableVerification) {
// callApi is a wrapper function that we wrote for window.fetch
return callApi(
'POST',
'https://api.screenlyapp.com/api/v4/assets/',
{
'source_url': url,
'title': title,
'headers': headers,
'disable_verification': disableVerification,
},
user.token
);
}
For contributors new to the project, it would be quite hard to identify what arguments to pass. Take the user
parameter for instance. At first glance, it looks like data needs to be a JavaScript object, but it’s not particular about what attributes to include. We can get away with debugging it by temporarily putting console.log statements all over the place but it can be tiresome especially when things get quite complicated.
This is where TypeScript can be useful. Here’s what the createWebAsset
function looks like right now:
export function createWebAsset(
user: User,
url: string,
title: string,
headers: object | null,
disableVerification: boolean,
) {
// callApi is a wrapper function that we wrote for window.fetch
return callApi(
'POST',
'https://api.screenlyapp.com/api/v4/assets/',
{
source_url: url,
title: title,
headers: headers,
disable_verification: disableVerification,
},
user.token,
);
}
As seen on the snippet, user
should be of User
type. Here’s how the User
type is defined:
export interface User {
token: string;
}
This means that we should pass to createWebAsset
a TypeScript object with a property named token
, which should be a string
. Developers won’t have to guess what kind of arguments to pass or rely on console.log
statements.
With these improvements, TypeScript can detect errors that JavaScript might miss.
When not to use TypeScript?
Initially, our browser extension project was written in JavaScript. As the codebase grew larger, it became less readable and more prone to bugs that could have been caught earlier.
As mentioned earlier, TypeScript is not a “one size fits all” solution. It requires a learning curve, especially for developers who are used to JavaScript’s flexibility. There can be cases where TypeScript’s strictness might hinder rapid prototyping or experimentation. The tooling and ecosystem around TypeScript are still evolving, and there might be compatibility issues with certain libraries or frameworks.
What’s next?
The project remains open source, so we encourage everyone to contribute. If you find a bug, feel free to create an issue. Additionally, if you discover something that can be added or enhanced—whether it’s an internal change, a minor user interface fix, or a documentation update—feel free to open a pull request.