Mike Hartington - AUDIO EDIT === Josh: [00:00:00] Hi, and welcome to Pod Rocket, a web development podcast brought to you by Log Rocket. Log. Rocket provides AI first session, replay, and analytics, which surface the UX and technical issues impacting user experiences. Start understanding where your users are struggling by trying it for free@logrocket.com. I'm Josh Goldberg, and today we have Mike Hartington, director of developer relations at nx here to talk about his React Miami talk. TypeScript is so slow. Do, do, do or is it? So first of all, Mike. Hi. Welcome to the podcast. Mike: Hello. Thank you for,~ uh,~ having me excited to be here. Josh: ~Yeah, ~yeah. ~Uh, ~you're a great person to talk to. React. Miami's a great conference. TypeScript performance ~is, ~is such a fascinating deep dive. So ~just, ~just to start off, TypeScript has performance things you are talking about. Why do you keep using TypeScript despite the fact that you're also fetching about his performance? Mike: ~Um, I, ~I remember ~the, the, ~the life before TypeScript,~ um,~ and the tooling before TypeScript. And ~I, I, ~I don't really want to go ever go back to that. ~Um, for, ~for the newer developers in crowd, there was nothing that provided really accurate and [00:01:00] good type analysis,~ uh,~ in your JavaScript program. Despite TypeScript having some performance issues, it is still a far better tool than what we, ~you know, ~came from in the past. ~Um, ~so it's like, just is that good that despite its performance issues, I will,~ uh,~ continue to use it. Josh: Excellent. I also wanna push back on the performance issues a bit. If you're starting a new project, you have maybe a half dozen, a dozen files. Will you notice anything wrong with Mike: Absolutely not. ~Uh, I, ~I, yeah, I did wanna make sure that it came across when I was,~ uh, kind of ~going through it. Most people never run into the issues that I was ~kind of ~highlighting. ~Um, ~for the most part,~ uh,~ it's only ~like ~once you hit ~a. Uh, ~a hundred, 200 files, large mono repos, or if you're on like a CI environment where the resources are super restrictive and you're not running stuff with enough,~ uh,~ memory and. You'll run into bottlenecks there, but you still have to hit that other hurdle of the code base is pretty large. ~Um, ~and that scale is really like what drives a lot [00:02:00] of the performance issues. But your Greenfield project or your Hello Worlds, you will never notice an issue. Josh: Great. Let's dive in then. What makes a type slow, or how do you define slowness when it comes to TypeScript? Mike: Yeah, so ~I, ~I kind of focused on two parts. ~Um, ~one is like throughput, so like TypeScript itself and the compiler itself. TSC basically has to go through and analyze all your files, figure out the types, whether it's kind of evaluating that,~ uh,~ by just following the symbols, or it has to go through and check the type that you have annotated onto ~your, uh,~ your variables ~where.~ Where that kind of performance issue,~ uh, kind of ~sneaks in is if you have so many files and they're all in the same kinda workspace, there's a lot of back and forth and ~kind of ~traversing of your program for TypeScript to like fully understand, hey, this, you pass in a string. It expected a number ~that com,~ that whole step of. I have to now know everything about this program to be able to tell you that you have an issue. And this file tends [00:03:00] to be like ~the, ~the major performance,~ uh,~ impact. ~Uh, ~and we see this a lot with ~like ~some of our customers at nx,~ uh,~ that they are in, ~you know, ~the enterprise, the expectations for large code bases are completely different, and they're okay living with. ~You know, ~two, three minutes for a TypeScript to compile, but it could be better. Josh: ~Sure. ~Just ~to, ~to clarify for folks who haven't used TypeScript much, does this impact runtime code in any way? Mike: No, no. This is only, this is a build time only,~ uh, uh, ~issue. I think with the. Runtime code tends to be pretty much ~like what? Like ~no performance impact other than like, how are you bundling? But the build step itself and being able to like compare the compiler,~ uh,~ the compiler speed is really just like ~a, ~a dev ergonomics or a dev experience versus actual user experience. Josh: ~Hmm. ~That's such a great delineation. ~And, ~and the two really feed into each other, right? If you have a great dev ergonomics or dev experience,~ uh,~ repo, then you can write better code. What is the impact of having something like, say, a very slow TypeScript type check ~or, ~or some other tooling issue it on dev [00:04:00] ergonomics, and how does that feed into the user experience? Mike: I mean, who wants to work in a repo or a project where everything just feels painfully slow? Like some of the demos ~I, I was,~ I've been working with like the compile time. Is over two minutes, three minutes. And if I'm having to go in day in, day out, work on a project that takes three minutes, just not even to fully compile and build a, ~you know, ~runtime code, but just to do type checking. That to me, ~you know, ~I'm not gonna want to put my best effort in on that project. I'm just ~kind of ~wanna be like,~ well,~ forget this. ~I'm, ~I'm already frustrated because everything's so slow. ~I'm, ~I'm not gonna care about the actual product that I want to,~ uh,~ I'm trying to work on. Josh: ~Yeah. All right, so let's, ~let's dig in a little bit deeper even into what causes these slow types. You mentioned that there are issues when you have throughput or TypeScript across different packages. What have people traditionally done between or to link these packages that isn't playing so well with TypeScript performance? Mike: ~Um, ~so in larger projects, I think the biggest thing that tends to be ~like the, ~like the cause of these issues is something [00:05:00] called TypeScript,~ uh,~ paths. And if you've ever looked at a project where like you have your ts config, there's a path,~ uh,~ setting inside of your compiler options that tends to be like. Some the only cause of it, but that tends to be like the big cause of,~ uh, of like~ slowness. 'cause the promise of paths is that have used them as ~like, ~I am isolating this chunk of code to its own folder and I'm just gonna import from that,~ uh,~ code. And ~it's, ~it's isolated and ~it's, it's, ~it's in its own directory and therefore it's never going to impact overall performance. But paths don't really work that way. ~Um, ~they make sense in like maybe smaller projects where all you have is ~like, ~I'm just rewriting a couple different import statements, but pads really are just like a shorthand. So that way when the compiler sees, oh, import something from at utils slash ~uh, ~whatever file name or whatever entry point, it's just gonna take that mapping for that,~ uh,~ that alias and. Put in ~the, ~the relative path information ~that you, ~that you set in your ts config. So like the isolation that you [00:06:00] think you're getting doesn't actually exist. And that right there ~kind of ~tricks people,~ uh,~ they think it's isolated. It's not isolated. So the compiler still is treating everything as just like one giant program. Josh: Whenever someone says one giant in the context of performance that seems like it's ~a, ~a good coat smell for what might be causing issues. Mike: And so like ~the, ~the easy way to ~kind of ~fix that is to use ~like ~two key things that,~ um, you know, ~are relatively new in the grand scheme of everything. ~Uh, ~project references and,~ um,~ workspaces, which are. Two different things for different purposes, but end up being,~ uh,~ beneficial to your overall experience. Josh: Let's talk about those two types, shared project references. What is Mike: Yes. ~Uh, ~basically this is like a built to end way for TypeScript to treat,~ uh,~ units of code as isolated modules. ~Um, ~so I think in most people's projects, they're used to seeing one ts config probably at the root. ~Uh, ~with project references, you can start to split up your code base into [00:07:00] smaller TypeScript,~ um,~ modules where each directory, for instance,~ uh,~ could have its own ts config and it's got all the compiler settings. It might be extending from like a base settings. But it's essentially just a way for TypeScript to see, I have this directory, it's got a ts config. I'm gonna compile it in isolation, and then I'm gonna go to this module. It has, its on TS config. Cool. Compile it in isolation. So now we can tell,~ uh,~ TypeScript two, instead of compiling like a hundred files, we're compiling maybe. 10 modules with 10 files, which it can do pretty quickly. So we are essentially having it figure out the same results, just faster because things are isolated. Josh: ~Hmm. ~It sounds like a form of caching almost that would delineating different layers that can be cached ~for, ~for reusability ~and, ~and, downstream Mike: Yeah, so, so it does include a little bit of caching in there. ~Um, ~it produces this output,~ um,~ I believe it's called like ts lib info, which is essentially just like a giant str gobbly good, like string of your [00:08:00] program. But if the inputs match, whatever it has been cached, you're able to just like, oh, we already did this. We know what it is. Let's just,~ uh,~ re reuse that information so that way we're not,~ uh,~ performing excessive,~ uh,~ builds. Josh: I think what you're referring to,~ I,~ I just looked it up. I had to,~ uh,~ ts build info files. Mike: Yes, ts build info files. They're one of those things, like they are a result of the build. And I never really look in there, so it's like I just have a mental, like, all right, I'm just like, ignore that file, file and keep on going. Josh: Excellent. Okay, so it, one, one strategy is to separate one's project into, say, a monorepo style or just multi-pack style using type your project references. You also referenced workspaces. ~Uh, ~what is Mike: Mm, ~so workspaces, uh, originally kind of came out of like the learner, uh, phase where there was a workspace key that you could use to tell, um, your package manager. These direct, all the directories in this location are going to be treated as separate projects, uh, with their own package, JSON, with their own list of dependencies.~ ~Um, so treat them separately. Uh, it was a good enough idea that MPM Yarn, PMPM, bun, all the kind of node, uh, tooling vendors all have their same. Uh, so it's all built into NPM yarn, as I said, uh, where everything that is listed in that workspace is essentially just sim link to your node module, so it's treated as if it's its own node module.~ ~Um, where this comes into play is types can isolate things in its compilation set, but it doesn't understand how to import things from node modules. So we have, or, um. Lemme rephrase that. Things inside of TypeScript, it doesn't fully understand how to get the source out of it, or it shouldn't be having to resolve a module.~ ~I don't know if I made that clear or if that's even more confusing. I could say it again.~ Josh: ~Just for the sake of the editor, let's say it again from the~ Mike: ~Okay. So.~ Josh: ~Okay.~ Mike: Project references, essentially pull in your types for your module and for your isolation co ~uh, ~like for an isolated,~ uh,~ compilation,~ uh,~ silo. But it doesn't necessarily resolve how those, how like external dependencies get in there. Project references because it treats,~ um,~ workspaces because they [00:09:00] treat everything as if it's like its own node module. It's pretty easy to resolve. So if we are having stuff all live in,~ uh,~ the node modules directory, TypeScript compiler can understand where those symbols are coming from. And even though it's still just local to the same project, the resolution is all done through node and then the TypeScript compiler can only focus on the types. So it's a little bit doing less work on the compiler side. But it's also following ~kind of ~better practices of making sure your code is easy to import all around the project. Josh: Gotcha. So I could have a bunch of separate projects set up locally in my repo, and then using workspaces, I can have them fancy, fancy sim link pointing at each other. And then all TypeScript has to, does do, if I'm understanding this is just cash ~or, ~or set up the TS buildin info between those different projects. Mike: Yes, ~in a, ~in a very kind of ~like, ~vague way of describing it,~ um,~ there's a little extra work and it's kind of why, ~you know, ~in, in my talk,~ I,~ I ~kind of ~was like, Hey, you [00:10:00] should probably use a model repo tool, whether it's NX or not. ~Uh, ~there's a couple of other tools out there that also do this,~ um,~ where I'm in project A. I have a dependency on Project B, project C. I need to include those references in project A, but they also need to be referenced in the Base TS config. So there is like this very weird duplicate effort of declaring the project references on the TypeScript side across the project that you actually need them, but also the base project. And so like NX in this case, 'cause we know all the,~ uh,~ all the dependencies inside of your monorepo, we're able to automate some of that and,~ uh,~ make sure that those are included in there. If you were to do this on your own, this is probably going to become a very painful project, especially if you have a hundred, even 50 different packages that you are trying to maintain. 'cause every time you include a new dependency, it needs to be updated. Josh: Sure. Okay, so this sounds like one pretty [00:11:00] severe strong point of performance pain for a lot of folks. There are a lot of other kind of zones we could dive into for types of performance that unfortunately we don't have the time. But are there any other hidden gems or particular things you wanna cover in this area before we move on? Mike: Yeah. And this is,~ uh,~ this is a fun one of just editor completion, or editor like. Responsiveness. ~Um, ~you could be inside a VS code. You could hit ~your, your, ~your trigger character. You hit that dot, and then all of a sudden you're sitting there waiting and waiting and waiting, waiting. And then you finally get an actual,~ uh,~ return from ~like, ~oh, here's all the symbols that you're, that are on this object. ~Um, ~that's a terrible dev experience too. I don't know anyone who would want to work on a repo like that. ~Um, ~and in the example I ~kind of ~highlighted it is actually a really fun one from,~ uh,~ a community member. ~Um. ~Where they created this very deeply nested,~ uh, um, ~TRCP router setup with very deeply nested types. And they generated it so that way it was [00:12:00] creating a hundred routes all with very complex types. So that way the TypeScript kind of language service is having to go through and like really try to figure out. What the type is for this one TRCP object. ~Um, ~that's terrible. I call it Tom Foolery, but there's like more colorful language that you could use to ~like ~describe it. ~Um, ~and so ~like ~one of the reso ~uh, ~resolutions that we ~kind of ~worked with him on figuring out is ~like, ~what if we could just pre-build everything thing? So instead of having the language service, ~like ~evaluate all of your types on the fly to figure out like. What are all the symbols and what are there valid types? If we just ran a build and generated static DTS file, like we could just return that information versus having to do the live evaluation, which ends up working out a little bit better. It's still slightly slower than not doing this. Tom Fery. ~Um. ~But it does ~kind of ~get back to the point,~ like,~ if you are running into like live evaluation issues where your completion is slow, trying to find,~ um,~ workspace symbols that becomes very slow. [00:13:00] Pre-building things could be a very valuable,~ uh, uh, ~improvement to your setup. Josh: Sure. Just as an anecdote, I once did a performance consulting call for a company. They were using things like Zod and TRBC and whatnot, but their biggest performance issue was a multi megabyte JSON file that they were compiling each time into a DTS. That was a itself, multi megabytes, and yeah, actually your strategy was roughly what we did. ~We, ~we pre-compiled into a much smaller DTS and it saved a lot of time. ~I, ~I think that's really cute. Mike: A multi megabyte file. Josh: It is terrible. Mike: Yeah, and ~I, ~I bet you the developers did not like working on that project, and probably we're very thankful that you,~ uh,~ you came along with that solution. Josh: Yeah. But I like this. ~So, ~okay, so you can pre-compiled DTS files. ~Uh, ~have you found that,~ uh,~ there's a lot of good tooling support for this? Is this something that's easy to set up? Mike: Yeah, for the most part it's like you treat all the individual packages at this point as if they are going to be published to MPM. So you include the entries in your package json for all the exports, the types, the entry [00:14:00] points, and I think a very simple way of doing it is having a post install script. That just runs the build ~for, ~for all the dependencies on all the projects and that~ that ~that's really, as ~you know, ~complex as it can be. I'm sure you could do more, but like a post and sell script that just calls NPM run builds for all the dependencies is, ~you know, ~valid enough. Josh: Yeah, ~that ~there are worse things one could set up. Mike: You could over-engineer it, but sometimes the simpler solution of just. into a post install tends to be ~the, ~the better one. Josh: Okay. There are a couple of spaces we could ~kind of ~explore now. I think one is TypeScript Go, which is very exciting, and the other is ~kind of ~the organizational strategy. I'd like ~to, ~to segue into the latter, how would I know if I am a web platform person or team or ~you know, ~startup, founding engineer, whatnot, what type of strategy should I pick or what's the algorithm for choosing how to set up ~these, ~these fancy Tom ese? Mike: ~Um, I tend to, you know, ~I would look first at just ~like ~have re regular metrics and analytics over ~your, ~your bills. If you're like a founder and like a solo engineer, you're gonna know the pain points and how long something takes [00:15:00] to build. If you're a more advanced and you have ~like ~a team of people. Check your CI times check to see like, how long are we waiting before PR gets merged, we ship to production. ~Like, what's that?~ What's the delta between when things actually get merged in and when it actually gets released? ~Um, the, ~if you're spending more time waiting on a PR to turn green, that's pretty bad. So you check that, you figure out, okay, we're spending this one PR probably took ~like ~10 minutes. We have maybe a hundred PRS over a week. That's a lot of wasted time just waiting for CI to just run a build and validate everything. ~Um, kind of ~one of the ~pi you know, ~the things that we do ~inside of our, uh,~ inside of NX is like show like how much time you've saved. By setting things up in a correct manner and taking advantage of caching and taking advantage of these techniques for organizing your project. So that way you can see there is some validation. Like if you did not do this, you'd be adding an extra a hundred minutes to your waiting time for ci. So look at the C CI times, look to see how long [00:16:00] you are waiting between each PR and if you are. you're feeling like it's too slow, you tend to know ~you're, ~you're a pretty good,~ uh,~ judge in that regard. If it feels too slow, take a look at some strategies. If not, continue on your merry way. Josh: You say time, I hear both time and money, right? CI time is both literal money spent in CI and the engineer's salaries. Mike: Yeah, ~I mean, ~from an engineering perspective, you'd never think of money, but from the business side of it. It is very much a ~very, uh,~ a costly,~ uh,~ expense. It's so much time waiting for Circle CI or some other CI provider to just like finish running and then you're just waiting there. It's the XKCD comic of, oh, it's compiling. Oh, it's in ci. Josh: Okay, so let's say I've done that. I'm on a non-trivial company size. I have a full team around me. I'm in charge of web platform. Woo is me. And I know that one of our big problems is lack of caching or lack of project references or workspaces. What do I do? ~Kind of, ~how do I start my team organizational journey towards this nice caching Eden. Mike: ~Um, ~started kind of [00:17:00] look at your dependency list. ~Um, ~honestly, ~like. ~I think this is something that we still try to figure out on a per client basis or per customer basis. There is no like real easy way of mixing both paths in project references as,~ uh,~ as far as I understand it, I think they're ~kind of ~exclusive. So you have to ~kind of ~either adopt one or,~ uh, you know, ~stick with slow builds. ~If you pick, ~if you realize that you need to move to,~ uh,~ project references, you could. Utilize some AI tool to go through and analyze all your workspace and say, Hey, create ~a ~a ts config for all these projects and migrate our main mono repo over to project references. And that seems like a pretty easy thing for,~ uh,~ any kind of AI and AI with some MPC ~uh, ~input. Josh: What about the kind of organizational side? ~Uh, ~how would you sell these sort of approaches to teams who are used to the simpler project structures? Mike: I would sell them as pushing isolated modules and boundaries,~ uh,~ more than what paths,~ uh,~ would do. No [00:18:00] one likes to find out that they imported. The wrong module or the wrong symbol into their project, and then, oops, you accidentally imported something that was meant for Node, but we don't have a really good naming convention, and now it's throwing an error because it's. Well, paths don't exist in JavaScript in the browser. ~Uh, ~with project references, you can ~kind of ~really push the team on isolation and modules inside of your code base, and that forces those boundaries between here's something that is solely it's own isolated context that is never going to be imported into,~ uh,~ a web. Project because we set the compiler to know that this is targeting node, we're only doing this. It kind of forces that boundary and that isolation even further than just good naming conventions. Josh: Now that you mention it, having ~a ~a Ts config per project opens up really nice opportunities to set compiler options per project, right? So you can say like different lib types or whatnot, different parts. Mike: Yeah. And if you have a [00:19:00] multi-platform monorepo where. Like I said, one, one team's working on like a node backend. One team's working on the, like a react front end. It's easy to separate what can be,~ uh,~ compiled for one context and you get that feedback,~ uh,~ a lot faster if you do things wrong. Josh: Great. there anything else we should cover on the organizational side before we start talking about go. Mike: Let's start talking about go. I ~kind of ~excited, I'm excited about the Go for it. I really would love to talk about it. Josh: Oh,~ we'll, we'll, ~we'll explain ~what, ~what are you so excited about? Why are we talking about go. Mike: I don't know if you know this, but the TypeScript team is porting TypeScript to go, and that is going to be,~ uh,~ something that will improve performance by tenfold, if not more. I think it's gonna be probably one of the coolest like. Once it does ship, it'll be like one of the coolest releases in a long time. Josh: 10 x that sounds hyperbolic. Do you actually mean 10 x Mike? Mike: ~Uh, ~I, I do,~ um,~ if not more,~ uh,~ there's a really good,~ uh,~ video from the TypeScript team,~ um, from, ~from Anders the, [00:20:00] or one of the original creators on the Go Port and their initial kind of findings for it,~ uh,~ where they were showing the performance benefits of. A compilation speed, which took a couple seconds to run, and then the ts go,~ uh,~ go version that ended up taking like milliseconds. And if it's a very small, trivial example, it's probably not that impressive. But imagine the improvements that can be made in a larger project now that you're using a language that also offers some kind of parallel. Parallel parallelizing of,~ uh,~ tasks goes multi-threaded. It can run things parallel to one another. So you feed a big project, it splits off into multiple different,~ uh,~ streams or different,~ uh, uh, ~threads to compile each one of those separately. That would be great. Josh: Yeah. One of the things I find fascinating is that the 10 x, the literal 10. X improvements that they've shown, give or take a percent here or there are just from the initial pass, right? Like they, they poured it as much as possible. They roughly kept the initial existing structures [00:21:00] and that was 10 x. Imagine what it's gonna be like after 6, 12, 24 months of optimization post launch. Mike: Yeah. And ~like ~there's nowhere it could go but up. I think it's ~kind of ~a good thing that they chose a language where porting. easy to do, like the syntax and the semantics,~ uh,~ for ~like ~what you're trying to do in JavaScript and how you can do it and go there. ~You, ~you can get to the same results pretty easily, but now they're going through the whole entire code base and realizing, huh, this is a little weird. Why are we doing it like this? Maybe we can also improve the actual TSC program itself. There will be performance benefits. It's just not just the language change and the improvements there, it's just the whole entire thing is going to be so much better if it gets here. Josh: Let's talk about that. When you say if or when you say when. What are your thoughts here? Mike: ~Um, ~I tend to be a little bit more pessimistic about these things. ~I mean, ~TypeScript five came out in, I think ~like ~two-ish years ago, 2023. ~Um. ~We are on 5.8 as of [00:22:00] February. ~Uh, ~so their releases tend to be a little bit slower. ~Uh, ~it's a large project. It touches a lot of code,~ uh,~ all over Microsoft and other organizations. So intentionally being slow is good. I had initially thought that we'd probably see it by like 2027,~ uh,~ maybe midway through 2026 would be like the really hopeful outlook. ~But you know, ~when they went from like ~the, ~the ~BLO~ TypeScript blog open, they have March 1st,~ 1st, uh, ~11th being like the initial like preview, and then May 22nd being the. We have a package, you can install it. It's not feature complete, but please try it. Maybe they'll get it in for something sooner. They said the target release was TypeScript seven should be the full go option, but maybe they'll have a use native flag in the compiler that people ~could, uh,~ could,~ uh,~ enable. Josh: ~It's, ~it's a fun case of the TypeScript project using EMR to its advantage to have a six point x version in parallel ~at ~at some point to the seven point x. It's kind of funny. Mike: ~For, ~for a [00:23:00] project that isn't known for following semantic versioning at all. ~Um, hopefully, ~hopefully they will actually do that with the new release. Josh: ~I, ~I look forward to that being possible ~at, ~at a language scale, but, okay, so let's say that I have a very slow project and I've set up things. I've set up project references. I've even set up performance optimizations we haven't talked about, like isolated declarations and such, and it's just still slow. I'd like to try out TypeScript, go. Do you have any suggestions or pro tips for me? Mike: I,~ I, I, ~I, honestly, I don't because TypeScript Go is not feature complete. ~Uh, ~there's like certain features in it, LA that. ~Uh, ~are not enabled yet. So there is like this dash dash build flag, which is necessary for project references to,~ uh,~ work TypeScript Go doesn't have that yet. ~Um, ~when it's supported. And when it's ready. Hopefully all you should need is either replacing TSC in ~your, ~your MPM scripts with tsc Go. We're adding ~like a, ~I would say a,~ uh,~ compiler option that enables it [00:24:00] for ~like ~either that one project or for ~your whole, uh,~ your whole project. So there is no ~like, ~easy solution for this at the moment. ~Uh, ~at least as far as I know,~ um,~ I have not followed the progress of the TypeScript go,~ uh,~ development. So ~I am,~ I'm sure you're a little bit more knowledgeable on it. Josh: ~I, ~I am not that. I don't have that much more information. I will say though, that it's very telling about your response, that you didn't start going into the structural differences, and now you have to restructure and change your project configurations. It's. ~From, ~from what everyone has seen roughly the same. So actually ~you, ~you've been very good at using the right word here, port rather than rewrite. What's the delineation? Why is that important here? Mike: So a rewrite would be. You have the same concept in program A that you wanna ~do ~do in a different language. And so you rewrite it. You basically rethink the whole structure, rethink the whole entire implementation. ~So that that way it's a different,~ even though it's in a different language, it's a different approach to solving a problem. And ~that~ the port instead of a rewrite is very different because they're taking the steps of. We're writing it in a different language, [00:25:00] but the instructions for how TypeScript compiles something is operating in the same,~ uh,~ steps. So it's like read in the project config, read in the files, analyze the a ST, produce the final output, and produce the DTS in a very kind of like hand wavy steps. They're following the same steps instead of trying to. Well, what if we did it in a different direction? What if we did it in a different order? ~Uh, ~their promise, support it, and to keep it as close to the original implementation, at least in terms of what it is doing, is really what I think is going to enable like the,~ uh,~ interoperability or the compatibility between the non,~ uh,~ native,~ uh,~ implementation. Josh: Sure. So this is then why they haven't say, done it in rust or C Sharp or some other language that's a little more distant from JavaScript. Mike: ~Uh, ~they probably would say that's probably why they picked go. I wouldn't, I don't even think like ~the, ~the language really matters. ~Um, ~I think [00:26:00] as long as they are approaching it in the same,~ uh,~ process of we are just trying to reimplement these steps. In the same exact order. The language doesn't really matter. Josh: ~Hmm.~ Mike: I'm sure the go syntax is more familiar for folks who are doing,~ uh,~ mostly JavaScript and TypeScript on a day-to-day. So there's probably something about,~ uh,~ ease of adoption. Josh: Yeah. I'm also trying, in my mind, imagine the rust model working for a, a direct port and it's, it sounds like it would be quite a bit different too. Yeah. Mike: It'd be a ~lot of, ~lot of hard to read code and I'm sure contr contributions would be,~ uh,~ very tricky for external contributors. Josh: that is an interesting point here that it, I think part of the reason why they waited this long to do a go port, not just because of how much effort it's, but because having types sheet and typescripts allows, ~you know, ~just one language knowledge, people to contribute there. There's a bit of a downside, your know, of switching to a different language. Mike: Probably I would, I think the different language. If you're doing, and I don't want to like, sound like ~I'm, ~I'm poo-pooing anyone's contribution [00:27:00] that isn't considered meaningful. But if you're doing high impact kind of contributions, the language that you're using really doesn't matter too much. You already have the systems' knowledge of how this whole entire thing works,~ um,~ whether it's go or rust or whatnot. Kind of, ~you know, ~doesn't matter if you're just making a, Hey, this comment or this thing was,~ uh,~ not as clear as it could have been. You don't really even care about the language either. You're just gonna make that one change or comment. ~Um, ~and not to sound like I'm pushing AI tools, but I think you can get pretty far with some,~ uh,~ some AI tools and,~ uh,~ AI powered like IntelliSense that. Having to know the entire depth of knowledge of Go doesn't, it's not a need that you need anymore. Josh: In this world where you have things like AI tools to help you develop where language specifics are a little more obfuscated from you, what are you think ~the ~the main TypeScript pieces of knowledge or foundational concepts that are gonna be most useful for folks then? Mike: ~Um, ~probably just how types work and the flow of types in, [00:28:00] are we talking in user program or in the TypeScript? ~Uh, ~contributions. Josh: Let's talk user programs, although I would really love to dive into TypeScript contributing at some other point. Mike: Yeah. ~Uh, ~in user programs, like it's, as long as you are fully aware, like you could probably build something ~with, um,~ with full AI tools and just. Get something that works, but if you don't understand what's being produced and how data is being flown around and how the types are working,~ um,~ you're probably not gonna have a good time and maintenance is going to become a pain when you eventually have to update it. Josh: So regardless of whether your TypeScript is 10 x faster or a hundred x, what are some of the ~kind of ~lines that you would draw between good uses of the type system and two clever or confusing uses then? Mike: ~I am gonna blank on the name of them. The tag, uh, the string template types.~ Josh: ~Who~ Mike: ~Is that what it was called?~ Josh: ~template literal types or string~ Mike: ~Temperate. Literal, uh, temperate. Little ~template. Literal types. ~There was just like, um, it was like a kind, ~once those kind of came out, I think there was like a, we're gonna make a type for every valid, ~uh.~ Area code or phone number that could ever exist and there were people who were just creating these giant types of like nonsense that was like, okay, that seems excessive. Josh: Yeah. They have doom [00:29:00] now ~in ~In Mike: They have dooming types. Great that you can do that. Probably don't ever do that. Josh: Yeah. ~But you know, ~this is kind of a natural trend for developers, right? ~Where, ~where you have something, you have ~the, ~the powerful type system or feature, you're gonna wanna use it and ~it, ~it can be hard to know whether you're using it correctly, that you're actually using the power where it's worthwhile, versus you're just ~kind of ~going down a rabbit hole that isn't actually beneficial. Do you have any tips for coaching teams away from these type system gymnastic shenanigans when they aren't actually useful? Mike: Yeah, ~if you're, if you're, ~if you're finding yourself actually having to go through and type like as unknown as any, or like kind of coercing, like the type to be what you need it to be, you're probably going, if you have a lot of those, that's probably a code smell and you should probably figure out, okay, we have an electron project, an electron has its own,~ uh,~ API, that they bolt onto a window. ~How do we, ~how do we make sure that we do that in a way that is actually. ~Uh, ~providing the correct types, but we're not having to go through Peren window as any dot electron or window dot any [00:30:00] as, any dot insert, any third party library. There should be ways where you are actually providing the correct information for whatever library you're trying to use to the program and. Do it in a way that doesn't feel like, oh, I have to make sure that I remember as any or as my type. There are ways to extend the official built-ins. You just gotta read how to do it or have an AI do it for you. Josh: Something doing it. All right, Mike, I have no more long form questions for you. Before we go into the quick rounds, do you have any other points you wanna bring up? Things to discuss? Mike: Yeah, I think the big thing,~ um,~ performance issues, like I said at the beginning, ~you're,~ most people don't ever run into the issues that ~I, ~I kind of highlighted and talked about. ~Um, ~when they do, they can seem daunting, but take it one step at a time and you'll be fine. Josh: If that's a good life advice, Mike: One step at a time. Josh: one step at a time. Awesome. Well, speaking of small steps to take one at a time, quick round, how do you prioritize fast builds compared to, or along with perfect type safety? Mike: ~Uh, ~take this [00:31:00] approach of get it green, then make it better, so whatever, to get something to build and then iterate. Josh: ~Hmm. ~Great. TypeScript. Go Will. Its ship in 2026. Mike: Not likely. ~I.~ Josh: ~Build time over two minutes. Acceptable or deal breaker?~ Mike: ~Two minutes locally or two minutes on ci. One of those is a better two minutes. I would say if it's,~ Josh: ~more question then locally and then in ci.~ Mike: ~uh, locally unacceptable, um, on ci acceptable~ Josh: ~Okay. ~If TypeScript disappeared tomorrow, what would you miss? Most? Mike: everything. Like I said,~ I,~ I remember the days before TypeScript. Those are ~very, ~very dark days. Oh, I'm a CE IntelliSense. Probably the most, Josh: ~Hmm. the ~the typing a few characters and seeing the list or the dot, and then the list of options. Yeah. Mike: the tools that existed that did that before TypeScript, I had to look it up because I forgot about it. It was this one called Turn js, Josh: Turn Js. Mike: ~Um. ~It was great for its time, but boy was it not type script. ~Uh, ~and it was Josh: Wow. Mike: amazing that they were able to do something like that. Josh: This looks like a, like an older web. If I'm looking at the website now,~ I,~ I would highly encourage any listener who has spare time to go and,~ uh,~ deep dive. This is a ~fascinating, ~fascinating project. Mike: I think it was originally made by the person who did. ~Uh, ~code Mirror. Josh: oh. Mike: Yeah, code mirror was ~the, the, the, the ~one of the original authors of it who did [00:32:00] code mirror and ~por, uh,~ prose mirror. Uh, wrote turn js. Josh: What an MVP. All right. Last question, Mike. This was not on the pre-approved list of questions. What's your perfect Saturday? Mike: It's raining. ~Um, ~I have a nice coffee. I have no plans and I just get to hang out ~kind of ~at home, ~do ~work on my hobbies, and not feel like I have to be rushed to go somewhere. I'm a pretty easygoing person. ~I, ~I'm a homebody at heart and I love it. Josh: That sounds lovely. All right. ~Well, ~thank you so much, Mike. This was a fantastically fun interview. We talked about TypeScript performance, about project references, workspaces, ~the ~the dreaded path aliases, TypeScript go, and of course, your perfect Saturday. ~Uh, ~I think that's all we have for today, so thanks for listening, everyone. This has been Josh Goldberg and Mike Hartington. Cheers.