Explore how software engineers use Effect to build reliable, production-ready software in TypeScript.
I'm coming to them and saying, learn this
entirely new way to write TypeScript.
Trust me, bro, it'll be worth it.
And it helps to like have some examples I
can point to. And I think I recall one
team member of the one actually with
prior TypeScript experience.
He he trusted me enough to give it a try.
And he said it really clicked for him
when he was writing tests, actually,
because he mocked some layer or
wrote a test layer for for some service.
And he's like, oh, this is what I can do
with this and like isolate just certain
services and tests
just the core business logic.
And it's super helpful there. But
that was the moment that clicked for him.
I think we've all had sort
of that that moment, you know, that that
is just like, oh, this is
what this is capable of.
This needs to be sort of
everywhere on a code base.
Welcome to Cause & Effect, a podcast
about the TypeScript library and
ecosystem called Effect, helping
engineers to build
production-ready software.
I'm your host, Johannes Schickling, and
I've been building with
Effect for over four years.
With this podcast, I want to help others
understand the powers and
benefits of using Effect.
In this episode, I'm talking to Adam
Rankin, CTO of Warp, a YC-backed payroll,
payments, and HR platform for startups.
In this conversation, Adam shares his
path from Rails to TypeScript and how
Warp incrementally adopted Effect across
a single fast-moving monolith.
Let's get into it.
Hey Adam, it's so nice
to have you on the show.
How are you doing?
Doing well, thanks for having me.
Excited to be here.
Yeah, I'm really excited to
learn more about Warp today.
But before we talk about Warp, do you
mind sharing more about who you are and a
little bit of your background?
Sure, so I'm Adam. I'm the CTO of Warp.
I came to Warp maybe three years ago,
started it with the CEO who
I actually met on Twitter.
Before that, I've only
ever worked at startups.
I have experience building web apps of
all sizes using mostly Ruby on Rails.
And I trained as an engineer in school.
That is awesome.
So you mentioned like most of your
background being in Ruby on Rails.
Can you already foreshadow a little bit
of like how you went from
Ruby on Rails to TypeScript?
Did that happen at Warp?
Did that already happen
as sort of a prior role?
Sure, so I actually started
my career in Ruby on Rails.
I worked at a startup while I was in
school who was
building a web app on Rails.
And I actually didn't know any
other way to build a web app.
It's a great experience, Rails.
It's very opinionated.
Ruby is a very sort of
easy language to write.
I like to say if you know English, you
know Ruby because you're just kind of
like guessing the
method names and they exist.
And then I actually sort of took a long
break from it while I was writing some
Python and various backend services for a
bigger company, a banking company.
And then when it came time to start Warp,
we kind of were
choosing our initial stack.
And we were choosing something that could
make us move as fast as possible and ship
early features to customers.
And at the end of the day, I basically
googled, you know, what do
people use in web apps nowadays?
And it's like, okay,
Next.js has some cool logos.
Let's try this.
And that's sort of how we
started with TypeScript.
I actually want to linger a little bit
more on that because I feel like that
there is still some aspects about like
Ruby on Rails is not bad it is like I'm
not sure numbers wise, I wouldn't be
surprised if it has more usage than ever
before, just because like the well, many,
many people are building software in
many, many different ways.
I think like one of the like North stars of
like what developer experience can be
like that I think in many regards, the
TypeScript ecosystem has not been able to
replicate partially due to just the
constraints of the language, but also
like there's some like vibes and some
like maturity and some like elegance of
the ecosystem that I also
think like kind of culturally is
quite different in the JavaScript and
TypeScript ecosystem and I
don't agree with like all the
perspectives that the Ruby
on Rails creator DHH has.
I still think that there's
like very interesting ideas.
So I'm curious whether you're still kind
of like keeping up with the developments
where it's like Ruby on Rails is going
whether you're still can derive like some
inspiration from that ecosystem.
I haven't kept up with the development
lately. It's funny you say that because
Rails is definitely lingering. It's
definitely still strong.
You know, every I feel like once a month,
you find out like a new website or some
new product that has billions of users or
sorry, millions of users and it's like,
wait, they're on Rails. No way.
So many like of these huge products
started on Rails and I think it's because
it has so much out of the box that you
you need to run like like jobs for
example, you know, you pick up a
TypeScript project and you're like, how
do I queue up some background job and
like respond to my users API request and
in Rails, that's kind
of trivial in TypeScript.
There's no opinionated way to do that.
People are doing all kinds of different
things. You have to kind of build your
stack more and think about it.
I think good DX tends to always win. That's
why we see Next JS on Vercel winning.
Rails is super easy and it kind of
abstracts away the complications of doing
a lot of infrastructure heavy activity.
And I think that's something that the
TypeScript ecosystem in
general is, you know, behind on.
Yeah, I definitely agree. I think what
you've mentioned about like the queuing
system or like any kind of common
canonical thing. Yes, it is possible with
TypeScript, but you like open 10
different blog posts that show you how is
like any find 10 different ways.
Whereas like in the Ruby and Rails world,
like you have 10 blog posts and they all
show the same like there's just like in
one world you're kind of like at ease
where you feel like okay like all roads
where you feel like okay like all roads
where you feel like okay like all roads
lead to Rome and like in the TypeScript
world is like wait what like no this is
like entirely different
stack like should I use that?
Oh no, people like in Reddit say like
it's dead. Should I use that? And it's
just like it's a very different world.
And I think there's like a lot positive
to be said about about that where like I
think it's a it's a richer place for
different ideas to like be
be explored at the same time.
But there's also the kind of like
confusion that and sometimes even like
like paralysis of choice that
comes alongside. And
you see a similar thing also in
other language ecosystems, Java obviously
being a big one, but I think in Java, you
have something like Spring etc that has
more of like that that rails kind of
coercion in in one direction.
And I think this is also for if we're not
bringing things back to to Effect, what
we want to talk today about.
I think this is also one of the big
pieces of potential of effect. Yes, it
gives you individual building blocks, but
they all fit together in one holistic
cohesive way of building software that I
think can actually bring a lot of the
nice coherent aspects of something like
Ruby and Rails or something of
like Spring Boot to the the TypeScript
world. And so yeah, and I think we're
going to hear quite a lot about that
today is like in the way how you're
building Warp. So thanks a lot for for
sharing your background and like
which twisted paths you've
taken through the world
of software development.
Maybe before we dive into all things
technical, can you share a little bit
more about Warp? So you mentioned you
started it together with a friend who you
met over over the
internet three years ago.
Like how quickly did things develop? Like
I think today it's no longer just the two
of you, but you I believe like you you
raised a fairly big round recently.
Can you share more about the company and
maybe starting with what is Warp? What is
the product and the goal of Warp?
Yeah, definitely. So we have sort of a
funny origin story. I met the
founder on Twitter in sort of this
pseudonymous era where where people were
using like fake Twitters to sort of meet
each other and he had announced a project
that he was working on
and he raised money for
I thought it was cool. It was actually a
consumer social app. So I had joined it
and and we kind of connected on there
And he had posted on there that he was
looking for engineers and I was sort of
looking for my next thing at the time.
So we actually met each other and agreed
to work together before we knew each
other's names. I always like to tell that
story because it's super funny. I was
visiting my parents at the time
And I was like, oh, I have sort of a job
interview and they were like, you know,
with who? And I was I was like, I don't
know his name, so I
can't really tell you that.
And there was a peak of covid as well,
right? Yes, yes, this is like 2021.
at the time for some
personal context, I was like kind of
playing with the idea of starting my own
thing. I had left my previous role. I was
actually living a nomadic life. I was
living in a different city every month.
So I found this social app. I met the
founder of it. We agreed to work together
on this social app. It
was Swift UI, AWS, Firebase.
And when you build a consumer social app,
you need to monetize it
eventually. And there are only two ways
to do that. And it's to get people to pay
or to get people to see ads.
And if you're not growing with some
insane K factor, then you're not going to
make any money on ads. So we ended up sun
setting the project and sort of going
back to the drawing board and saying, you
know, what can we build?
And again, this was mid covid. We were
using a competitor, payroll product at the
time. And our sort of insight was that,
you know, remote work is not going
anywhere. There's a lot of compliance
work in paying remote teams and paying
people across the globe
and across the country.
There are thousands of tax jurisdictions
like what if we could just take all of
this off the plate of founders and build
a payroll payments HR products tailor
made for startups and founders.
So that sort of was our initial insight.
We joined YC and started talking to
startups and other small customers. It's
like, what do you need? Let us handle it.
And that's sort of how we got started.
And our roadmap has sort of been built
from there. We've like built a lot of the
table stakes features you need. And now
it's very product driven by like
what people are requesting.
And then sort of in conjunction with
the whole covid thing, the LLM
revolution has sort of come along. So
we're now exploring ways to be more AI
native and use these things for
automating different processes that that
we don't want to do.
And our customers don't want to do so.
Hopefully that's that's a good background
on kind of how we started and what we do.
Oh, most certainly. And I want to make
sure that we come back to the AI native
automation part as well as that's another
key interest of
mine currently as well.
But I want to linger a little bit more on
sort of like your personal relationship
to Warp as you went from building a
consumer app to now building a software
for other startups, etc.
I guess much more B2B. And I think there
is kind of two perspectives on like how a
startup founder can end up building
something either kind of out
of love or out of frustration.
What I mean with this, you love something
so much. So you want to build something
that's just like fundamentally good and
like makes it even better.
Or you're so frustrated with an
experience that you say, like, OK, this
needs to be solved. And I think you're
falling into the ladder.
But I think what is tricky about that as
a founder myself, like I had plenty of
like very frustrating experiences
throughout my life where I felt, OK,
there can be something better.
But I also then pictured myself in a life
where I'm not like solving this problem
for 10 years and I would not derive a lot
of joy of like getting and becoming an
expert at tax codes in France.
I'm like frustrated enough with like
barely trying to stay
afloat with the German ones.
So I'm just curious like how your own
perspective is sort of
like has evolved on that.
I'm very glad you're all in solving this.
So I have a better
experience not being exposed to that.
But how you're finding your own balance
of like that frustration that you wanted
to address, like you're flying even
closer to that sun of
frustration to like figure it out.
Maybe you can just
reflect a little bit on that.
Yeah, yeah, it's a funny question because
payroll tax codes, it's like the
unsexiest thing you
could probably imagine.
It's like B2B SaaS payroll.
I have like a few answers to that.
I think one is like the fact that not
many people could imagine themselves
doing it is sort of good for us because
we're happy to kind of go in and like get
our hands dirty and let's
figure out what needs to be done.
And I think the actual joy of building a
product comes from seeing a customer use
it the right way, seeing a customer be
satisfied and not have to worry.
One joke we like to make is that we pride
ourselves on least required user minutes.
So we have some founders that have like
not logged into our product in months and
it's just sort of running in the
background for them.
So we like take a lot of joy in people
not actually having to use our product
because we've become
experts in payroll and tax.
And yeah, I definitely know more about
payroll than I ever thought I would.
But I think that building a intuitive UX
for something that's so boring, I think
with sort of these unsexy industries,
people come to expect unsexy and clunky
products and we're trying to change that
and that's really fun to me.
All right. Yeah, that definitely
resonates. And so like if you think about
this as like this delta between like very
frustrating experience without work to
like joy and delight and like blissful
ignorance of like all the stuff that
needs to happen behind the scenes.
Like if you can get it, delta is probably
pretty wide. So thank you for doing that
work that no one else has to do it.
So yeah, I don't want to get much
closer to tax codes, but I want to get a
slight more intuition and context on like
the people of building Warp.
So I've mentioned that you all raised, I
think, a Series A recently and that
allows you to continue to grow.
So how many people are currently in the
company and how many
of those are engineers?
We have 16 people currently in the
company and our
engineering team right now is four.
So we've we've kind of tried to remain
small, even though we just raised a big
round where we're hiring
for all engineering roles.
So if you're listening to this
joinwarp.com/careers
We like to move very fast and remain sort
of nimble and kind of cut out processes.
Yeah, so we've tried to remain small.
We're very conscious of
growing too fast, but also hiring.
That is awesome. And that definitely
resonates. And like for I think a
contemporary example of like who has done
that really well for a long time is
Linear, where like their tax code
equivalent is task management.
And they've built an absolutely amazing,
delightful experience
for project management.
And I think maybe you're thinking of
yourself like being part of the same
category of like next
generational software.
And the parallel I definitely want to
draw here is they've remained super,
super small for a very long time in
regards to engineering team.
And you mentioning that you're still just
four people like I
definitely applaud you for that.
I think this allows you to just have like
a velocity and agility that is hard to
match when when you're growing and
growing in terms of the engineering team.
I think at some point that is inevitable,
but like remaining small and like keeping
the bar high for engineering talent, I
think is definitely the way to go.
So maybe you can share a little bit more
on like the background of the other
engineers, like when we are now drawing a
bridge to Effect, which has not
too many similarities with
Ruby and Rails in that regard.
That is like more coming from like the
functional programming world, even though
that is not like the core
essence of Effect these days.
This is where it had its origin story and
still draws a lot of people to Effect.
And it requires a little bit of like a
entry ticket to learn a few new things.
So I'm curious, like what was sort of
like the catalyst event for
Warp getting on board with Effect?
Yeah, I guess to say a bit about our
early team, I mentioned Rails.
One of our other core engineers came from
a huge product
running on Rails and React.
And our other team members have come from
a big Python world, especially the guy
who's good at AIs,
written a lot of Python.
And then the last member, I guess I can
just enumerate the whole list
since it's since it's small.
He was a new grad, so he was actually
very interested in Rust and systems
programming languages.
So not actually much
TypeScript before we started Warp.
I think that the way, if I could tell the
story of how I first came across Effect
was that I'm in sort of these online
circles that expose me to things way out
of anything I need to
write B2B SaaS payroll software.
And I'm sure you know a lot of these
communities that they're like heavy
systems programmers.
You'll find some very like eccentric
people writing like
the craziest software.
I'm very interested in
like type systems in general.
And I was writing a lot of random side
projects in Haskell.
Yeah, and I always love that experience.
But I just couldn't justify for the
business like starting to
write something in Haskell.
It would be like such a big
learning curve for people.
It would be like, how
do we deploy this thing?
How are we going to build our entire
pipeline around this?
I can't justify that when you're trying
to just ship features.
But anyway, back to how I found Effect.
I think it was in these circles like some
of these guys obsessed with type systems
are like, why would
anyone ever use TypeScript?
It sucks.
Like only Effect is like
doing something decent with it.
And I'm like, okay, like take that with a
grain of salt, but
file it away for later.
Kind of go to the Effect docs eventually.
A bit daunting like, all right, what is
this thing on TypeScript?
And eventually sort of through osmosis
and seeing like code snippets of people,
especially like the
Vercel team posts a lot.
Like, okay, this could be nice.
And then looking for sort of some project
to start it with some like
some excuse to write with effects.
And finally, we had some little proof of
concept very isolated from our product
that we were going to build.
It was actually an AI browser agent.
So it was automating browser actions and
computer use with AI.
And I was like, you know what, screw it,
I'm going to use Effect for this.
And that's sort of my first experience.
It was very slow going.
There is definitely a learning curve.
And that's sort of the impetus.
And I guess I can mention sort of to why
I was even ready for
something like Effect.
We like started early on TypeScript, as I
mentioned, because it was just like the
easiest way to get started.
You can move very fast.
And it's very optimized
for like happy path coding.
It's like, you know, those old TVs with
the antennas on top, you like hit it a
bunch of times and
eventually it like starts working.
It's like static and you just hit it.
That's how it feels like coding in
TypeScript or in JavaScript without like
proper result types
and dependency injection.
It's just like, okay, this error happens.
Let me like add some
conditional for that.
And then like eventually like a thousand
times later, you have like something that
works and you're way too
scared to touch it again.
That's how it feels like coding in
vanilla sort of TypeScript, JavaScript.
So I'm like, all right, this
is like just not sustainable.
We have a product where, you know,
everything has five or six different
states it could be in, statuses.
And then every and then there's like, say
20 objects with 20 different statuses.
Like it's just an exponential amount of
different statuses things can be in.
So a lot of antennas
that you need to slap.
Exactly.
That's what I'm saying.
So I'm like, I need
something that can do this better.
And so that's why I was like very
receptive initially to Effect.
So this is one analogy I make quite a bit
of sort of like the sugar high versus
eating vegetables, like
getting building something quickly.
This is like, I mean,
JavaScript is like perfect at that.
But then like when you like run into
those problems where in production you
see undefined is not a function and you
have no clue where
this might even happen.
Maybe the the strike phrase is like, it's
somewhere like some esoteric place and
you're just like completely lost and easy
kind of like dawns on you.
Yes, I should have eaten more vegetables.
I should have built
this in the right way.
But now to kind of like get from place
A to place B where like
you're currently in
undefined is not a function place.
And you're in that place where everything
is nicely modeled like
that can be quite daunting.
So you've taken the plunge with the A.I.
browser automation project.
Can you share a little bit more of like
what that looked like?
What were you trying to did
you build that from scratch?
Did you have like an existing version
that's like has worked in happy path
land, but you now want to make production
ready or like take me through like the
adoption journey of Effect
for that particular project.
And how did you involve
your other team members?
So this project
was very, very isolated.
It was a from scratch product.
We haven't done
anything like that before.
It was it was sort of R and D just kind
of going out seeing
if this would work.
And and actually in hindsight, like that
was probably not the right place to start
with Effect because we were just trying
to build a proof of concept.
But I was like so dead set on on
improving our workflows that I was trying
to use this thing I wanted to use.
You know, startups are great
because you can just kind of choose your
tech stack as you go
along and try things out.
You're not like constrained to other
internal libraries or anything.
So super excited to try it there, even
though it wasn't the best fit.
I was using this library called Stagehand
from Browserbase that kind of
integrates with different providers and
and read sort of the DOM to extract
actionable things in on any
web page and then act upon them.
So I was just kind of like wrapping
functions with Effect and
like seeing how it worked.
Like how does this
dependency injection thing work?
So that's sort of how it got started.
I was actually working on that
project pretty much alone.
And then we built out the proof of
concept where like this can work, we're
going to productize it later.
But I need to go back
to like building product.
So it was sort of a decent amount of time
between that experience and all right, we
need to get this into our product.
And I think the
sort of thing that pushed me
was actually hiring new people.
We have this like mess of of old happy
path code in some places that that needs
to be like more productionized and and
part of it is like an ego thing like, oh,
I have to show this code to someone else.
I have to like someone
else has to work on this.
We need to turn up before
before your friends arrive.
Exactly, exactly.
I'm like, how can I expect like a new
team member or like five members?
I know the feeling this is like you want
someone like it works the right way, but
like you gotta you gotta clean it up now.
Yes. Yeah.
So that that's when we were sort of like,
all right, we need a
better developer experience.
We need everything to be more testable,
everything, all the errors enumerated.
Let's like sit down and sort of if we
were in an ideal world,
what would our stack be?
That still allowed us to move very fast
and allowed people to onboard quickly and
write both front end
and back end very quickly.
And we sort of came up with that answer
and we were like, all
right, let's just go for it.
And just to share sort of like one
anecdote I've heard from a couple of
other companies who are using Effect.
That is it's actually interesting that
they also hired people with no prior
TypeScript experience.
And this was sort of like the first time
really where someone went super deep on
TypeScript and went right into Effect.
I was like me as a Effect team member,
this felt initially kind of
counterintuitive because I came to Effect
because I've done TypeScript for like a
decade, suffering through the
limitations of TypeScript.
And then I saw Effect
as the answer to that.
But I've already learned sort of like all
of like those mishabits of like holding
it in this particular way that like tribe
knowledge has just
been passed down to you.
But people outside of the TypeScript
ecosystem, they've never been burdened
with all of those like crafty experience
like you're using this way not
because it's particularly nice, but just
because you have to do it this way.
But if you're new to TypeScript and new
to Effect, then like you're learning it
the right way right away.
And it's weirdly enough, it's actually
easier to learn Effect if you don't have
that year's worth of like using
TypeScript already in
this particular way.
And so that really resonates now.
Well, it is almost like writing or
reading a new language.
Like you never really use generators in
like your day-to-day TypeScript.
Like you'll never see
that in a React app.
And then the type signatures are just
completely different from
something you write yourself.
Yeah. And I think that's the most useful
mental model that you can give like a
newcomer, being
unburdened from like things before.
Yes, the type signatures, etc.
I think that's helpful to have an
understanding of that.
But I think this is actually one of the
most elegant parts about TypeScript, how
nice the inference works.
But then sort of like to absorb the
mental models of the concepts, etc.
Like if your brain is not constantly
racing of like trying to bind it to a
prior TypeScript thing you've been using,
but just like absorbing
that in a more like free world.
I think that's actually
kind of works super well.
And I think this seems to work super well
for people with prior Rails experience.
And also for that new grad you've
mentioned coming more from a Rust
background, since I think Effect is
actually the closest thing
to Rust we have in TypeScript
in terms of like applying systems
programming mindset
and rigor to TypeScript.
Yeah, I definitely agree.
Going back a bit to writing Haskell,
there's this meme in Haskell where if you
pass the type check,
then your code works.
In vanilla, like JavaScript and
TypeScript, I heard someone joke one time
that TypeScript is a VS Code extension.
And that's really funny to me because
types are just suggestions there.
They're not actually real guarantees.
And Effect is sort of the layer that
makes it feel like my
type is a real thing.
I can actually trust that this thing here
is this thing it says it is.
I go so far in writing
production ready code.
Yeah, so as you then like introduced
Effect into like that first R&D project
and then you brought it
to the rest of the system,
walk me through how you've like, how you
cleaned up before new people joined and
how did Effect step by step.
How did you migrate
your project step by step?
I guess we started with sort of
asking the question, you know, how can we
do this incrementally?
And the first place we sort of used it
was we're using these
NoSQL stores in some places.
And we were like, all right, let's try to
use Schema and just the general Effect
dependency injection to try to more
strongly type some of these NoSQL stores
we're using and see if we
can like parse out our data.
We were using like a lot of places just,
you know, let's get this basically
document object and like just write as
thing at the end of it.
And then it's like that thing and we run
into tons of issues doing that with
that's that happy path coding, you know,
so let's schema parse all of these.
Let's like, be sure we have
the things we say we have.
And that sort of led us to starting to
wrap our like database drivers and our
various domain objects
in schemas and context.
And we're like, you know what, let's just
like, forget that, like forget trying to
like rewrite old stuff.
Let's just come up with our
new stack and and write it.
And so we actually
completely wrote a new server.
It's funny the way it
worked because the other sort of DX
improvement we were looking to get was we
wanted to write less
hooks on the front end.
We wanted Open API specs so that we could just
generate all of our front end code.
So we're looking at different ways to do
that. We eventually found, you know, the
Effect Platform thing.
We're like, all right, let's take our
existing API and write the HTTP
group endpoints that
match like what our API is.
And then we can generate our hooks from
that. And then we go deeper and we
realize, oh, we don't need
to generate anything.
Effect can just like infer the entire
HTTP client. So we'll do that.
And then we're like, you know what, let's
why would we rewrite the old things when
we already have the hooks for them?
Like, let's just actually implement our
new API endpoints
through the effect platform.
And then so we kind of incrementally
after implementing one thing in each
place, we were like, you know what, like,
let's just write the whole thing end to
end in Effect and like start pulling in
like entire flows from the legacy code
into our like sort of new stack.
And that's sort of how we've been going
about it. We use RPC to sort of interface
from our old backend
to our Effect backend.
And that's sort of the bridge where we
need to like make a call for a new
service or a new context.
It is like somewhat of a friction point
to add random effects in non Effect code,
because you do like the run sync, you
have to add the all the dependencies
basically right there.
And then you have to handle all the
errors before you're back in like the
world where you don't know anything.
It's a bit more verbose, but I actually
somewhat prefer it because,
as we sort of adopt more and more that
the sort of scope of that initial run
sync just grows and grows.
And then it's like, okay, now we just
have everything Effect. So that's sort
of how it's been going.
I know that was kind of convoluted, but
hopefully answers the
sort of adoption path for us.
No, it definitely resonates. And I think
it shows sort of, I mean, there, I don't
think there is like the canonical
adoption experience for Effect.
I think it always kind of depends on your
particular pain points. That's typically
what I would recommend to people when
they look into Effect.
I wouldn't recommend them doing one big
bang migration where they don't ship any
new features and just migrate everything.
And that drags on for a very long time. I
would rather recommend doing it
incrementally where you can start it
one day and like in the same day you ship
the first version of Effect.
And that touches just a small part of the
code base, but then like you've gained
sort of that incremental confidence that
you can do that without maybe your
colleagues even knowing.
And step by step for the code that you
own, you can clean it up
and make it more like a home.
And then over time you will realize that
it can absorb a lot of
the manual code you've written before.
And by embracing more parts of Effect,
you can delete a lot of the code.
And then also there is some gluey stuff
that you have while you're still sort of
in the adoption process.
And that's fine. Like that you don't need
to ever move beyond that.
But if you then start adopting even more
Effect, then every like even those parts
become just like seamless, like sort of
the seam becomes seamless.
Where you interact with Effect and then you
have like a single entry point.
And I think this is really like where
when I went first through that, it's
like, oh my gosh, this just felt so good.
Like how everything feels so coherent.
And the last time I had that experience,
I think was like migrating a
giant jQuery code base to react.
And once that was completed and I could
just like delete the jQuery dependency,
that felt sort of like a similar step.
Think back to the
time when you onboarded more of your
engineering colleagues and like you
exposed them to Effect.
how did you take them by the hand
and sort of like showed them around and
help them build an intuition?
I probably sounded a bit like a
crazy person at the time.
If they hadn't heard of effect, I hired
them one with prior TypeScript
experience, one the new grad with none.
And then basically he got a bunch of
TypeScript experience.
And then I sort of come to them and I'm
like, this is amazing.
Like we need to rewrite everything,
basically like everything, you know,
effect works best when
it's like end to end.
It has a way of just like
sucking up more and more.
We joke now that like, oh, another day
like I was like reading through
source code or like deep in the discord.
And I found another primitive that that's
in this library that just
like works perfect for us.
So side note, there's a lot of work to be
done to like get a lot of these effect
primitives and sub packages
to have more documentation and get more
people to know about.
I think this this definitely resonates
because Effect is such a vast
ecosystem and sort of like the along
the lines of the saying like that gift
that keeps on giving.
But I think it's all about having the
right mindset since like you could with
one perspective look at it as like, oh,
such a vast ecosystem,
so many things to learn.
And you could be paralyzed by saying
like, oh, this is this is too much. I
won't even get started.
What I think is much more helpful is like
picking a few abstractions of Effect, not
even bothering about the existence of the
others and like starting to adopt it.
And like you'll be surprised how great
this will already feel.
And then step by step, once you have an
understanding and an intuition for how
these pieces work, then
you're in the right spot to.
Appreciate the next abstraction and have
that sort of like improve everything in
the same way as if we see how other
ecosystems and languages have have
evolved over the years,
something like React hooks.
They solve particular pain
points that existed before.
But if they would have been introduced
like that in the beginning, maybe that
would have been too overwhelming. So
If you fully adopted Effect throughout
your system, then there's still another
incremental adoption dimension where you
can start refactoring things with more
Effect primitives that you realize, oh,
this is actually a great fit.
And I think with that, you can solve
about modeling your system.
Right. And once you start sort of
thinking in Effect, you start having
these ideas like, oh, what if I wrapped
this service this way or like abstracted
this thing this way.
And you come to realize that the
ecosystem has already done that.
And here's the thing that does it. And
you're like, oh, this is this is actually
perfect. I don't need to like even write
anything. I can just use this.
one example recently was
just simply caching any
network call like on Redis.
And we were like about to write a wrapper
for just calling an Effect that calls
some other service and first
checking the cache in Redis.
And then we found the tagged requests and
it's just like, oh, just add a cache key
and like to provide the
provide the Redis layer or whatever.
And it's like, oh, these things already
exist. It's back to the
way Rails is sort of very opinionated.
It's the way that Effect
has this giant ecosystem.
It's moving more towards these are the
ways we should do things and it's almost
even better because you can implement a
layer any way you want.
So it's not as opinionated. It's just you
have the building blocks for what you
need. It's like it's like building with
Legos, but it's almost
even better than that because
when you build with Legos, you can't like
enter in the center and rip out a piece
and like replace it.
But with Effect, you can you can rip out
any layer and replace it with anything
else at any time as long as it like
matches the service.
Exactly. And I think this is sort of
hinting at the amazing
concept of composability.
And like when we say we're talking about
Legos is like that we
can click them together.
We can compose them.
and there is sort of like the like the
atomic or subatomic level of like you
can't get smaller than that.
But everything else is kind of composed
out of those. But then you have like
those like more macro structures that are
already useful and you can use them.
But you can also at any time like kind of
take take those apart and like have the
little Legos that make the big Lego.
And I think this is what you rarely have
in those larger
ecosystems like Ruby and Rails.
This is where basically you get the big
thing. And if it doesn't do what you
want, well, bad luck.
You got to roll your own from scratch.
Whereas with Effect, you can very
elegantly kind of take those things apart
and tweak them to your liking.
I guess back to your
earlier question about introducing it
sort of to the to the team and whether
they were apprehensive.
They definitely were.
there's a learning curve and we're always
just trying to ship as fast as possible.
We have pressure from customers and
product guys just to
ship as fast as possible.
Like, let's have this out tomorrow. So
I'm coming to them and saying, learn this
entirely new way to write TypeScript.
Trust me, bro, it'll be worth it.
And it helps to like have some examples I
can point to. And I think I recall one
team member of the one actually with
prior TypeScript experience.
He he trusted me enough to give it a try.
And he said it really clicked for him
when he was writing tests, actually,
because he like mocked some layer or
wrote a test layer for for some service.
And he's like, oh, this is what I can do
with this and like isolate just certain
services and tests like
just the core business logic.
And it's super, super helpful there. But
that was the moment that clicked for him.
I think we've all had sort
of that that moment, you know, that that
is just like, oh, this is
what this is capable of.
This needs to be sort of
everywhere on a code base.
Exactly and I am considering those sort of like
the superpowers of Effect. And
you can also turn around those
superpowers into like super tricky
problems when you like those being error
handling those being observability
testing concurrency, etc.
Like if your app doesn't need those yet,
great. And like if you're in that
position, like Effect
might make less sense for you.
But the moment you need those and even
more if you combine those, then you're in
a really tricky spot.
Like, let's say you want to test your
app. OK, that's hard. But now you want to
test your app for particularly tricky
error scenarios that you don't know how
to kind of like induce into your system.
like trying to do that without Effect,
then you basically just spend
like so much time building your app and
you spend so much time just building this
crazy mocking system that like tries to
simulate everything.
And you probably feel like, do we really
need that test? And just this
incentivizes good software engineering.
And I think this is
what Effect really flips.
There's always a breaking point for
someone's error
handling for someone's testing.
And I think you just need to like
walk someone to that problem. And then I
think it like it starts to click.
Yeah, exactly. This
composability, interestingly, has
actually been great
specifically for payments.
You have like all these different payment
rails and and all these different like
providers and you can just write one
common interface and the usage
code doesn't care about what
rails the payments going on.
You can change the rails. You can
dynamically route the payment rails just
by like providing a different service,
providing different layers.
So it's been super interesting to see
that the patterns we
can develop this way.
Can we shift gears a little bit and talk
a bit more about like the architecture of
your system? So like if I'm going to
joinwarp.com, like there's a website and
probably next to the website, there's
also some sort of like dashboards that
your customers are using.
So that dashboard, I suppose you're using
something like Next.js for that. So that
run, there's a front end at minimum.
But that front end is then talking to
some sort of like API tier. So we have
that as well. But I'm curious, what else
is there? Is there like you have an API
level, but then you
probably also have places.
Maybe you have cron jobs. Maybe you have
like other things you've mentioned like
that AI agent browser setup, etc. So I'm
not sure whether you're thinking about
this as like
microservices or majestic monolith.
But like maybe you can explain a little
bit of like how that imagine we're at a
whiteboard and you're drawing the system
architecture. Like maybe
you can do that in words.
We definitely prefer to keep things
as simple as possible. We're a team of
four and we don't have high requirements
for like latency on requests.
We have requirements for reliability
being being payment software.
another thing is we don't have a high
total number of like daily active users.
So our compute requirements are actually
interestingly somewhat low. That being
said, the way we started was on Next.js
and almost everything was
just in a Next.js API route.
That grew honestly way past its
usefulness, but that's the way things go
at startups. You just pick a stack that's
been the theme of this whole interview.
You pick a stack, you go too far with it.
It doesn't meet your needs.
And also just as a side note, it's almost
diametrically opposed to what you've been
building before with the social network
where like it's like the latency really
matters, etc. And like it now you've like
completely flipped all of
your like tech trade offs.
Yeah, that one was fun to build because
it was tons of caching, streaming, like
all the stuff that needed to scale very
quickly when there was a usage upburst
for whatever reason.
And now our usage patterns are a lot more
predictable if you think about it. People
log in to see their paycheck twice a
month. We just need to like get that part
right and then make sure
all the payments are right.
So I guess to say more about the
infrastructure, we're running containers.
We have one monolith pretty much that
handles all of our API routes, jobs, even
like yeah asynchronous jobs, cron jobs
and that's our effect platform API.
And then we do have like separate
services, for example, for the browser
agent thing, we have a slack bot that's
separate. That's like sufficiently
different to necessitate another service.
But all that to say pretty simple, we
like to work in a monolith.
And is that monolith currently deployed
in a single place or are you already
running that in a distributed setting
that maybe you have one running in the
East Coast, one running on the West
Coast, wherever your customers are?
Yeah, we just have one running on the
East Coast that's next to our database.
Got it. So maybe at some point, there
might be the day on the horizon where you
need to like go multi data center, which
I'm sure will upend a whole bunch of like
so far trade offs you
didn't have to make yet.
But this is another thing where maybe
I'll invite you back to the podcast to
see whether Effect Workflows could help
with that. Since this is
exactly what this is about.
Kind of like to like going with a
monolith and just deploying that monolith
to a single place is the simplest you can
go with. And I love simplicity.
But at some point, you might need to go
beyond that and then to still go for
maximum simplicity. I think this is where
Effect will be another gift will be
receiving from Effects is like Effect
workflows that try to help
exactly with the sort of thing.
But we'll talk more about that in the
future. Yeah, I hope to make
it there. I hope to have these problems.
but maybe going back to that, so
you mentioned like you're running this
right now in a container. You mentioned
that you run some sort of like jobs,
background processes, etc.
How do you orchestrate that right now? Is
that still mostly driven through what are
the entry points are those entry points
are requests. Those entry
points might be cron jobs.
Anything else that sort of serves as an
entry point to kick off code that runs?
Yeah, so we have the HTTP like sort of
restful API that that kicks off code
where we actually wrapped.
We actually wrapped BullMQ with
some Effect helpers so that's the
way we're kind of queuing up jobs and
processing them. We're still running that
just on one server, all the
handlers. We could distribute that
somewhat simply.
And then yeah, there's also RPC endpoints
just for calling more service type
functions from from our legacy back end.
that's pretty much it.
I guess to mention cron we can
queue like cron type jobs in in our
BullMQ so we're not officially using like
cron jobs, but it's it's
you know daily scheduled jobs.
Got it. Can you share a bit more about
sort of like the DevOps lifecycle things
that that you're dealing with and how
you're using Effect for that
part of the picture as well?
One thing I didn't mention
is that we're using bun in in our
container runtime. So that's
been fun effect pretty much instructs
that away. So it's it's no different than
using it in node other than we get to say
we're running on bun and and
it's it's fun a bit faster.
There are some bun
features that that we like.
Yeah, I guess we're we're fully automated
like deployments. We just you know, build
the container in a GitHub action with bun
and PNPM and then push it to our
like ECS cluster on running on AWS.
Got it. Speaking of sort of like the
monolith and bun approach a friend of
mine has been working at Midjourney and
I think Midjourney actually has also
embraced the sort of architecture and
deployment architecture where they have
like one big machine where they're
running their monolith through bun and I
think they call it the mother bun.
So just a little fun fun side note here.
But speaking of Midjourney and therefore
AI, you mentioned initially that one
theme that you're currently also spending
quite a lot of time on is automating
things further with AI. So maybe we can
pivot the conversation a bit in that
direction. Do you want to give an
overview of like what that means and then
diving closer into that?
Definitely. The way I think
about AI and our product
is sort of two
separate kind of verticals.
We are a payments product we, you know,
remit taxes, we have to know all the
taxes and we have to get those right. So
you think that plus AI is probably a
recipe for disaster.
But I think there are there are sort of
two ways we we think about it. One is the
customer facing way, which is, you know,
we've built this wonderful
platform for people to use.
How can we make AI to one make that
easier to use and two, I think one common
theme that's going on right now is just
meeting customers where they are, which,
for many means building slack bot.
Chat interfaces, etc. So how can AI
actually be the bridge between our end
users and our products in a way that's
like very safe and human in the loop and
you know we're not triggering payments
for people that are that are approved,
but we can actually use our
product with natural language.
And I guess when I say AI here, I'm
talking about LLMs specifically.
And then sort of the other way we're
thinking about it is automating process
heavy workflows sort of on the back end,
which is, you know, what if an
AI can file taxes, what if an AI can like
read your tax reports and, you know,
generate insights and and go and and sort
of do the things that need to be done.
And these are things that, in
the pre 2023 era, you might have needed
an army of employees or contractors to
like, go through these, you know,
convoluted .gov websites and
click through these things.
But we're sort of asking the question,
you know, what if, what if a person
doesn't actually have to do that.
So those are sort of the different
ways we're sort of thinking about it.
Got it. That that is super helpful. So in
regards to the the latter,
automating those
various like manual processes.
When you mentioned that currently work is
16 people, 4 of them being engineers, I
suppose, like a big chunk of the other
employees are still doing that sort of
like making the entire
thing happen behind the scenes.
But there is, as you scale up your
customers, you would need to scale up the
employees. So you want to like automate
as much as possible.
And this is where AI like is helpful.
Yeah, exactly. The economics of it, I
mean, is that, you know, we have to scale
our team somewhat linearly with the
number of customers we have.
But with AI, you can presumably pay
pennies for things that you'd have to
hire a bunch of people for.
So we're exploring
different different ways to do that.
Got it. And now it's like a great
opportunities for your existing employees
who've been doing that so far, like help
in that automation process
as they're the domain experts.
And yeah, that sounds fascinating. It
gets us full circle back to the initial
point of like we can be thankful to
you like doing that.
And now it's actually super fun for the
people who were the domain experts that
they can now start being
included in the automation process.
So that makes a lot of sense. And I think
that's a whole different topic of what it
means to do that automation.
And there's like a lot of like just from
my own experiments and like work on AI
driven things. There's like so many
things that can just go wrong.
I mean, if you're just like as a human
navigating websites, like things just
rarely are going
as they as they should.
There's like a downtime. There's like
whatever like a page just
reloads without you triggering it.
There's just so many unpredictable things
or sometimes they don't use HTML selects
and you know, reading the DOM, you have
no idea what to like there are
accessibility issues that
that an AI can run into.
There are so so many things. Yeah. So
this is it's whole
different kind of words.
And like honestly, it becomes like a
whole different profession of like how to
how to build systems that like can
automate these things
that we have in mind.
But maybe we focus a little bit more on
the first part you've mentioned where
you're like where you meet people where
they are and like expose sort of like
those more AI native interfaces to them.
Are you also building those systems with
Effect and maybe you can also share a
bit more of like how those are built
which of the Effect's
primitives they're using.
Yeah, we are using Effect for it.
We haven't actually
used the Effect AI thing.
I have wanted to use that but I guess our
team member who's doing it is it like I
said came from the Python world and it's
very like fast iteration cycles.
He was kind of fighting the learning
curve of learning
effect versus trying to get features out.
So we haven't explored that specific
primitive too much. We are using Effect
sort of in the same way we've used
we've just wrapped like the providers.
we're only using one LLM right now
which which I'll refrain from
naming. But you could guess.
Yeah, sort of the same way just just end
to end like wrapping workflows. There's
very much human in the loop sort of
things and we have to ask on a lot of
workflows like for
confirmation from the user.
So there's these like very stateful
flows. So we're actually using sort of
Effect and TypeScript more generally to
kind of pick up these workflows where
they left off and write
like these stateful flows.
Got it. That makes a lot of sense. And I
think it's always like a good judgment
call to see like hey is this is using
Effect here like today. Is that solving
a problem we have or would it potentially
if I pay that learning cost is worthwhile
paying that today or should
I pay it in two months from now when I
have more acute problems.
that's always a good
question to ask and I think that starts
adding up but rest assured that Effect AI
has become a lot more polished and I use
it relentlessly in many
projects and it's an absolute joy.
Oh, I'll have to explore it deeper. Yeah,
like you mentioned, it's hard to justify
when one the person doesn't know it and
two when you don't know what your data is
going to end up looking like and you
don't know if the
project will even survive.
So there is there is this. You know back
and forth between like is the
learning curve worth it
versus I need to ship features.
Yeah, so maybe looking a little bit more
into the future. What are your hopes for
Effect as an ecosystem and what are your
plans for Warp from
engineering perspective.
Good question. I think I'm I've been
super happy with the stuff we're
building. It's been like such a
refreshing experience building the new
way that whenever I'm like digging deep
into legacy code. I'm just like upset in general.
I'm like ashamed of what I've what I've
written in the past in some ways. So I'm
super excited. I'm very excited for a lot
of the things that are marked
experimental to just be like
production ready, so to speak.
Super excited for more things like the AI
package and and also like I mentioned. I
think there's so many opportunities to
get a lot of the ecosystem in better like
documentation states. There are so many
like discord threads with gems that you
know the the person coming to Effect for
the first time will never see for the
thing that they need
I think I'm excited for it to be in more
of the LLM training data. I've seen a lot of.
They spin their wheels because
they don't know the syntax or
whatever. They don't know a specific
diagnostic error. The LSP extension helps
a lot with that. So really, I'm just
excited for it to hit the mainstream more
and and I'd like to you know do anything
I can to support that.
There's a lot of
opportunities for educational content. I
see a lot of your team to their credit.
posting like animations and
different things. So I'm super excited
for the direction it's going and I think
the the Effect team has been great and a
lot of the projects I see written in it
are really cool. I think a lot of a lot
of people I respect are writing it.
And that's sort of
reason enough to try it.
I couldn't agree more. Thank you so much
for sharing your own experience with
Effect today and sharing your
super interesting story of like how
you've come to to co-found Warp. I
think it's very inspiring for the
audience to to show like how with how a
few engineers you
can build like a global system that that
solves like really material problems that
that's that's exactly what Effect is
built for and it's very cool to see that
is working well for you.
Yeah, we're we're super happy with
how it's turning out.
And if if anyone listening wants the
write Effect, come come join Warp.
Please do. Yeah, we're going to put the
link in the in the show notes and yeah,
Adam, thank you so much for taking the
time today and sharing your story.
Yeah, it was great to join. Thank you so
much for having me. Hopefully
we can do it again sometime.
That sounds great. All right.
Thank you for listening to the
Cause & Effect Podcast.
If you've enjoyed this episode, please
subscribe, leave a review
and share it with your friends.
If you haven't done so already, you can
join our Discord community.
And if you have any questions, feedback
or suggestions about this episode or
about Effect in general,
don't hesitate to get in touch.
See you in the next episode.