All Episodes

June 5, 2025 85 mins
In this episode, Dan and I (Steve) dove deep into what turned out to be a surprisingly complex, yet incredibly insightful topic: gradually migrating a massive legacy JavaScript project over to TypeScript. We're talking about nearly 1,000 JS files, 70,000+ lines of code, and years of developer history—all transitioning carefully to a typed, modern future.

Dan walked us through how he started by setting up the project for success before converting even one file—getting CI/CD ready, setting up tsconfig.json, sorting out test dependencies, dealing with mock leaks, and even grappling with quirks between VS Code and WebStorm debugging.

We talked tools (like TS-ESLint, concurrently, and ts-node), why strict typing actually uncovered real bugs (and made the code better!), and why it’s crucial not to touch any .js files until your TypeScript setup is rock solid.

Key Takeaways:
  • Gradual migration is 100% possible—and often better—than ripping the bandaid off.
  • TypeScript can and will catch bugs hiding in your JavaScript. Be prepared!
  • Use VS Code extensions or TS-Node to support your devs’ tooling preferences.
  • Don't underestimate the setup phase—it’s the foundation of long-term success.
  • Start small: Dan's team converted just one file at first to test the whole pipeline.
If you’re sitting on a legacy JS project and dreaming of TypeScript, this episode is your blueprint—and your warning sign.

Become a supporter of this podcast: https://www.spreaker.com/podcast/javascript-jabber--6102064/support.
Mark as Played
Transcript

Episode Transcript

Available transcripts are automatically generated. Complete accuracy is not guaranteed.
Speaker 1 (00:05):
Hello, everybody, Welcome to another thrilling episode. I was going
to say, example episode of JavaScript. Jower, I am Steve Edwards,
the host with the face for radio and the voice
for being a mine, but Dan got to me the host,
so you're stuck with me speaking of panelists. Was I
speaking of panelists?

Speaker 2 (00:25):
Now I am?

Speaker 1 (00:25):
Anyway, Dan Shapiro is here with me. We are flying
solo today. How you doing, Dan, I'm doing great.

Speaker 2 (00:32):
So let's do our usual weather report.

Speaker 1 (00:33):
It is cool and rainy here in Portland, shocking for Oregon.

Speaker 2 (00:38):
And in April, I know.

Speaker 1 (00:39):
How tel Aviv guess warm and sunny?

Speaker 3 (00:44):
How did you ever guess? We literally didn't really have
a winter this year, to be honest, it was more
like a bit of a fall. Not that you know,
we should have more rain than we did. But you know,
it's still lovely there at least that and it still
is lovely weather fabulous.

Speaker 2 (01:05):
Well it's fabulous for you, it's jealous for me.

Speaker 1 (01:07):
But anyway, so today we are going to be talking
about a practical application of pipescript in JavaScript. I'll let
Dan give the details, but we're going to talk about
everything that was involved in Was it a new project
I already forgot. Oh so yeah, I'll let you talk

(01:28):
from here so I don't mess it up anymore.

Speaker 3 (01:31):
All good. So basically I had this interesting situation at work.
We have a large legacy JavaScript project that's still a
core part of our offering, and it's under active well

(01:51):
beyond maintenance. It's being actively developed and enhanced and improved
and whatnot. But it's all done in JavaScript on hundred
percent JavaScript because it was started more than eight years
ago and it was never moved over to typescript. It
just stayed JavaScript, and I was looking at introducing typescript

(02:19):
into that project. Actually that project has two parts. It
has a server that's just running on no JS with Express,
and it has a client or front end side, which
is implemented in React. That part actually again talking legacy.

(02:41):
Some years ago before I joined the company, they made
the kind of unfortunate choice to introduce flow into the
front end part for type safety, and they only did
it partially. I didn't want to touch flow yet, so
I was looking at introducing type script to the back
end part, to the no JS part of the project,

(03:05):
and it turned out that it was much more complicated
and error prone than I expected. There were a lot
of pitfalls and gutchas along the way. I kind of
thought that, you know, given that the whole idea of
typescript is to get JavaScript devs onto the bandwagon, that
it should be really easy and straightforward, and it wasn't.

(03:28):
And I even consulted with some typescript luminaries like Matt
Polcock had a lot of great advice and suggestions, but
it still wasn't easy. Also with Jack Harrington and others,
they all had great advice, but it still was much
more challenging than I expected. And the end result is

(03:49):
that I kind of documented the entire process, did a
bit something like an internal blog about it, and we
have this internal wiki. So I wrote the whole doc
about how to do it so that if and when
we do it in another project, it'll be much easier
that time around. And I thought that it would be

(04:10):
interesting and useful for our audience for me to show
this information. I hope that it is okay.

Speaker 1 (04:16):
So just to clarify, we're on the front end, you're
still sticking with what was there, right, In other words,
you're going to go with the flow, should we say.
And then on the back end was where you're doing
your typescript upgrading.

Speaker 3 (04:30):
Yeah, So the answer is actually that our ultimate intention
is to do typescript on both sides, but I wanted
to start somewhere, and it seemed easier to start with
the just JavaScript part because Flow and typescript, while they
are similar, they're not the same. They're not compatible, and

(04:52):
I didn't want to get into the whole mess of
how I get typescript and Flow working together in the
same project.

Speaker 1 (04:59):
Oh you so you wouldn't. You wouldn't replace flow with tithescript.

Speaker 3 (05:03):
I would, But these are large projects, so replacing well,
let's put it this way. I really wanted to do
everything gradually. It's important to emphasize this point. So for example,
talking about just to give an an understanding of the

(05:26):
size the scope of the project, So talking just about
the back end part that no JS project, we're talking
about close to one thousand files JavaScript files, about seventy
thousand lines of code, something like thirty five hundred commits

(05:46):
since the project started over seven close to eight years ago.
So it's not a small project. And obviously I can't
move all the JavaScript files over to typescript, all thousand
of all one thousand of them in one go. Now,
there are some automated tools that automatically move all your

(06:11):
JS files into TS and add types as best they can,
using all sorts of tricks and static analysis and whatnot.
I did not want to do that. I was looking.
The way that I wanted to go about it, and
especially after I spoke with some people, is to enable
a gradual migration. And I'll talk about the two ways

(06:33):
in which a gradual migration can be achieved. By the way,
if you want to understand why I'm looking at a
gradual migration, why I prefer this approach, you can also
listen to the interview that I did with Matt Pocock
a while back about typescript, and we also discussed this
aspect about migrating projects, although again we did not go

(06:57):
into the exact details that I'm intending to go into today.
So the idea was to basically introduce typescript into the
project so that we can do the actual migration of
the files slowly over time. It could literally take years.
Is that is that clear? I hope? Yes.

Speaker 1 (07:21):
Sorry, I was looking at the Matt Pocock episode so
I could tell people what it was.

Speaker 3 (07:25):
Yeah, we can probably put a link in the show notes. Yeah. Yeah,
it was an excellent episode, highly recommended. Wait a minute,
we did two episode with them. Are you looking at
the latest one, the one from like about a few
months ago, or an older one from like two years ago?

Speaker 2 (07:42):
Uh? Yeah, five thirty eight.

Speaker 3 (07:45):
It was probably a couple of years ago, so we
did more recent one.

Speaker 2 (07:51):
Okay, we'll find those and mention them later.

Speaker 3 (07:54):
Okay, So again we're talking about one hundred percent JavaScript
product built on top of NOGS with Express. Like AJ
likes it, it uses common JS rather than import, so
it requires it's a legacy project for an API with
the front end side, it actually uses a combination of

