Plug-in architecture: how TypeScript let us paint-by-numbers

Rate this content
Bookmark

Adding a new feature to an unfamiliar codebase can be painfully slow. What if you could lean on TypeScript to guide you?

At Snyk plugin architecture is a common pattern to extend language support across different products and codebases. Adding TypeScript to the mix has allowed us to add new features quickly and it can be as simple as painting by numbers when it comes to extending the code.

Join me as we create a simple library using plugin architecture and follow the trail of TypeScript hints to add a new feature. 

This talk has been presented at TypeScript Congress 2022, check out the latest edition of this Tech Conference.

FAQ

When Lilia started at Snyk, she faced the challenge of understanding every package manager, registry, and source control management system, a significant shift from her previous experience of leading a team building websites.

One of the first features Lilia worked on was adding support for npm6, which was significant as it introduced log files, adding a new aspect of npm into the platform.

The plugin architecture at Snyk consists of a core system and plugin modules that interact through a predefined interface. This structure allows for scalable and manageable support for various source control management systems and tools.

TypeScript plays a crucial role in Snyk's plugin architecture by providing a structured environment where plugin functionalities must conform to defined interfaces. This helps in tracking errors and implementing new functionalities efficiently.

Onboarding new team members at Snyk can be complex due to the intricate codebase. However, once the patterns in handling package managers are recognized, the process speeds up, although initially, it may take new members a few attempts to see these patterns.

Plugin architecture is crucial for efficiently extending product support at Snyk, as it allows the team to manage and update individual components without overhauling the entire system, especially when dealing with various tools and versions that may not be compatible with each other.

TypeScript offers benefits such as error tracking and enforcing type safety, which streamline the development process by clearly defining what each component of the system is responsible for, thus reducing the time to production and easing the onboarding process.

Lili Kastilio
Lili Kastilio
15 min
29 Apr, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

When faced with challenges in supporting multiple package managers and keeping up with growth, implementing a plugin architecture can help. Extending a CLI for source control management systems like GitHub and GitLab can be done using TypeScript and Oclef CLI. TypeScript errors can be resolved by adding missing properties and implementing required functions for plugins. Supporting multiple repositories by following TypeScript errors and having the right setup can reduce time to production and onboarding. Plugin architecture with TypeScript can be a valuable tool for faster development and onboarding onto repositories.

1. Introduction to Challenges and Plugin Architecture

Short description:

Hi. My name is Lilia and I'm an engineering manager at Snyk. When I started at Snyk, I had little understanding of the challenges ahead. We needed to support multiple package managers and keep up with our own growth. To speed up support, we implemented plugin architecture. With TypeScript, we could follow the trail of errors to help us.

Hi. My name is Lilia and I'm an engineering manager at Snyk leading the technical services team. When I started at Snyk about four years ago now, I had very little understanding of the challenges that would lie ahead of me. Having just led an engineering team building cookie cutter websites at a small agency, my expectations were that Snyk would be similar, but maybe more challenging. And I was certainly not prepared for having suddenly to understand every single package manager, like a registry and source control management system that has ever been built. And all this because I've joined the ecosystems team.

I remember one of the very first features was adding support for npm6. This is the first time that npm introduced log files. So this was adding a new flavor of npm into the platform. Then came Yarn, Yarn Workspaces, Gradle, Go, different flavors of Go, Kotlin, SPT, Cocoapods. It just seemed to be a never-ending stream of package managers and tools that needed to be supported. And sometimes the new versions were completely incompatible with the previous versions and required rewriting the support entirely from scratch.

Not only did we need to extend support and keep up with customers migrating to all of these different tools and versions, we also needed to keep up with our own growth. New team members are joining all the time, and onboarding onto the codebase can take some time, as it is complex. Once we've added support for the package manager once or twice, we kind of start seeing some patterns, and then you can speed up. However, as a new team member joins, they have to start from scratch, and then it takes them another 2 or 3 goes before they start seeing those same patterns as you. So we needed to think about how we can speed up. As some of the support was taking longer, sometimes certain areas of the product were being missed where support needed to be extended. So we needed to speed up, but we also needed to ensure that we were covering every area of the product where support needed to be extended. We needed plugin architecture.