(08:17):
Swagger and open Api for public RESTful APIs and actually
graphql with Apolo for the internal private APIs. For unit
testing we used Moca and Chai and it has end
to end tests implemented mostly using Playwright, but that's less relevant.

(08:39):
As I said, almost one thousand JavaScript files, almost seventy
thousand lines of code, and around thirty five hundred commits
since the project started. And again we use squash, so
it's really thirty five hundred prs really rather than you know,
along the way the world a lot more commits, but

(09:00):
they were just squashed together.

Speaker 1 (09:03):
By squash you mean, not the vegetable. But when you
do the get merging in, you squash multiple commits and
do one bigger commit exactly.

Speaker 3 (09:12):
Just a clarify for yeah people, because you know, there
are a lot of small commits along the way. I'm
fixing this. I'm fixing that they're they're not that interesting
in most cases. You know, you can keep them if
they're really important, but in most cases they're not that interesting. Okay,
So I was looking to enable a gradual migration, which

(09:34):
means introducing Typescript into the project, but not actually moving
the entire project over to typescript. Maybe a few words
about why I wanted to do that. It's really funny.
I also spoke about this with Matt. When typescript first
was introduced, I had a kind of a negative attitude,

(09:57):
you know, when I came to JavaScript. Statically typed languages
like C plus plus and like Java, like C Sharp
and JavaScript. The dynamic nature of JavaScript afforded an amazing
amount of freedom, and I loved it. But as I

(10:17):
became ever more seasoned in JavaScript development, especially working in
larger teams, I came to realize and understand that for
larger projects involving larger teams, for production grade software, you
want something that's more structured and rigid, and you want

(10:41):
something that helps you avoid certain errors that can easily
happen if you're just using JavaScript. You know, the obvious
example is you just misspelled or mistype a property name
and you just get undefined instead of the actual value.

(11:03):
But there's no error in any other in you know,
in any other way, and it seems to run. It
just runs wrong, And that's one of those things that
typescript protects you from. Typescript. Also, the code is much better,
much more self documented, especially if you're talking about APIs,

(11:24):
Especially again if you're talking about larger teams that compose
software from parts, components or services together. You want APIs
that are much better structured and self documented. And the
integration with modern development tools like vis code especially that

(11:48):
does the much smarter autocomplete for you and puts squigglies
if you pass in wrong parameter types or the wrong
number of parameters or whatever. All these are super useful
tools when you're working, especially as I said, in an

(12:08):
enterprise type environment. And these days it's also better with
AI because it gives the AI greater context. By the way,
all that being said, if I need to solve a
lit code type problem, I'll probably just do it in
JavaScript and not mess about with the types. But for
everything else, I find that even though we are writing

(12:31):
those types that ultimately are evaporated out of the code,
because when Typescript is compiled to JavaScript, it basically just
strips out all the types. Despite that fact, I still
find it incredibly useful maintenance for the development and maintenance
of larger certainly of larger code bases, and especially in

(12:54):
this case, the fact that the project was done in
JavaScript and not Typescript was definitely hurting our developer experience.
Just recently, somebody literally introduced a bug that could not
have happened had the project been entirely done in Typescript,

(13:15):
and it didn't propagate all the way to production, but
it was only caught by an end to end test,
you know, later down the line, and it was much
more difficult and expensive to handle than if vis code
would just have put a squiggly under that offending instruction.

Speaker 2 (13:35):
So far, so good, so far, so good.

Speaker 3 (13:38):
By the way, I totally appreciate the fact that a
lot of front end developers or full stack developers still
preferred to work in JavaScript. You know, you do you
whatever works best for you. For me, after all these years,
I've come to the conclusion that again, for the larger
projects involving multiple developers, certainly I prefer you working in typescript. Okay,

(14:05):
So I have the project, it's pulled down to my computer,
and I want to start. The first thing that I
went about, again because it's a legacy project, is I
want to upgrade, to make sure that node is upgraded
to the latest possible version, ideally to the latest LTE
version LTLS version sorry, long term support version. And if

(14:33):
people are curious about what that means. We had that
conversation with the node guys about the nine pillars of note.
Hopefully you're using something like NVM, the node version management,
so you just you know, find the latest version you
support you can support idea, the latest LTS version and

(14:53):
put it in your NVMRC file. Update to that and
make sure that that it runs and that you can
work with it. Also make sure that obviously that you
were pulled on the latest version from you know, GitHub
or whatever, and that it appears to work properly in

(15:13):
your environment. The next step is to make sure it
seems obvious and explain why it isn't that your unit
tests work correctly. Now you might say, well, obviously, because
otherwise the project will be broken. But in our case,
at least, it turned out that some of the unit

(15:35):
tests had cross dependencies. What that means is that they
used mocks but didn't always properly cleaned the mocks up
the results. Some of the tests actually only passed when
they were run in a particular order.

Speaker 1 (15:54):
No, yeah, I've ran into that before. I know exactly
what you're talking about.

Speaker 3 (15:59):
Yeah, And it turns out that everything seemed to be
fine because when it was run in the JavaScript project,
it was it happened to run in the correct order.
Otherwise people would have noticed and fixed it a while ago.
But when I actually started moving the project over the typescript,

(16:19):
it turned out that because of the transpilation step, things
didn't run in exactly the same order, and then certain
tests broke. Or I had certain situations where I needed
to touch the business logic, and then I wanted to
run particular tests individually, and I found out that when

(16:40):
I tried to run the test individually, they failed, and
then I went back to the original code and founded
those tests. Even when I ran them individually in the
actual original JavaScript project, they also failed because they only
passed when they were run in a batch in the
appropriate order, because again of mock leaks. I won't go

(17:03):
into the detail of what mock leaks have are. Basically,
it just means that a mock was put in but
wasn't properly removed at the end of the test. It
consequently leaked into the next test, uh, and it impacted
that and in that case it actually enabled it to

(17:24):
complete successfully. And when you just run that test on
its own, it doesn't get those mocks, and then it failed.

Speaker 1 (17:31):
So in all the idea, I mean, obviously, I think
the idea there is that tests should be self but
they stand by themselves. I don't know what the correct
term is, right, so you're not dependent upon other tests.

Speaker 2 (17:45):
Yeah, for the test to spin up.

Speaker 1 (17:47):
Your environment and give you a mock up and give
you everything you need, run the test, break it down
on the next test.

Speaker 3 (17:53):
Yeah. By the way, even the fact that you know
a lot of the code has that so many marks
were used were test statement to the fact that it
was legacy code, because ideally, in more modern code I
would use dependency injection and try to avoid so many marks.
But again, the code is what it is, and that

(18:14):
was the situation. So basically the thing was that before
I could actually start the migration to Typescript, I actually
needed to fix a bunch of mock leaks and get
the tests to run properly in the original project before
I even start migrating it over to typescript. So I

(18:38):
verified that all the tests could run individually, and only
then did I actually start the migration process. The next step,
of course, is to install Typescript and initialize it. So
you do youless you're using NPM or yarn or whatever.
You NPM or yarn or MPM installed typescript, you do

(19:03):
Typescript in it. And already here I ran into an
issue because my default assumption was that the installation of
Typescript should be as a dev dependency, because why would

(19:23):
you need the actual Typescript compiler in the production environment.
It's just part of your development pipeline. In order to
actually build the system, the installable part of your project.

(19:44):
You only actually deploy the disk folder or whatever it
is that you're creating. And it turns out that at
least in our case and maybe also in the case
of our listeners, that was not the case. I actually
had to install it as a PRAD dependency. Are you
familiar with the difference between a PROD and a DEV dependency?

Speaker 2 (20:05):
Absolutely?

Speaker 1 (20:06):
I mean we ran into the same thing, uh in
the PHP world on the back end with composer, where
a classic a similar analog to what you're doing is
PHP stand which is a static analysis tool for PHP.
Where you don't want that, you know, in your in
your PROD build, so you put it as a dependency

(20:29):
use a save DEAV flag.

Speaker 3 (20:30):
Yeah. So unfortunately, I actually had to install typescript as
a PROD dependency in our case. And the reason was
that the build. The way that the built pipeline worked
is that it actually created a pod for deployment, uh,
you know, like a Docker pod basically, and and it

(20:53):
actually did sort like a get pulled inside the pod
and then ran the build in the pod. So if
and it only did and it only ran the PROD installation,
so if I didn't put it as product PRAD, I

(21:15):
actually broke our CICD pipeline because it tried to run
the TC as part of the PROD build, and it
wasn't there. Now, ideally I should fix the CICD pipeline
so that it doesn't work this way, maybe build it
into a special environment and then copy the files over

(21:38):
into the PROD environment rather than build in the PROD environment.
But I wanted to reduce the amount of DevOps work
that I actually had to do, and it seemed just
a lot easier to just make Typescript itself a PROD dependency.
It's just an ideal, of course, because you're shipping Typescript

(21:58):
as part of your note modules. It's broad installation. But
you know what, it's so big anyway, it didn't make
that hole that much of a difference in our case.
And as I said, I just wanted to get over
this this blocker, so just.

Speaker 1 (22:17):
So just to clarify that, so it doesn't you know,
I'm not a big Typescript user myself used some and
not a real big user of it.

Speaker 2 (22:27):
But correct me if I'm wrong.

Speaker 1 (22:28):
But doesn't the whole point of the typescript compiler that,
as you you know, you write your typescript code and
then it compiles. It does I was checking it saves
it to job script files, and that's what you want
to build off of, isn't am I crrect?

Speaker 3 (22:39):
Yeah? Look, there there are really two ways these days
in which you can run typescript on top of note,
the way that you usually want to do in production
environments is you want to run the Typescript compiler TSC.
It runs, it does all the X, it fails if

(23:01):
it identifies an error, but if everything is fine, it
general like you said, it generates JavaScript files from the
typescript files. So for every dot TS file you get
a dot js file, and in that JS it's basically
just essentially looked mostly like stripped out the type information.

(23:22):
And then ideally you would just deploy those JS files
and you don't deploy the TS files. But as I explained,
the way that our CICD pipeline was built, because it
was originally done before TSC, nobody thought about about that.
The way that it worked was that it actually did
a Git pull directly to the production pod that it

(23:47):
was building, and then ran a quote unquote build on it,
which effectively did very little in the pre TSC scenario.
In the TSC scenario, that build actually runs the TSC compiler.
So building the production pod required having TSC on that pod,

(24:13):
so again not ideal. A better solution would be to
fix the CICD pipeline, but that's how it was built
when it was built, and I didn't want to mess
about with the CICD job and building new one or whatever.

(24:38):
As I said, I don't consider myself a dev's off person,
and if I can avoid doing that, and I prefer to.
By the way, these days, there's a different you can
there's a different way for running typescript on top of Node.
Actually there's a couple of ways. So first of all,

(24:59):
there's this project called tsnode which literally wraps Node and
adds TSC some support for typescript files into Node by
effectively running TSC when it loads a file when files
are loaded into Node, so you can use tsnode to

(25:20):
run the typescript files directly on note without having to
use TSC first to build the jobscript project out of it.
But obviously this is not something you really want in
production environments because all that thing adds a lot of
overhead when the Node process starts, and why pay for

(25:40):
that overhead. What the Node team has recently done is
they've actually added a new command line switch, which kind
of quote unquote gives Node TS support. The way that
they do though, is not by running TSC, is by

(26:03):
stripping out the type information. So think about like it's
it's overwriting all the type definition with spaces, so it's
kind of evaporating the type information out of the out
of the TS files and then what you're left with
is just JavaScript and it runs that, and it can

(26:24):
do that fairly quickly. But on the conversely, it doesn't
actually do any type checking. It just so they expect
you to do the type checking beforehand, but they say
you can still run the TS files directly and you
hardly pay any over any overhead costs for that. Is
that clear?

Speaker 2 (26:44):
Yes, sir, good.

Speaker 3 (26:46):
But again this is variatively new, relatively recent, and when
I worked on that project, I didn't use it, so
I I really needed to compile the TS file into
JS files. So as I said, I installed TS, I
initialized it, but I put it as part of the

(27:07):
pro dependency, not a dev dependency because of the way
in which our CICD pipeline is built. When you install
an initialized when you initialize typescript, actually it generates a
TS config file or TS configured dot json file to
be precise, at the root of your folder of your project. Sorry.

(27:29):
In fact, that's how TSC knows where the root of
your project is. It assumes that where that file is
located is the root of your project, and that ts
configured dot json files is a JSON file obviously of
configuration data for TSC telling it how to work how

(27:52):
to process your project. For example, you can tell it
which folders to include or exclude from its compilation. In
our case, all the source files except for the root
index file resided in an src folder, and all the

(28:14):
test files the unit test files, and also some of
the end two n test files resided in a test folder.
I configured ts configure to compile both these to look
at just these two folders, and by default TSC tries

(28:37):
to compile of the files to be next to the
original files. So if you have let's say a inn
x dot ts, it will generate an x dot js
alongside it. That is not what I wanted. The reason
that this is not what I wanted is that my
project is full of JS files and I want them

(28:59):
to be processed as well, and I can't generate an
x dot js file from an x dot JS file
into the same folder I need. I have to generate
it somewhere else. So I had to configure TSC to
build everything into a disc folder, so it would take
everything from the src and test folder and build them

(29:21):
into a disc slash slash SRC and a disc slash
slash sorry Test.

Speaker 1 (29:28):
Yes, So I don't know if I'm jumping ahead here,
so pardon if I am. But is it normal practice
to have like a TS file for the typescript and
that compiles to JS or is that yeah?

Speaker 3 (29:39):
But I'm going to do Yeah, But like I said,
I have one thousand JS files and I don't want
to just arbitrarily rename all these files to dot TS.
So from the way that I wanted to work is
that is to manually transform each and every file at
a time and do it gradually over time. So this

(30:02):
project going all the way. If we ever go full TS,
it might take years, and you know, but we'll, you know,
every day or two will take a JS file and
move it that particular file over to TS. But until
we do, that file stays as JS. So I really

(30:25):
need to have the TSC compiler take all the TS
files but also also all the JS files Effectively, I
needed to quote unquote compile the JS files as well
as the TS files because I need them all to
be compiled into the same folder, because otherwise I'll break

(30:49):
the project structure. I can't just compile the TS files
if I. If I have there a one thousand five
files in this project that are JS and three files
that I've moved over to TS, I need the resulting fold,
the resulting this folder to have all the JS files,
both from the originals and from the ones that I've

(31:11):
already moved. I hope I'm explaining it clearly enough.

Speaker 2 (31:16):
Yeah, I get it.

Speaker 3 (31:17):
The other thing is I did is I enabled incremental
build for speed. Incremental build means that that TSC maintains
something like a cash and it sees that, hey, this
file that I've previously compiled, nothing has changed in it,
based let's say, on the time and date, so I
don't need to compile it again. And this way you