Plugin architecture consists of two main components, the core system and the plugin modules themselves. And the plugins interact with the core system via a predefined interface. At the time we've had some of that in place, but not to the extent we wanted. With some time, we were able to start seeing what is the responsibility of the core system and what is the responsibility of the plugins. However, some of these behaviors can still be quite unclear. So you have a little bit of a challenge there as well. So as an opportunity presented itself to build a new library, using plugin architecture, we could use what we've learned from introducing TypeScript really early on into our application, as well as what we've learned and the bits and pieces that we liked and didn't like from our existing plugin architecture. And we could put all of our learnings together and create something new and try again. And we found that with some setup upfront, we could lean on TypeScript and follow the trail of TypeScript errors to help us. So let's have a look at an example to understand how you can follow the TypeScript errors as hints.

2. Extending CLI for Source Control Management

Short description:

We'll be extending a CLI called the Source Control Management Helper (SEM Helper) to work with different source control management systems like GitHub and GitLab. The CLI has a command called Describe GitHub, which provides simple information about a repository, such as whether it is forked or archived. The code is set up using TypeScript and Oclef CLI, with separate directories for commands and plugins. The describe GitHub command loads the GitHub plugin and calls its describe function. The plugin uses the OctoKit rest library to make API calls to GitHub. We also have an index and types file that allow us to support other SCMs like GitLab.

We'll be extending a CLI that provides some simple functionality relevant for working with different source control management systems, tools like GitHub and GitLab. So, let's dive in.

So our example today is a really simple CLI called the Source Control Management Helper. We're gonna call it SEM Helper for short. So let's have a look here and we essentially have a command called Describe and we're calling Describe GitHub and then it's expecting a couple of parameters, the owner and the repo. So we're trying to describe a repository. So if we give it some owner and repo as well, we're returning back just really simple pieces of information, whether the repository is forked and whether it's archived as well.

So if we have a look conceptually, we have essentially got a core system that is able to say, repo.describe for example. And then we have a set of plugins that can be called upon, in this case, it's GitHub specifically. And we returned some very simple metadata, for example, for true, archived, false. So let's jump into the code and have a look at what we have set up here.

So it is a really simple, basic, out of the box, follow the TypeScript documentation TypeScript set up. You'll see here that we have a source index and we're using Oclef CLI. So we don't have to worry about parsing of parameters or anything like that. You'll see that there is a command directory as well as a lib plugins directory. In the commands here, we have describe GitHub, which is what you have just seen running. And in describe GitHub, it's got some arguments, it's got an example, some description, and the main functionality here is it loads a plugin, loads a plugin GitHub, and then we're calling plugin dot describe and sending it the repository and on that. And that's it. And then in lib plugins, there is a GitHub directory in which there is a little bit of code, which is get credentials and then it describe API call itself as well. So we need to be able to grab the token and then we're calling in this case, OctoKit rest, which is a GitHub library and calling the specific repos get to get the information that we want. So let's have a look again inside the plugins. We also have an index and types file. So in the index file, you'll see that there is that our load plugin function and it takes an SCM type, which is all supported SCMs. This is an enum of all the supported SCMs. And we want to be able to support GitLab as well. So let's do that. So let's add and register GitHub as well as GitLab as a supported plugin here. So we're going to just say, GitLab equals GitLab. Okay, and let's see what happens. So now that we've done that, you'll see there are in our load plugin file in that index.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Scaling Up with Remix and Micro Frontends
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
This talk discusses the usage of Microfrontends in Remix and introduces the Tiny Frontend library. Kazoo, a used car buying platform, follows a domain-driven design approach and encountered issues with granular slicing. Tiny Frontend aims to solve the slicing problem and promotes type safety and compatibility of shared dependencies. The speaker demonstrates how Tiny Frontend works with server-side rendering and how Remix can consume and update components without redeploying the app. The talk also explores the usage of micro frontends and the future support for Webpack Module Federation in Remix.
React's Most Useful Types
React Day Berlin 2023React Day Berlin 2023
21 min
React's Most Useful Types
Top Content
Watch video: React's Most Useful Types
Today's Talk focuses on React's best types and JSX. It covers the types of JSX and React components, including React.fc and React.reactnode. The discussion also explores JSX intrinsic elements and react.component props, highlighting their differences and use cases. The Talk concludes with insights on using React.componentType and passing components, as well as utilizing the react.element ref type for external libraries like React-Select.
Full Stack Components
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
RemixConf EU discussed full stack components and their benefits, such as marrying the backend and UI in the same file. The talk demonstrated the implementation of a combo box with search functionality using Remix and the Downshift library. It also highlighted the ease of creating resource routes in Remix and the importance of code organization and maintainability in full stack components. The speaker expressed gratitude towards the audience and discussed the future of Remix, including its acquisition by Shopify and the potential for collaboration with Hydrogen.
Understanding React’s Fiber Architecture
React Advanced Conference 2022React Advanced Conference 2022
29 min
Understanding React’s Fiber Architecture
Top Content
This Talk explores React's internal jargon, specifically fiber, which is an internal unit of work for rendering and committing. Fibers facilitate efficient updates to elements and play a crucial role in the reconciliation process. The work loop, complete work, and commit phase are essential steps in the rendering process. Understanding React's internals can help with optimizing code and pull request reviews. React 18 introduces the work loop sync and async functions for concurrent features and prioritization. Fiber brings benefits like async rendering and the ability to discard work-in-progress trees, improving user experience.
TypeScript and React: Secrets of a Happy Marriage
React Advanced Conference 2022React Advanced Conference 2022
21 min
TypeScript and React: Secrets of a Happy Marriage
Top Content
React and TypeScript have a strong relationship, with TypeScript offering benefits like better type checking and contract enforcement. Failing early and failing hard is important in software development to catch errors and debug effectively. TypeScript provides early detection of errors and ensures data accuracy in components and hooks. It offers superior type safety but can become complex as the codebase grows. Using union types in props can resolve errors and address dependencies. Dynamic communication and type contracts can be achieved through generics. Understanding React's built-in types and hooks like useState and useRef is crucial for leveraging their functionality.
A Framework for Managing Technical Debt
TechLead Conference 2023TechLead Conference 2023
35 min
A Framework for Managing Technical Debt
Top Content
Today's Talk discusses the importance of managing technical debt through refactoring practices, prioritization, and planning. Successful refactoring requires establishing guidelines, maintaining an inventory, and implementing a process. Celebrating success and ensuring resilience are key to building a strong refactoring culture. Visibility, support, and transparent communication are crucial for addressing technical debt effectively. The team's responsibilities, operating style, and availability should be transparent to product managers.