(31:39):
don't need to compile the entire project each and every time,
even though in our case it was very very quick,
precisely because most of the files it was just taking
JS files and generating JS files from them almost as is,
which apparently it can do very quickly. They specified the

(32:01):
latest possible target based in terms of the JavaScript support,
based on the no JS version that we're using. And
since as I said, the project is using common JS,
which means it uses a required rather than import, and
also all the tests that we had did a lot
of their mocking based on the assumption that require was

(32:23):
being used, I can figure the output to be common JS.
That means that in the ts files that we're creating,
we can actually start using imports, but when the JavaScript,
when the TSC compiles it into JavaScript, those import become required. Now,
again this is less than ideal because ideally we would

(32:44):
like to also move eventually from common JS over to ESM.
But you know, one thing at a time, you can't
do everything all at once. So the next thing that
I did was allow JS files, since as I explained
multiple times, we aren't actually converting most of the files

(33:07):
yet most of the files remain JS. What it means
by allowed JS files it means that the ts C
will also process the JS files, effectively copying them over
into the disc folder when it compiles the project.

Speaker 2 (33:24):
So that you had to do that.

Speaker 1 (33:25):
Could you mentioned that earlier about about creating that.

Speaker 3 (33:28):
Because I don't. If I don't do that, think what
would happen That this folder will only contain the like
the three JS files that were compiled out of the
TS So sorry, I wouldn't be able to run the
original because the original already contained some TS files and
no doesn't know R to run them, at least without

(33:48):
that special command line switch. The disc folder will just
contain the JS files generated from those TS files, so
most of the files will be gone, so neither the
original source nor the disc fold there would be runnable.
I wanted the disk folder to be runnable, which means
that all the JAS files needed to be compiled quote
unquote into that folder as well.

Speaker 1 (34:10):
So my point was just that you had to have
this in conjunction with the earlier build step that copies
everything to the separate discfolder. You'd get a whole lot
of nothing.

Speaker 3 (34:19):
Basically. Yes, now, some of the code, some of the
Jazz files actually required JSON files that were also located
in the src folder with him. So what you also
need to enable is the flag that tells TSC to
handle to resolve Jason files. So it sees that a

(34:43):
certain JavaScript or typescript files requires a jason file. It
will also copy that Jason file over to that disk
folder in the same relative location. And because if I
initially neglected to do that, it didn't find those Jason
f files when I try to run the project and
that turned out to be bad. You can easily search

(35:05):
your folder and see if you've got any files that
don't match the dot js or dot jsx extension, and
then you know that you need to make sure that
these are copied over into the disc folder as well,
and preferably by the TSC compiler itself. The next thing

(35:29):
that I needed to do was enable source maps for debugging,
since I still want to be able to debug the project,
but now I'm actually running it from the disk folder,
but I want to debug it in the typescript files.
I want to see the original code that I wrote
when I put in break points, not the compiled output code.

(35:52):
It's very similar, but it's not identical, and I prefer
debugging the original. So in order to achieve that, you
enable source maps. Source maps are maps with the dot
map extension that are generated by default in the same
disk folder alongside the JS files. So if you had

(36:15):
an x dot ts it gets compiled into the same
relative location, and the disk folder into actually two files,
one with the dot x dot JS and one with
called x dot map. And actually at the very bottom
of the JS file, it adds a special comment that
tells dev tools where that where the map file is located.

(36:41):
And in this case it's easy because it's located in
exactly the same place, so it's a simple relative location.
Map files enable debuggers like dev tools, which is built
into Chrome or Edge or effectively any dev tools of
any debugger any browser, sorry or the built in the

(37:03):
buggers in most IDs, to be able to single step
through the original files because the debuggers is smart enough
to understand that this line in this file is actually translated.
It matches that line in the original file, and here's
the location of that original file relative to the compiled

(37:29):
output file. The next thing I enabled was strict type checking.
I was kind of concerned about that, but there was
no problem with it, so I used that. And I
also in our case, because we're using common JS, I
made sure to enable the flag that instructs TSC to

(37:49):
always put you strict at the type of at the
top of the generated files. If you're using ESM, you
don't need it because ESM files arem module files are
strict by default. But in our case sense again, since
everything was compiled to common JS, I really wanted to

(38:10):
have you strict there to get strict behavior.

Speaker 1 (38:13):
Can you elucidate on what strict means or what it's
going to do.

Speaker 3 (38:17):
Yeah, Strict is a very old JavaScript feature, dates back
to US six or before. Basically, there was certain let's
call it less than ideal behaviors in JavaScript that they
unfortunately could not remove out of the language due to
backward compatibility issues, and the way that they decided to

(38:41):
fix them was add this use strict directive that if
you put it at the top of your file, for example,
it's just a string quote open quote U strict close quote.
It puts the JavaScript engine in strict mode, which changed
just certain those certain bad behaviors a couple of examples.

(39:07):
The with statement turned out to be a bad idea
in JavaScript for various reasons. With you strict with is gone.
There's also a difference in what happens if you try
to use this outside the context of an object. You know,

(39:29):
if you just have a function and it does this
dot x before you strict, it would default to the
global object with stricted defaults to undefined. So they they
made certain changes that improved the behavior of JavaScript, but
they were not backward compatible, so they had to add

(39:51):
the TC thirty nine way back when had to add
this flag in order to support it. Now in modern
environment like EES models, if you're using ESM, then by
by definition you're using e S six, then you you're
they can assume that you're US strict by default because

(40:11):
there are no backward compatibility issues there. Likewise, if you're
inside of a JavaScript class, again it's modern JavaScript by definition,
so they can assume you strict within that class, regardless
of whether you put ustrict that in the top of
the file or not. And the last thing that I
needed to add was to skip lib lib tests, which

(40:34):
checks that you have type definitions for all the LIBS
libraries that you're using, because you were using some old
and even almost deprecated libraries which and especially some internal
libraries did not have type information, which means that did
they did not have a d dot t S files.

(40:57):
If you're familiar with the concept, yes, we.

Speaker 1 (40:59):
Would clarify that lib is not liberal versus conservative, that
is library.

Speaker 3 (41:03):
Yeah, exactly. So you've got a library let's say let's
say you have a library and it was compiled when
it was built from typescript to JavaScript, and you are
only distributing that library because it's it's an NPM package.
You're only distributing it as the compiled output the JAS files.

(41:26):
But you still want the type information, so that code
that uses that library can can only call library APIs
with your passing in the correct parameters of the correct
types and stuff like that. So what the Typescript compiler
can do is it generates a file with a dot

(41:49):
D dot ts extension, and that file contains type definitions
for that library, so that Typescript knows to verify that
you're using that library correctly. But some of our own libraries,
especially internal libraries, were old, did not have this support,
and unless I told it to skip the library tests,

(42:12):
it would fail because they would say, hey, you're trying
to use this library. I'm looking for type information for
this library and I can't find it. I can't use it,
you know, abort. By setting that skip lip tests, I
was able to tell TSC, you know, okay, it is
what it is, just deal with it. Give the things

(42:34):
that you import from that library type any effectively, well
not effectively literally now, since all the JavaScript files are
also processed as I explained. As I said, I needed
to specify everything to go into a disk folder to
avoid collisions. And obviously you need to add this disc

(42:59):
folder to your get ignored for example, because you don't
want to save that disc folder into git up for example,
because it's you know, you don't ever put in git
auto generated files. The next thing I wanted to do
is install types for various libraries that I use, So

(43:19):
you basically NPM install or arn't add things like at
types slash node or at types slash Express. Basically there
are a lot of these type these things that you
can install or that are at types slash something based

(43:39):
on the service or library that you use, and they
just make sure to add the type information for those
various libraries and services. So now that if I use
a Node API, I get the type checking for that
Node API, or likewise for Express, which is really great
and what we really want Typeescript for. Since I had

(44:03):
to put Typescript itself as a prod dependency, I unfortunately
had to put these as a proud dependency as well.
In your case, if your CICD allows it. You can
put both d S and these type these type packages
as as dev dependency sorry, assuming again your CICD pipeline

(44:26):
supports it. I also needed to install a package called
source slash map slash support to get the proper debugging
support in all the environments that I use with the
map files that have already configured. The generation of a
lot of steps and again not trivial. I for some
reason I couldn't really find Maybe our listeners are better

(44:50):
at they have a stronger Google for AI food than
I have and can find this information. I could not
find a clear description of all this information. The next
step that I had to do is I had to
do with eslint. So I assume or hope that you're
using islint in your project. If you do. If you don't,

(45:12):
then you should. We had guests on our show talking
about eslinteslint is a linting tool that verifies that you're
using the language JavaScript according to best practices you know,

(45:33):
either generally accepted or ones that you've decided on within
your organization. It could be almost comical rules like you know,
prefer quote single quote over double quotes, so you don't
have a random mixture of both types of quote in
your project. Or it can be about things like putting

(45:55):
the curly brackets at the end of the line rather
at the beginning of the next line, and so on
and so forth, everything that you prefer in terms of
coding style and avoiding legal but bad patterns within your code. Now,
if you're using Typescript, you also want to install something

(46:18):
called t s slint or Typescript e slint. We had
Josh Goldberg on our show to talk about why you
want this. Basically, it's es slint for your Typescript. Now.
You need it for two reasons. The obvious reasons is
that it adds particular specific linting rules for Typescript itself.

(46:42):
I mean obviously because similarly to JavaScript, there can be
things that are legal in Typescript, but you nonetheless prefer
to avoid because there are sort of anti patterns in
the language. But it actually goes beyond that. It turns
out without t S slint, eslint itself will flag certain

(47:05):
things in your Typeescript code as bugs because they don't
match lint JavaScript linting rules. For example, you can use
extends in JavaScript in TS in Typescript generics, but it
assumes that extends its used for extending JavaScript classes and

(47:28):
that you're using it wrong and it flags it. So
you need t S e S Flint for the linting
to work properly. Now, if you're adding t S slint,
you need to make sure that you're using the latest
version of eslint. Unfortunately, because we were a legacy project
in our case, this was not the case. So I

(47:51):
had to update eslint to the latest version. And then
I found out the hard way that they the Slint project,
made a significant, not backward compatible change in the way
in which they managed configuration. They went to a flat

(48:12):
configuration file. They basically changed the whole structure of the configuration.
So I had to go through the process of fixing
the configurations and as long as I was there, rethinking
the configurations because a lot of the rules were dated,
so I updated our Slint rules as a part of

(48:35):
this migration process. As you can see a lot of work.
The next issue that I ran into was the fact
that some people on our team prefer using vis Code
and some people in our team preferred using web Storm
for JavaScript development, and I wanted to support both I
didn't want to force people to have to switch their

(48:56):
development environment, which means that I had to get at
everything working in both. And where this ran into a
problem was with the unit tests. Web Storm out of
the box had this ability, has this great ability that
it can actually scan your files, find the unit tests,

(49:23):
and make it possible to run individual unit tests and
debug individual unit tests directly from within the web Storm environment.
You can actually do the same thing in VS code,
but you actually need to install an appropriate extension first.
Once you install the extension, it's great. I actually prefer
vis code with the extension of a WebStorm, but that's me.

(49:46):
We had developers who preferred using WebStorm, and for the
life of me, I could not get WebStorm to handle
the situation in which the TS file files were located
in one place and the output JS files were located
in a different place in the disfolder and to figure

(50:08):
out that even though the test code the source code
for the test was here, it should actually run the
code that's over there and use the map files to
properly support the single step and debugging with the VS code.
And as I said, we were using Mocha and Shi
on VS code. I was able to install those the

(50:30):
vs code extensions for Moca properly configure it. It just worked.
In that scenario WebStorm, I could not get it to work.
The only way in which I finally was able to
get it to work. As I mentioned before, this tsnode
thing where it's a wrapper to node that teaches node
how to handle TS files. So I actually had to

(50:53):
configure the template file for Moca on WebStorm to use
tsnde instead of nodes, and then it worked. So I
used a different typical configuration between web Storm and between
vs code and vis code. I would I preferred the

(51:15):
test to run closer to the way that they run
in the CICD pipeline. That means to run the test
and the compiled tests and the disfolder. And as I said,
I could get I could get it to work with
the source maps because the extension from Mocha was smart
enough to handle it. In the case of WebStorm, I

(51:37):
don't know if it can or it can't. I could
not figure it out. I had to use ts node.

Speaker 2 (51:44):
Now you can still run the test from the command line,
Is that right?

Speaker 3 (51:46):
Yeah?

Speaker 1 (51:47):
You're talking about is like the UI you know, it
gives you a little button you can press run this test.

Speaker 3 (51:52):
Exactly exactly which you want if you want to debug tests,
because when you have that button, you can actually right
click it select debug instead of run, and then you
actually single step that test within your ID, which you know,
if you have a failing test, the ability to debug
that failing test makes life a whole lot easier. It's

(52:15):
certainly much more, much more fun than console log debugging exactly.
And the other thing I needed to do was configure
the Mocha itself to run all the tests from this
test instead of tests. One more thing, and now I
had to start modifying scripts in the package json itself.

(52:38):
You know, we had all the built scripts and run
scripts and dev scripts, so I added the script for example,
a built script so that you could run TC as
NPM run build or Yarn build would literally just run TSC.
But I also wanted to support a more dynamic mode

(53:05):
for development. You know, in development, you want for example, node,
Node has this ability to watch your folder, see that
it changes, and then restart itself whenever it identifies that
the file is changed. But now it becomes a more

(53:27):
complicated scenario because what actually needs to happen is you
save that file. You want that file. You want ESC
to notice that the file is changed and then compile
it to the disk folder. And then Node you want
it to notice that the contents of the disk folder

(53:47):
is changed and to restart itself. So it becomes like
a two step instead of a one step. Is that clear, crystal?
So initially I did the naive thing. There was dev
script in the package Jason that literally had uh node

(54:08):
running Node in watch mode. I forget the syntax. Let
me take a quick look at how it actually is implemented.
So it had it had it used nodemon with a
watch to actually automatically reload Node whenever the content of
the folder change. And originally it was running things directly

(54:31):
from the source folder. I wanted noemond to look at
the disc folder instead. That was easy enough, but I
also wanted uh TSC to look at to watch the
source folder and see if it changed, to compile automatically
into the death folder. And there is a TSC minus

(54:53):
minus watch that you can use for that. So originally, initially,
so one thing you can do just run those two
commands separately. You can open like two terminals, or you
can use in vs code there's this thing that they call,
I forget the name tasks you can do. You can

(55:16):
run both two tasks, one to have TSC watching your
source and node more watching your disc. But I did
want to have to do to force our developers to
do these two steps, where in the past they just
did one. In the past, they would just do yarn

(55:37):
dev and it just worked, and I wanted to work
this way. So initially I was kind of naive and
I did TSC minus minus watch, then hun percent unpercent
node mon minus minus watch, and it didn't work. Can
you guess why it didn't work. It didn't work because
un percent unpercent waits for the process on the left