Workshops on related topic

React, TypeScript, and TDD
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Mastering advanced concepts in TypeScript
React Summit US 2023React Summit US 2023
132 min
Mastering advanced concepts in TypeScript
Top Content
Featured WorkshopFree
Jiri Lojda
Jiri Lojda
TypeScript is not just types and interfaces. Join this workshop to master more advanced features of TypeScript that will make your code bullet-proof. We will cover conditional types and infer notation, template strings and how to map over union types and object/array properties. Each topic will be demonstrated on a sample application that was written with basic types or no types at all and we will together improve the code so you get more familiar with each feature and can bring this new knowledge directly into your projects.
You will learn:- - What are conditional types and infer notation- What are template strings- How to map over union types and object/array properties.
Deep TypeScript Tips & Tricks
Node Congress 2024Node Congress 2024
83 min
Deep TypeScript Tips & Tricks
Top Content
Featured Workshop
Josh Goldberg
Josh Goldberg
TypeScript has a powerful type system with all sorts of fancy features for representing wild and wacky JavaScript states. But the syntax to do so isn't always straightforward, and the error messages aren't always precise in telling you what's wrong. Let's dive into how many of TypeScript's more powerful features really work, what kinds of real-world problems they solve, and how to wrestle the type system into submission so you can write truly excellent TypeScript code.
AI on Demand: Serverless AI
DevOps.js Conf 2024DevOps.js Conf 2024
163 min
AI on Demand: Serverless AI
Top Content
Featured WorkshopFree
Nathan Disidore
Nathan Disidore
In this workshop, we discuss the merits of serverless architecture and how it can be applied to the AI space. We'll explore options around building serverless RAG applications for a more lambda-esque approach to AI. Next, we'll get hands on and build a sample CRUD app that allows you to store information and query it using an LLM with Workers AI, Vectorize, D1, and Cloudflare Workers.
Best Practices and Advanced TypeScript Tips for React Developers
React Advanced Conference 2022React Advanced Conference 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Build Modern Applications Using GraphQL and Javascript
Node Congress 2024Node Congress 2024
152 min
Build Modern Applications Using GraphQL and Javascript
Featured Workshop
Emanuel Scirlet
Miguel Henriques
2 authors
Come and learn how you can supercharge your modern and secure applications using GraphQL and Javascript. In this workshop we will build a GraphQL API and we will demonstrate the benefits of the query language for APIs and what use cases that are fit for it. Basic Javascript knowledge required.