(55:58):
to finish successfully before running the process on the right.
If you remember your Bash.

Speaker 2 (56:04):
Oh sorry, I'm not a Bash guru, but hey, strip, so.

Speaker 3 (56:07):
It was waiting on TSC minus minus watch to successfully
finish before running a nodemond. But TSC minus minus watch
never finishes. That's the whole point. It runs continuously in
order to watch for changes in the source file never
so it never actually ran the nodemd Oh. Yeah. So
the easiest solution that I finally found for this is

(56:30):
another package called concurrently, which you can tell it to
run both things simultaneously and kill them both if you
do a control C. So look at a package called concurrently.
That's what I used to fix it. Maybe there's a
smart maybe smarter Bash gurus can do it without it.

(56:50):
That was the easiest solution for me. That's what I
ended up using. Notice one important thing that I have
not done so far at all, and that's kind of important.
I wanted to emphasize this. All this work was done
before I converted even one JS file to Typescript. So

(57:12):
I've got all this pipeline working and TSC working and whatnot,
but it's basically compiling JavaScript files to JavaScript files. I
don't have a single TS file in the project yet.
And that's really important because initially I kind of when
I kind of got ahead of myself and I started
moving JS files to TS in order to see that

(57:35):
things worked before I had everything properly working, and then
I ran into all sorts of problems, which eventually ended
up with me throwing the whole thing away and starting
from scratch. So make sure you've got everything working so
far before moving even a single JS file to TS,

(57:55):
because otherwise you'll be sorry. So create a PR from
everything that you've done so far, make sure that everything
according to what I explained. Make sure that your CI,
your updated CICD now passes while running TSC again without
converting any TS file yet at all.

Speaker 1 (58:18):
And I didn't with the assumption being that when you
do convert TS files and everything's in place, right, you haven't.
Everything you've done is to handle the conversion of the
typescript files to jobascript exactly.

Speaker 3 (58:30):
I wanted to get to a situation where everything else
worked and then I can start converting files individually and
not have to worry about it. I didn't want to
deal both with the configurations and the conversions at the
same time. So I created a PR. I verified that
the whole CI process passed for that PR. I didn't

(58:53):
merge that PR. I just wanted to see that it
was green. Yes, after I saw. After I saw that
it was green, I moved one and just one file
from being a jazz file to a TS file and
to see that it still worked.

Speaker 2 (59:11):
And by that you just changed the extension.

Speaker 3 (59:13):
Right, No, because that's not enough. If I changed the extension,
it would complain about various missing type declarations and whatnot.
I can obviously set it to super relaxed, not the
strict mode, but I intentionally wanted strict mode. So I
actually I chose a really small JS file, literally one

(59:34):
of the smallest files in the project that I can found,
one that was not dependent on any other project, a
file in my project. So it was literally a leaf
file only it may depend on external packages, but not
on anything inside my own project. And I just converted,
but I made sure that that jazz file was actually

(59:56):
a file that's being used. I didn't want to convert
something that nob the actually imports or requires, uh, And
I converted just that JS file D two ts. I
did it using get m vy or get move in
order to preserve its history. Are you familiar with Git move?

Speaker 2 (01:00:16):
Oh, yeah, very much.

Speaker 1 (01:00:17):
So it's basically it's it's one of the weird things
about get, At least to me, it seems a little weird.
Maybe it makes sense when you think about it. If
you want to rename a file, it's not a renamed command.
It's a move command to move it from one file
to another.

Speaker 2 (01:00:34):
Yeah, kind of the same making a branch, same thing
with the branch exactly.

Speaker 3 (01:00:38):
So I did a geit move of that a single
file from JS to TS, preserving its history. I added
the type information. I made sure that that it's a
file that's actually as I said. Then give the rules.
All file as small a file as I can find,
not dependent on any the other file within my own

(01:01:02):
within that particular project, but can be dependent on external things.
Is used by one of the unit tests again either
directly or indirectly, but small and simple, and is required
by somebody again by a by a unit test or
by and buy some code and and converted that. Added

(01:01:24):
the type information. UH, make it as simple as possible,
avoid changing execution logic, business logic. Just add the type information,
committed it, committed that change. UH, created a commit for
that change, updated the PR and saw that it still worked.

(01:01:49):
And happily you did so.

Speaker 1 (01:01:52):
You mentioned you said when I UH mentioned about just
changing the file from JAS or even moving it from JST, that.

Speaker 2 (01:02:01):
It would still fail.

Speaker 1 (01:02:02):
So in a typescript file, just for clarity, is there
something else that you have to put in there that
says no, you.

Speaker 3 (01:02:07):
Need to put it in the type information and unless
you make as I said, as I mentioned when I
created the TS CONFIGU Todd jason file. I set it
to strict type checking. I could have not put it
a strict type checking, and then I could have just
renamed that file. But I put it a strict which

(01:02:31):
means that it expects to see type information on things
like variables. Unless it can in further type information, it
needs you to give it the type information. So if
you do a const x equals three, it knows that
x is a number. But if it's just let x
without signing anything, it can't know the type of X,

(01:02:54):
So you need to be explicit about it. Likewise, if
you've got arguments, you need to tell it type of
the arguments. It can in further return value, but you
need to give it the types of the of the
function parameters or function argument. So when I renamed the
TF file from JS tots, I also needed to put
in the relevant type information. After all, that's the whole

(01:03:16):
point of moving from JS tots, and I wanted to
see it handle that type information. And as I said,
I moved just that one file. I pushed it in
and verified that everything that all the build works, that
the unit tests work, that the end to end test work,
that deployment is created, that I can actually use that

(01:03:37):
created deployment, and I even looked in the disk folder
to verify that the JS file was created for that
TS file, and then it contained what I expected it
to contain. So it was that that anal about it, really,
just because again it was that first file. After that

(01:04:01):
you can be more relaxed than your attitude. I then
intentionally introduced a typescript error into that file to see
that it failed. Because if you don't see that everything fails,
how do you know that it actually even working and
not just doing something stupid. So I put in intentionally

(01:04:23):
a typescript error. Shane, let's say something supposed to be
a string. I said that it's a number, and saw
that typescript you know, failed and the build failed, And
then I fixed it again and saw that the build
passed again, and I and I and as I said,
I pushed it into that branch and saw that the

(01:04:47):
CI process failed, passed, sorry, and everything was green. But
again I didn't merge it yet. Instead, I deployed it
to our testing environment, and I made sure that I
could properly debug it both using vis code and web Storm.

(01:05:13):
We've got a rather complex complicated for various technical reason
environment for debugging, which involves remote deployments and stuff like that.
It's not really important in the context of this discussion.
I won't go into the details. I then asked some
of my colleagues to test out that branch as well,

(01:05:34):
see that they're also able to use it and debug
it and that everything just works for them. Again, I
was very very careful about it. After I got the
okay from those colleagues, I rebased the branch, and because
we use rebase rather than merge, because it took me
a while, so obviously other changes were done in the

(01:05:55):
project during that time. So I rebased and finally merge
that pr and finally we had a version that supported
Typescript and had one and exactly one TS file in
that project out of those one thousand JavaScript files. And

(01:06:17):
I also made sure not to have to do that
right before the weekend, so that I don't break everything
just before the weekend.

Speaker 1 (01:06:26):
Well that's the general rule anyway, right, you don't do
major deployments on Friday.

Speaker 3 (01:06:32):
After merge, I verified that the main branch again was
also built correctly, that all the end to end test paths,
that everything worked correctly, I was ready to roll back otherwise.
Fortunately I did not have to. I then basically informed
everybody else about this change, and we started discussing about

(01:06:53):
how we can gradually move from JS to TS. And
we've been doing it very slowly since then, and that
more or less concludes where we are now. And it was,
as I said, it was a lot less trivial than
I expected it to be. Now some of the issues

(01:07:15):
had to do with our own unique environment. But still
now I have heard other suggestions about how to go
about it. For example, convert your repo into a mono
repo type environment, start pulling out self contained files as
separate packages within that mono repo, and since there are

(01:07:38):
new packages, just make them TS from the get go.
You can do that. You still need to be very
careful about how you preserve history and stuff like that.
It's not trivial, but that's not what I did in
this project. Anyway, I might actually have to do that
other way in that project with JavaScript and flow, because

(01:07:59):
I don't take I can get both JavaScript and flow
to work within the same package. Anyway, I'm done.

Speaker 1 (01:08:08):
So, how many files have you actually now that all
that's in place, how many files that you actually.

Speaker 3 (01:08:13):
Converted not so many so far, approximately ten out of
the one thousand. This will take time. The biggest problem
in converting files is that, well, you know, sometimes you
run into complicated types that require generics and stuff like that,

(01:08:34):
and you need to get the team up to speed
about typescript because a lot of them have been basically
just using javascripts, so they're not as familiar with typescript
as ideally they should be, and you need to allocate
time for that as well. But the bigger issue is
that the move to typescript has actually uncovered various bugs

(01:08:56):
in the code, places where null tests were missing. So
one of the great things about typescript is the typeescript
basically having is explicit about something being that can be null.
So it's something is can be either if something is,

(01:09:20):
then if a variable is of type number, it cannot
be null. It you basically, if you wanted to also
be null, you need to explicit be explicit about and
say number or null. And it uncovered a lot of
places in the code that null tests were not properly

(01:09:43):
put in place, or places where library third party libraries
were used and a version was updated that changed the API,
but the way in which that library was used, wasn't updated,
and the wrong parameters were actually passed into certain APIs.
Now somehow it worked, but now Typescript complains about it.

(01:10:06):
Then you have to fix it, and you have to
think about, you know, how do I fix it? It
actually requires changing the actual execution code in order to
get Typescript to be happy about it. If you're passing
something which is a number into something that should be
a string and it happens to work, you know, you

(01:10:27):
don't just want to cast a number a string. You
want to fix it. You want it to work properly.
So the biggest time consumer really so far has been
basically fixing bugs that Typescript uncovers.

Speaker 1 (01:10:42):
Yeah, I've been so I do a lot of work
leral on PHP in my day to day, and so
the past couple of weeks I've been working with PHP STAN,
which is a PHP static analysis tool, hence the name STAN.

Speaker 2 (01:10:54):
And STAN. I definitely have a love a lot of
hate relationship with it. Well.

Speaker 1 (01:10:59):
A couple of things that I found out is one
cases you're correct, it does the similar thing where you
have to declare okay, it can be the this or no.
You know, I have to clear the options well, a
lot of times, what I find myself having to do,
and I'm curious to see if you've run into this
as well, is having to restructure working code for the tool.

(01:11:24):
So in other words, if if you have a step
that has that you know, does some chaining and does
multiple things, sometimes you have to break that apart so
the static analysis tool can realize, okay, this variable is
of this class and then you can go on into
it where it works fine, you know with with when
things are chained together, but you have to break things
apart strictly for the static analysis tool. That was probably

(01:11:48):
one of the bigger frustrations that I've you know, in
dealing with that, that I've had to fight.

Speaker 3 (01:11:54):
Look you can, yeah, but I'm thinking about how to
phrase it. First of all, I'm not familiar with PHP
stand but I can say that typescript is amazing in
the in the sophistication of the static analysis that it
can perform. So, for example, if something is if a variable,

(01:12:16):
as I said, is number or null, and then you
do an if in the code and check that it's
not null, then it knows that within the scope of
that if the type of that variable is now assumed
to be number and not number or null. It's really
smart about how to infer the correct type. So the

(01:12:38):
value that the type of of of a variable actually
changes according to the code because of various type checks
that can exist in the in the runtime code. These
are known as type guards. We actually talked about in
the in the recent episode that we did with the

(01:12:58):
Lyran and Ariel. You were in that episode, I believe, right, yes, yeah,
so we actually talked about that. So Typescript is amazingly
sophisticated about such things. The fact that you need to
break the code into smaller pieces. From my perspective, that's
actually a benefit. I like my code broken down in
smaller pieces.

Speaker 1 (01:13:21):
Right, and I tend to be that way too. You
don't want to, you know, have fifteen chain functions on there,
just for the sake of having shorter code. If a
little more broken up code is easier to read. But
when it's already working, you got to break it up
just for the tool, it can be frustrating.

Speaker 3 (01:13:35):
I agree with that, and that exactly goes to the
point that I mentioned that the biggest challenge so far
has been those situations in which we actually had to
change the JavaScript in order for Typescript to be happy
about it, and in most cases the change was for
the better. It was a good change, but it's still work.

(01:13:58):
And once you know ideally, you're thinking, I'm just adding types,
so all the tests should pass because the types are
removed from the generated code anyway, so they don't impact
the tests. But once you have to start modifying the code,
you also start breaking tests, which is another reason why
you should have good test coverage when starting projects like that.

Speaker 2 (01:14:24):
Right, sure, Okay, I think.

Speaker 3 (01:14:26):
We're more or less run out of time.

Speaker 2 (01:14:28):
Yes, I believe so. Quick question.

Speaker 1 (01:14:32):
You had mentioned at the beginning that you had documented
this on your internal wiki, and we've got this episode obviously,
but are you going to put this out in written
format publicly, like a blog post or something.

Speaker 3 (01:14:44):
I probably should.

Speaker 2 (01:14:46):
I seem like some pretty valuable information.

Speaker 3 (01:14:48):
I think so too. As I said, maybe it exists somewhere,
but I just couldn't find it, but it probably is.
Probably should. The only problem is that I I don't
really have a blog anymore, so I need to figure
out about where to actually put it. I'm also, as
I mentioned, I think I may want to submit it

(01:15:09):
as a conference talk, not that you know it prevents
I can do all three. You know, we now have
a podcast. I can have it as a blog and
as a proposed conference talk. I just need to figure
out where to put that blog post. Probably should You're.

Speaker 2 (01:15:25):
Right, all righty, So that will move on to picks.

Speaker 1 (01:15:29):
Picks are the part of the show where we can
talk about anything else, or we can talk about tech
if we want. I'll give Dan throw to break since
he's been doing most of the talking here, and do
my dad jokes of the week. Maybe we'll get a
laugh from Damn. Maybe not so recently. You know, I
had to change a password, and I normally use a

(01:15:51):
password manager, but this particular time, we'll say this was
back before password managers. I need a password that had
eight characters, so I did snow White and the Seven
Dwarfs because seven plus one is eight. So I've got
three kids, and when our last one was born, my

(01:16:13):
wife was in labor and I tried to tell her
jokes to distract her from the pain, but she didn't
last at all. It must have been the delivery, right man. Yeah,
this is this is a recent one. I love it
because it's somebody pointed out to me on Twitter it's
both funny and inspirational. Says when you think that all
is lost, there's no hope left. Just remember the lobsters

(01:16:35):
in the tank in the Titanic's restaurant.

Speaker 3 (01:16:37):
Oh that's that's a good point.

Speaker 2 (01:16:39):
I'm free, I'm free. Anyway, Those are the dad jokes
of the week. Dan, you got any picks for us?

Speaker 3 (01:16:45):
Yeah, not that many, but a few. So one pick
I have is a friend of mine here in Israel
called the lead Josef great confidence speaker by the way,
So he created a very interesting project. There's he actually

(01:17:06):
put on X the whole story, a thread about the
whole story about how they built this thing. It's an
incredible read. Unfortunately it's an Hebrew I know that it
has a built in transition capability, but still but anyway,
this this really interesting thing is called get mcph. I

(01:17:27):
spoke about MCP with Jack Hankton when we had him
as a guest on the show. MCP I forget what
it's what it stands for, but it's basically a standard
protocol for connecting stuff to llms. So the llms can

(01:17:48):
actually use that protocol to get additional context, additional information,
or to control various external resources. So they created something
called get MCP, which basically makes it possible to instantly
create an MCP server from any getub project and then

(01:18:10):
you can hand it over to something like Cursor and
immediately Cursor has context based on that getub project, which
is really interesting. So if you want to learn about
some getub you know, you can obviously clone a getub
project and open it within you within Cursor and then

(01:18:32):
you get context. But suppose you want to you're working
on your own project that uses some other project APIs
from some other project, and you want Cursor to be
able to help you generate code for using those APIs. Well,
with get MCP you can just point. It's literally just

(01:18:53):
replacing the word GitHub in the URL with geitub dot
com with get mcp dot io. That's literally it. That
URL will immediately work. You just hand over that URL
to Cursor, for example, and then and instantly Cursor has
context about that project. It seems like magic to me.

(01:19:18):
I've not tried it myself yet, but it literally seems
like magic. Some of the videos that they have on
their website literally seem like magic. It's it's pretty amazing
the stuff that you can do. These days with these tools.

Speaker 1 (01:19:31):
So MCP stands for you mentioned the CEE. It's a
model context protocol.

Speaker 3 (01:19:35):
Right, it's a this protocol proposal that's supposed to be
a new standard for connecting llms to stuff, and uh,
it's pretty amazing what they've achieved. So it works with Claude,
it works with Cursor, it works with Windsurf, it works
with vis code. As I said, I've not tried it yet.

(01:19:58):
I've only learned about it effectively yesterday and I haven't
had a chance to play with it, but it seems
pretty amazing the fact that you can literally just by
changing replacing the word in the URL from getub to
get MCP and immediately get it to work, it's just
amazing to me. And the other pick is I think

(01:20:25):
I mentioned that I'm speaking at a conference in Romania
towards the end of May. It's called JS Heroes. I'll
be talking about how modern web frameworks use or prefer
using RPC as the communication protocol between the front end

(01:20:46):
and their back ends. If you're thinking about frameworks like
next JS or like quick or like solid, they're all
or ten stack. They're they're kind of moving over to
using our PC, So I'm talking about what RPC is

(01:21:07):
and why they're doing it, and what are the implications,
the good sides the bad sides of this transition. And
the thing is that, first of all, I have to
say that Jas Heroes Conference, the agenda looks amazing, The
speaker lineup is really awesome. The interesting thing, though, is
one of the organizers is Tagus. We've had Tags on

(01:21:30):
their show a few times. Tags is an amazing person,
and he kind of tweeted recently that a lot of
conferences have effectively disappeared in the past year or two,
that there are very few conferences actually still running. And

(01:21:51):
now he should know because he's very involved in the
in the conference scene. He does like thirty conference talks
a year or maybe even more. He's really into it.
So if he's saying that a lot of conferences are
shutting down, I trust him about it, and it sounds
really unfortunate to me. My information myself is anecdotal. I'm

(01:22:14):
looking at services like sessionize, and it does seem to
be the case that there are a lot fewer conferences
out there. That's really unfortunate, and it seems to me
that we should be supporting the conferences that are still
running by participating by buying tickets, and attending by sponsoring.
So if you can help a conference organizer keep the

(01:22:37):
conference up and running, please do my last pick since
I mentioned Tagous, Tajos has his own podcast these days.
It's called Contagious Code, which is a nice play on words.

Speaker 2 (01:22:52):
I was going to say, yeah, that's a good name
right there.

Speaker 3 (01:22:55):
And he recently posted a new episode which is really interesting.
Usually most of his episodes are about he interviews people
you know in a same similar vein to the way
that we do. And and you know, even though we

(01:23:16):
have a podcast, he has a podcast. I have no
problems saying that his podcast is awesome. I highly recommend
listening to it. In fact, I was a guest on
his podcast a while back. But the reason that I'm
mentioning it is that his latest episode, that he basically
put out a week ago, is not an interview. Rather,
it stages himself speaking for one and a half hours

(01:23:40):
about the state of AI in twenty twenty five. He also,
you know we mentioned MCP. He talks about MCP in detail.
He talks about agents, he talks about RAG and much more.
And I'm about halfway in. It's excellent. I highly recommend

(01:24:01):
listening to that episode. I hope we can get them
on our show as well, but regardless, I recommend listening
to that episode to get really up to speed about
the technicalities of AI in twenty twenty five. And those
will be my picks for today, all.

Speaker 2 (01:24:15):
Right, So with that we will wrap things up.

Speaker 1 (01:24:19):
Hopefully this provided good information from you that for you
that are going to be converting code basis to typescript
and Dan, I can people follow you on Twitter if
they want to get info or do your Twitter or
where can they find out if you publish this written
form somewhere?

Speaker 3 (01:24:37):
Well if if and when I do, I'll obviously announce
it on X, so yeah they can, and if they,
if they're on X, please do follow me. I'm Dan Shapier.
That's d A N S H A P P I
R on X. I'm also on Blue Sky if you

(01:24:57):
prefer that platform instead, so I'm there as well. On
Blue Sky, I'm also Dan Shapiir, so find me there
as well. Follow me here or there or anywhere. I'll
gladly follow you back. Also glad to get feedback about
our podcast in general, So feel free to contact me

(01:25:20):
and that's.

Speaker 1 (01:25:21):
It, alrighty, And if you want to get a dad
joke today, if you're amazed the quality of my curated
dad jokes, you can follow me on x slash Twitter
at Wonder nine to five. All right, with that, we
will wrap this poppy up, thanks for listening, and we'll
talk it to you next time.

Speaker 3 (01:25:37):
Bye,
Advertise With Us

Popular Podcasts

Dateline NBC

Dateline NBC

Current and classic episodes, featuring compelling true-crime mysteries, powerful documentaries and in-depth investigations. Follow now to get the latest episodes of Dateline NBC completely free, or subscribe to Dateline Premium for ad-free listening and exclusive bonus content: DatelinePremium.com

Stuff You Should Know

Stuff You Should Know

If you've ever wanted to know about champagne, satanism, the Stonewall Uprising, chaos theory, LSD, El Nino, true crime and Rosa Parks, then look no further. Josh and Chuck have you covered.

Law & Order: Criminal Justice System - Season 1 & Season 2

Law & Order: Criminal Justice System - Season 1 & Season 2

Season Two Out Now! Law & Order: Criminal Justice System tells the real stories behind the landmark cases that have shaped how the most dangerous and influential criminals in America are prosecuted. In its second season, the series tackles the threat of terrorism in the United States. From the rise of extremist political groups in the 60s to domestic lone wolves in the modern day, we explore how organizations like the FBI and Joint Terrorism Take Force have evolved to fight back against a multitude of terrorist threats.

Music, radio and podcasts, all free. Listen online or download the iHeart App.

Connect

© 2025 iHeartMedia, Inc.