All Episodes

February 3, 2026 75 mins

What if you could keep Rails pages fast, accessible, and SEO‑friendly, yet still get modern interactivity without shipping a mountain of JavaScript? We sit down with Cameron Dutro to unpack Live Component, a server‑first approach that breathes life into ViewComponent by treating state as data, rendering on the server, and morphing the DOM with Hotwire. No fragile ID wiring. No React by default. Just clear state, small payloads, and focused updates.

We trace the path that led here: experiments rendering Ruby in the browser with Ruby.wasm, Opal, and even a TypeScript Ruby interpreter, and why those payloads and debugging pain pushed the work back to the server. Cameron explains the Live Component mental model—initializer‑defined state, slots, and a sidecar Stimulus controller—plus how targeted re‑renders make forms and micro‑interactions feel instant. We talk transports (HTTP vs WebSockets), serialization best practices for Active Record data, and where React still shines for high‑intensity builders and editors.

Beyond the code, we dig into the bigger web story: how DX‑first choices often punish users on slower devices and networks, and why a balanced, server‑driven approach can close that gap. You’ll hear real‑world tradeoffs, debugging techniques that feel like home to Rails devs, and a clever fix born from a Snake game that surfaced timing issues and led to a preempt option for queued renders. If your team wants dynamic islands without adopting a full SPA, this conversation offers a practical roadmap.

Explore Live Component at livecomponent.org and the GitHub org at github.com/livecomponent. If this resonated, follow, share with a Rails friend, and leave a review so more builders can find it.

Send us some love.

Judoscale
Autoscaling that actually works. Take control of your cloud hosting.

Honeybadger
Honeybadger is an application health monitoring tool built by developers for developers.

Judoscale
Autoscaling that actually works. Take control of your cloud hosting.

Disclaimer: This post contains affiliate links. If you make a purchase, I may receive a commission at no extra cost to you.

Support the show

Mark as Played
Transcript

Episode Transcript

Available transcripts are automatically generated. Complete accuracy is not guaranteed.
SPEAKER_01 (00:00):
Hello everyone and welcome to another episode of
Code and the Coding Coders WhoCode It.
I'm your host, Drew Bragg, andI'm joined today by Cameron
Dutro.
Cameron, for anyone who's notfamiliar with you, would you
please do a quick introductionfor the listeners?

SPEAKER_00 (00:12):
Big fan of the show, so thanks for having me on.
Yeah, I'm Cameron Dutro.
I work on the Core Dashboardteam at Cisco Meraki and have
been working with Ruby on Railsand Ruby more generally for the
last 15, 16 years.
Started out at Twitter workingon the Translation Center, which
is a Ruby app or a Rails app,and then just have kind of stuck
with it since then and excitedto chat with you today.

SPEAKER_01 (00:34):
Anyone who is new to the show, the way this is going
to work is I'm going to askCameron three questions.
There will be more, but threebasic questions.
What are you working on?
What kind of blockers do youhave?
What's something cool, new, orinteresting you want to share
with the audience?
Doesn't have to be codingrelated, but it is code and the
code encoders, etc.
So it absolutely can be coderelated.

(00:56):
So, Cameron, what are youworking on?

SPEAKER_00 (00:58):
I'm kind of on the show.
I think because I reached out toDrew about a project I've been
working on called LiveComponent.
And I was telling Drew kind ofpre-show here that Live
Component is like an outgrowthof a bunch of front-end concepts
and ideations that I've beenworking on over the past couple
of years.
And I think actually Drew hadjust brought up too in the

(01:19):
pre-call that we had aconversation.
I think it was Sin City Ruby in2023 or 24, which is
unfortunately the only one I wasable to go to.
Jason Charns had given apresentation during that
conference about his company,Podia, and his work on trying to
get, I think it was like awebsite editor project.

SPEAKER_01 (01:39):
He was our site editor.
We have it in React.
We built it when Hotwire wasn'treally a thing.
So he was kind of like, I wonderwhat it would be like to try and
build it now with Hotwire as itis.

SPEAKER_00 (01:49):
Totally.
Yes.
And I apologize.
I forgot that you also work atPodia.
Podia is always like talkingabout what they're working on
and doing.
And like I because I listened toAndrew Mason on the other on the
remote review podcast.
And he talks about his work alot.
Just lots of cool stuff going onover there.
Anyway, so Jason, yeah, soyou're right.
So the site builder that he wasworking on, yeah, like you were
saying, he I guess first builtit in, I guess tried to build it

(02:11):
with just regular rails, andthat didn't work out so well.
And so you guys switched toReact.
And then his presentation wasabout like, what if we had tried
to build this with hotwireinstead?
And he sort of like live codedthe hotwire version of that on
stage, which was like so great.
I mean, I was nervous for him,but also like so impressed that

(02:31):
he managed to, because he reallydid it.
I mean, it was at the end of theday, he had a working prototype
of that in Hotwire.
And I had not used Hotwire thatmuch before watching him do this
or stimulus for that matter.
And so watching him do it was areal like crash course education
and like how that stuff works.
And there were some things thatI noticed, right?
Like one of the things I noticedwas that he was having to like

(02:51):
wire up IDs everywhere.
So like you have an ID on thepage, and then you have to
target that ID in the controllerwhen you render the response,
the hot wire response.
Like a turboframe, I suppose,has an ID and that matches with
an ID that's already on thepage, and then it morphs the
contents of that into the page.
And the morphing part of it wascool, but like the ID wiring, I
was like, boy, that really feelslike it could be ripe for
mistakes, right?

(03:12):
Like I could target an ID thatdoesn't exist, or I could target
the wrong ID, or right.
And there's nothing reallylinking those two things
together.
That was one thing I noticed.
Another thing that I noticed wasjust how often he had to flip
back and forth between differentfiles.
So like there was a JavaScriptfile and there was his templates
and the controller, and thethis, and then there's so many
times he had to like flip toanother file, and sometimes it
would be the wrong file, andhe'd be like, oh crap, this is

(03:32):
the wrong file.
I have to go search for theother one, a bunch of tabs open.
I think we've all had thisexperience with working on apps
in general, and the navigationaspect of it can be kind of of a
time sync, right?
Like I've got a billion filesopen.
I'm trying to find the, I knowexactly where I want to go, but
I can't find it in my editor.
So just the overhead, sort oflike switching between files,
maintaining these IDs in yourhead, which one do I target

(03:53):
next, right, from thiscontroller action.
And something he also said thatlit off sort of a spark in my
brain was that Podia has a bunchof view components, but they
couldn't really use them becauseyou can't re-render them on the
front end.
You can only render them on theback end, kind of one time.
They generate HTML and they shipthat to the browser.
And that really made me thinklike, huh, what if you could

(04:15):
render a view component in thebrowser?
Would that have made thiseasier?
So I actually asked him thatquestion at the end of his talk.
And he said it would have madeit much easier, or it would have
made it more possible, I think,to reuse their existing systems
and components if they had beenable to do that.
And at the time I was working onthis web like framework, I guess
you call it, like a replacementfor React, that I called Nido.

(04:36):
And the concept behind Nido wasthat it was Ruby running in your
browser, and you could load aview component, for example.
I think I actually used Flex atthe time because Flex was easier
to run in Ruby and inJavaScript, because it's just a
simpler project.
Like View Component depends onaction view.
That's a big dependency to stickin your browser.
And so I was looking at Flex forthe first iteration of this.
I had also at the time, beenbecause I didn't want to

(04:57):
transpile the code, so I'd alsobeen working on like a Ruby
implementation, like a Yar ofimplementation in TypeScript,
which is like one of the reasonsI was able to answer some of
your questions on the game show,because I had been working on an
actual Ruby interpreter.
And so like I knew the ins andouts a lot better than I would
have otherwise.

SPEAKER_01 (05:12):
The cheat code for the game show is like if you
work on a Ruby interpreter, youget pretty close to some of the
weird Ruby in the game show.

SPEAKER_00 (05:19):
You do absolutely do.
Yes.
To be honest, though, some ofthose questions still like
totally stumped me.
Like there was no substance.

SPEAKER_01 (05:29):
But I wrote the thing.
That's the only and it's funnybecause if I haven't given it in
a while and I'm like prepping togive it, like I quiz myself and
I get questions wrong.

SPEAKER_00 (05:40):
Totally.
Yeah, some super esoteric littlecorners of everybody I've ever
talked to just loves your gameshow, by the way.
Thank you.
It's super fun.

SPEAKER_01 (05:48):
It's hard to put down because of that.
Like I keep saying I'm gonna doa talk that isn't that.
I'm gonna do a proper talk or atleast just a different topic
with some other weirdpresentation aspect to it.
So many people are like, we'dlove to have the game show.
And I'm like, well, if you'dlove to have it, I'd love to
give it.
Like I'm not gonna submit it toany places.
I'm not gonna be like, would youlike my game show?

(06:09):
But there's enough places thatthey're it's fun.
And like I said, if you haven'tseen it in a year, I could not
change a thing and you'dprobably still get a couple
wrong.
It's just such goofy Rubysyntax.
So if I did at RubyConf inChicago with Matt's in the front
row, yeah.
And when he got a questionwrong, I was like, I just like I

(06:29):
can retire now.
I got I stumped the creator ofRuby with my silly little game
show.
This is gold.

SPEAKER_00 (06:35):
I can retire.
Happy man.
I can say that even though I hadworked on the interpreter and
got some wrong at Sin City, Icame back and had seen the whole
thing.
I think you probably added somenew questions and whatnot, but
like even seeing it again, likethere were some that I'm like,
oh yeah, I saw this one lasttime, but I do not remember the
answer to the question.

SPEAKER_01 (06:50):
Yeah, in addition to the Matt's stumping Matt's with
one, that was great.
Having him like interact withpeople, like everyone was
calling on him to help.
But the best was I forget whoended up coming up, but they
were like, Yeah, I'm on the Rubycore team.
And I'm like, Well, that'sgreat.
And it was for the flip-flopoperator.
Oh, yeah.

(07:10):
Like he was helping whoeverlooked at the question and he
named it.
And he's like, That's theflip-flop operator.
And then he paused and he'slike, Now I just need to
remember how it works.
How it works, yeah.
And I was like, that is perfectbecause like it was one of
those.
The first time I saw it, I waslike, I don't even know what to
Google here.
Like, how do you really?
I don't know what this iscalled.
I don't know.

(07:30):
And this was pre-AI, so Icouldn't just copy and paste the
syntax and be like, what thehell's going on here?
Yeah, yeah.
So it was just so great.
Someone even on the Ruby coreteam gets up and he's like, I
know exactly what that is, Ijust don't remember how it
worked.
And I was like, Thank you forproving my point.
Of like, when you're writingreadable Ruby, people have to
know what's going on.
Great.

SPEAKER_00 (07:49):
Like sitting here now, too.
Like, I don't think I could tellyou what the flip-flop operator
looks like or even does now.
Even having seen thepresentation twice and like
having written Ruby for a longtime, I just feel like we don't
use it that much, I guess.

SPEAKER_01 (08:00):
Now, because I've talked about it enough, people
have shown me real use cases andlike the reason why it was
undeprecated after it wasdeprecated of like, hey, we use
it in this parson library, weuse it in this way, or like
these older projects rely on it.
We're not rewriting them.
So I get it now, but yeah, it'sone of those.
The first time I ever ran intoit, I was like, really?

(08:22):
Not even a code comment saying,hey, you might not be familiar
with the flip-flop operator orlike something.
It's like for me, Ruby wasalways the most readable
language.
And then I ran into somethingthat was just like not readable.
Yeah.
It's like holy crap.

SPEAKER_00 (08:36):
Yeah, for sure.
But there's been a number oftalks, I think, at previous
Rails comps where people willbring up sort of like weird
corners of Ruby.
And sometimes I think theflip-flop makes it in there.
James Edward Gray, back in like2012, the first RailsCon if I
ever went to, he gave a reallyfun talk where he went through
like a hundred weird things inRuby in like rapid fire back in
the day.
Yeah, he was doing talks likethat and they were super fun.

(08:59):
And I think that yeah, he alsohad the flip-flop in there at
one point and like just blewpast it.
And this is one of a hundredthings.
And everybody was like, okay,like I don't even know what I
would use this for, but yeah.

SPEAKER_01 (09:09):
So good.
Sorry, I totally derailed yourline of thought.
Well, we were talking about.
No, no, no.
You were writing a bit of a Rubyinterpreter in TypeScript.

SPEAKER_00 (09:17):
Well, actually, you know, it's funny you say that.
TypeScript is actually such agreat choice for a library like
that because there are so manytimes where I'm like, I don't
actually know what I'm doing.
Like the big one that reallymade me appreciate the power of
like a typed language in forsomething like this is that you
so you know that the differencebetween like a regular method
and like an async await methodin JavaScript.

(09:38):
So like it returns a promise,and you can't just like use the
value to await it, right?
And so like that whole asyncawait model, if you use it in
one place, it like a it likeinfects everything else, right?
So like if a function callsanother function that returns a
promise, then that function hasto also be Marcosync to be able
to await it, right?
And so it ends up, and that'swhat happened to me.
I was trying to use some nodeAPI, or maybe it was even a

(10:00):
browser API, in some like Rubymethod in this interpreter, and
the only way to call it was viaasync await or via promises.
And I was like, oh no.
And so I literally had to gothrough the entire thing and
change basically every methodcall to async await so that I

(10:21):
could support that.
Yeah, it was really painful.
But because it was inTypeScript, I was able to just
like turn on a bunch of likecompiler warnings that told me
when I wasn't awaiting things orwhen something wasn't, and like
I could also I actually don'tthink I used any tools to
actually fix all the functioncalls and things, but every time
that I put an async in front ofa method call or a method

(10:41):
definition, it would tell me,wait, you forgot to change the
return value to a promise ofthis type, right?
And then just also just beingable to like right-click and say
rename this symbol, and itrenames it across the entire
code base.
And at the time that I was doingthis, I mean, I was pretty far
along in the project.
And so like being able to dothat was so nice and helpful.
And like, yes, adding the typesand maintaining them and all

(11:03):
that and keeping them in yourhead, it's overhead for sure,
but it really pays for itself insome cases.

SPEAKER_01 (11:08):
I mean, now that we've got Claude AI writing all
of our code for us, you're notthe first person to bring up
like those kinds of hey, it'sreally nice with typed languages
because you can do this quickrefactor, it'll yell at you.
And it used to be like, yes, Ihear you, and there's trade-offs
for everything between staticand dynamic typing, but like

(11:28):
with Claude, I'm like, yeah,Claude can do that in my dynamic
language now, too.
And I mean I'm fairly confidentin its ability to do it
accurately.
The benefits of both differenttypes are almost like melting a
little bit.
It can just handle it.
It's yeah, wild.

SPEAKER_00 (11:45):
Yeah, that's so true.
It's they're getting so goodthat yeah, like maybe this is
like kind of a boon, really, fordynamically typed languages
where you don't actually have tobe have the type information
around it all the time, whichyeah, super interesting.
Good point.

SPEAKER_01 (11:57):
Yeah, we just had Scott Werner at Philly RB and he
was talking AI because he runsthe artificial Ruby meetup up in
New York, and he had some reallyinteresting ideas and thoughts
on where programming is going togo because of AI and like the
way we're using AI right now islike it's not the end game.
We're like barely scratching thesurface of how AI is going to

(12:20):
shape how we write programsgoing forward.

SPEAKER_00 (12:22):
Yeah, yeah, both exciting and scary, I would say.

SPEAKER_01 (12:25):
Yeah, interesting stuff, stuff that we didn't have
to think about before.
Like I love meetups because youget this side conversation,
someone does a talk, and theneverybody kind of creates their
own little bubbles where they'retalking about X, Y, or Z.
And the one group I was talkingin, someone had ranked the token
efficiency of programminglanguages, and Ruby was in the

(12:46):
top three of most efficient.
So, by most efficient fortokens, uses the least, AK costs
the least.
Couple that with it's not hardresearch, but from all of the
tinkering I've done with AI, AIdoes a really good job with
Rails conventions.
Like if your Rails app followsthe Rails way pretty closely,

(13:07):
like it does a really good jobfinding stuff, knows where to
put things, understands theboilerplate.
And I'm like, you combined thatRuby on Rails is already a
predictive framework, and Ruby'sa great language to read.
Couple that with AI works reallywell with Rails and it's token
efficient for Ruby.
I wonder if that's going to helpmore startups be like, well,

(13:29):
let's use AI to build ourvibe-coded thing, but let's use
Ruby on Rails since it's cheapand AI's good with it.
Like that's an interesting forcemultiplier for Ruby on Rails, I
think.

SPEAKER_00 (13:41):
Yeah, for sure.
I do think, too, there's like alot of really interesting
investments, I feel like, thatare being made in AI tooling,
like lots of Ruby MCP servers,lots of like jobs that of course
communicate with like the openAI API, things like that.
Those came out really quickly.
Like the Ruby community seems tolike really be responding to
this moment in AI right now.
And I that's really hearteningto see because I think, like

(14:03):
again, I'm somewhat of an AIskeptic in some ways, but also
like something of not of one,right?
So like I tried to feel it outjust like everybody else.
And I mean, I think AI willchange the way we write
programs.
There's no question about that.
And so, like, if we can be moreready for that than less ready,
then that seems like a goodthing, right?

SPEAKER_01 (15:01):
Yeah, it's not even remotely surprising that the
Ruby community as a whole islike on top of, hey, what can we
do with this?
Not even like, yeah, I don'tthink anybody in the Ruby
community, aside from a handfulof people that are like very
bullish on AI, like, no one'spushing AI.
It's more of like, hey, what canwe do with it?

(15:22):
Like, where is this going to go?
And like, that's what I loveabout what Scott's doing with
AI.
He's doing so much exploration,and some of the stuff he comes
up with feels so why?
Like, very whimsical, very like,why would you build this?
Like, what's the point of this?
It's like, I just wanted to seeif I could.
Like, I just wanted to, yeah, wewere riffing on an idea and
we've shoved it into AI and letthree different agents come up

(15:45):
with a plan and we like and theway that he's going about it
seems so much more fun than Idon't know how we're going about
it in our day-to-day, where it'slike, well, I don't write code
anymore.
I tell the LLM what I want it tobuild.
Yeah, that's yeah, boring andcorporate and bullshit.
He's over there having fun withit and having a blast.
Wacky, no one's gonna use this,but I wanted to see.

(16:08):
And that's why, like, when hegave his talk, and I don't want
to spoil it because I know he'splanning on giving it in a few
more places.
It was just a very like, I thinkhe's on to something.
I think he's on to like we'reusing this tool to do something
way different than we can bedoing it because of this tool.
We just haven't quite figuredthat slice out yet.

(16:31):
Like, software engineering isnot going away, it's just
changing.
We are going to use this tool tobuild bigger and better things,
but we are still building.

SPEAKER_00 (16:40):
So, yeah, and I love that framing.
And that's a much less defeatistframing, I think, than like all
the jobs are going away andnobody will be writing any code
anymore, and it's all gonna beagents everywhere.
And like, I think one of my bigsort of problems, I guess, with
how a lot of the AI companiesthemselves are framing AI is
that they're they're claiming itcan do all these things that
they really can't do.

(17:01):
That's number one.
But there's also, I think, justkind of this condescension, I
suppose, for labor.
And there's some companies in prin particular that actually want
to replace all jobs, not justprogramming jobs.
I don't mean necessarily theleaders of these AI companies,
but more just there's there'sone company in particular that
wants to like use AI toliterally make it so that nobody
has a job, so that nobody has towork, so that everybody has, and

(17:23):
they're trying to fit universalbasic income into something,
into that world and like planfor when none of us have jobs,
we're all just able to dowhatever we want all the time.
And condescension is the wrongword, but just like this
contempt for labor, right?
Yeah.
And that's something that reallykind of rows me the wrong way.
And I wish that there wasn'tthat aspect to it, because I
think if there weren't, like wecould all just focus on how cool

(17:45):
the technology is, but insteadwe have to focus on how cool the
technology is and also how am Igonna feed my family based on
these things you're telling me?
And that I was told back in theday, like, this is a good
career.
You should go into this career,you should learn how to code.
And I was like, okay, and I did,right?
And now it's like just kidding.
You know, this is a bad careernow.
You shouldn't learn to code,nobody should.
We're all gonna use agent.
And so it's like, wait, what?

(18:06):
It just feels like a rug pull.

SPEAKER_01 (18:08):
And really, I don't think it's true that there won't
be a human component.
I mean, maybe AI has changedrapidly.
It's sort of weird to think likeClaude Code came out in what May
2025.
Like, we haven't even hit a yearwith it yet, and it's already
changed our jobs drastically.
Yeah, yeah.

(18:29):
So I don't want to sit here andsay, oh, it'll never happen or
anything, but like the idea thatour jobs will not exist is not
an imminent threat.
Our jobs definitely will change.
I really loved writing code,like I found it very meditative.
Like, you'd solve the problemand then you'd write some code,
and that was great.

(18:49):
And I loved the writing codepart, it felt very zen.
It was a great escape for me.
I loved it, and that part of myjob is gone, and I had to do a
little bit of grieving becauseof that.
But the really, really fun partof my job is figuring out
problems, and that still existsbecause I think that LLMs are
still really bad at it.
And to be fair, even the codethat Claude writes for me, when

(19:12):
I have it write code for me,it's not ready to go.
It's like 80% of the way there.
It needs refactoring, it needssomeone to tell it things and to
call it on its bullshit.
I call it out all the time.
It can't one-shot things right.
Maybe it's a fault of mine,maybe I'm not prompting well
enough.
But talking to my peers atpodia, like we're all kind of on

(19:33):
that boat of like sometimes youdo get a PR that was one-shot AI
and you can tell, and it's notgood.
It needs a little bit of humantouch before it goes out.
Still, maybe that'll change.

SPEAKER_00 (19:46):
No, true.

SPEAKER_01 (19:47):
There's still someone gotta be there guiding
it, giving it guardrails.

SPEAKER_00 (19:51):
Yeah, so you're right.
I think our jobs are secure forthe time being, anyway.
I also like your framing there,just like you know, that the
writing of the code itself iswhat a lot of us think of as the
fun part, but but really, whatare we really doing?
We're really just solvingproblems, and like the problem
solving part of it is kind ofwhere I think a lot of we can
drive a lot of meaning.
It's not so much like the actualoutput of the code, it's like I
learned this problem well enoughthat I could write a code

(20:11):
solution to it, and that iswhere the value is.
It's not so much in the codeitself, right?
Yeah, but no, of course, aconversation is going to include
AI because that's just such ahuge topic.
So back to live component andwhere you were at with Yeah.
So the I think I left the storyoff that I'm working on this
TypeScript interpreter, and youknow, that was super fun.
And I'm still contributing tothat from time to time.

(20:33):
There's just obviously so muchto do on it, right?
Like the Ruby standard libraryis enormous, and so like trying
to support all of that is hard.
I will say what I've been doingon that project, I've been using
AI on that project to debugproblems for me.
So I don't have it write a lotof code.
What I have it do instead islike find where this problem is
because a lot of the time I'llrun a piece of Ruby code through

(20:53):
the interpreter and it willcrash with some like very vague
JavaScript or Ruby error.
So I will point, I use augmentin my editor and I just say, Can
you figure out?
Don't write code yet, but likefigure out why this is breaking.
And it will what would take mehours to debug, it can do in
like 10 minutes, which is justsuper helpful.
And then I can go and I caneither write the code or I can
ask it to like draft somethingfor me.

(21:15):
And I usually I usually writethe code myself because that's
again the fun part and it's aside project and all that, but
it could just save me so muchdebugging time.
And because I've got two youngkids, I don't have a lot of free
time.
And so, like, if I can just typeinto my augment code extension,
if I can just say like figureout what's going wrong here and
then report back to me, and thenI can hit enter and then go play
with my kids or serve them lunchor whatever, and then come back.
It's just such a great like timesaver for me and a great like

(21:38):
like productivity unlock.
And again, this is all sideproject stuff that I'm not like
actually shipping to people.
So it doesn't I'm not, I don'tfeel super responsible for
writing every line of code ordebugging every single problem.
Anyway, so that was that's a funproject that's called Garnet.
You can go to camera tron slashgarnet dashjs on GitHub.
It uses the Prism parser inWasm.
It does a bunch of other coolthings I think are cool.

(21:58):
Like it uses the Enigmo regularexpression library, which is a C
project that's also compiled toWASM.
It uses that as its regexengine.
Because I did not want to writemy own regex engine.
That sounds like a huge.
I wonder why.
Yeah.
So anyway, so that project wassort of in flight and sitting
there at SinCity Ruby andlistening to Jason talk about
rendering view components in thebrowser, and I was like, man,

(22:19):
this is really where we shouldbe doing.
I should try experimenting withhow I could potentially take a
view component and render it inthe browser with Garnet or
whatever.
And so I tried that and itworked okay.
But like there's no way thatlike I'm gonna tell people to
use Garnet because it's such anincomplete implementation.
And so I also dove into liketrying Ruby.wasm because you can
run Ruby in the browser now withthat project and got to a place

(22:41):
where like I was rendering stuffin the browser with that as
well.
But then I kind of hit a wallbecause you look at the download
size of Ruby.wasm and it's justenormous.
Like it's we're talking like 50megabytes.
And that's not even yourapplication code.
That's just the interpreter.
And after a while, it just feltlike I was just fighting the
browser.
Like the browser is not reallymeant to run these.
I mean, yes, it can do them.

(23:02):
And it's amazing that we can getthis far with this cool new
technology.
And I mean, WASM is really,really cool stuff.
I mean, don't get me wrong, it'sall very cool.
But I was like, it feels likeI'm kind of going in the
opposite direction here that Ishould be going.
And so like I took a step backand started to think about an
alternate approach that wasn'trendering view components in the
browser necessarily, but maybewas rendering them server-side

(23:23):
and then shipping them back tothe browser, sort of using the
same hotwire paradigms thatthey're already in Rails.
And a lot of this was also likeinformed by the fact that I used
to work for GitHub.
I used to work for the primerteam.
Primer is a design system.
And I worked on the ViewComponent framework itself and
was for a while a co-maintainerof that.
And then also worked on primerview components, which is like a

(23:44):
collection of view componentsthat implement the primer design
system.
And after a while, though,GitHub started to sort of
shutter that project becausethey were moving mostly to
React.
And there was also a primerReact library that I contributed
to as well.
But like sort of in thatconversation about like should
we switch to React or not, I wasvery much on the side of we
should not, by the way, becauserewriting an application is

(24:05):
because GitHub just seemed likea very foolish thing to do.
And we can kind of see, I thinknow some of the cracks in the
armor that that's caused.

SPEAKER_02 (24:12):
Yeah.

SPEAKER_00 (24:13):
So for sure.
And there were a lot of peopleat the company at the time too
who like really were againstthat idea, but whatever, it
happened anyway.
And so like part of that processwas me internally like trying to
fight against it a little bitand like resisting that change a
little bit.
And so I sort of had this brainflash one day.
And I thought, what if webecause like a view component is
really just made up of its propsor it's arguments you pass into

(24:35):
the initializer and slots thatyou define.
It can really be reconstitutedfrom those two things.
And I thought, what if we likedefined that a JSON structure of
some kind in JavaScript thatprovided those pieces?
It provided the props and theslots, and then just sent those
to a special controller actionthat knew how to render whatever

(24:56):
component you wanted based onthat information and then
returned to you the HTML.
And so I mocked like a reallyquick proof of concept.
I also was thinking like, whatif it worked over WebSockets so
that you were not dealing with alot of the same like HTTP
overhead that you would normallybe dealing with in like a
server-side renderedapplication?
And so mocked that up.
I had it working in thislookbook thing, which is like a

(25:17):
Rails app that lets you previewview components and you could
click on a button and it woulddynamically add an item to this
action list component that wehad.
And I showed this off to a fewpeople, and the reaction that I
got was like really good.
I was like, this is people seemto think this is an that's
pretty cool that we could evendo this.
And I didn't think it was thatlike revolutionary.
It's like we're just you knowrendering stuff on the server

(25:37):
like we always have.
But yeah, I got a lot of wow,that's cool reactions to it.
And so I thought, okay, well,there might be something here.
But I kind of put that on ashelf for a long time because I
was still working on this likeneato idea and didn't know where
that was going to go.
And finally came to theconclusion that like this is
just like shipping more and morestuff to the browser is just
generally, I think, a bad idea.
I think that, and this is sortof where the conversation gets

(25:59):
maybe more philosophical.
I think we have to startthinking about the browser
differently than we are now.
And this is not just true ofRails developers.
This is true, I think, of ourwhole industry.
The browser is not somewherewhere you want to catapult a
bunch of code and just hope forthe best, right?
The browser is an environmentthat is at its fundamental core
good at like displayingdocuments.
Like it's not an applicationenvironment, at least it didn't
used to be.

(26:19):
And it is now because that'swhat we wanted to build.
All of us web developers wantedto start building more
applications.
Totally understandable.
And that's where like React camefrom because Facebook had this
ads product back in the day, andthey were like, we are having a
hard time updating this page andlike not breaking everything
with a single line code changebecause you targeted the wrong
ID, you know, this whole veryprocedural concept.

(26:41):
Like, I'm gonna with jQuery findan element, I'm gonna hide or
show it, I'm gonna maybe add aclass to it, remove a class from
it, right?
Like that kind of programmingwas like brittle and hard for
them to maintain for such adynamic product, like their ads
product they're trying to build.
So that's where React came from.
That's actually where a bunch ofother frameworks too came from,
like internally at Facebook.
They tried to build a couple ofother frameworks at the same
time, they're kind of competingwith React, and React eventually

(27:03):
won.
But the fact that the web andthe browser was not dynamic
enough is like where React camefrom.
But we have now come to a placewhere like the browser does a
lot of these things for us.
We have web components, we havethe CSS transitions API.
We have so many tools now thathave sort of been a long time
coming, granted, but are nowlike in the browser that we can
start to remove these hacks.

(27:23):
And I really think of React askind of a hack.
It was designed to fill thisvoid.
And I think it's debatablewhether it's removable in its
entirety now, but I think weshould at least start having
that conversation.
Because what I think React and abunch of other front frameworks
have done is sort of given uspermission to like focus on DX
over everything else and tofocus on entirely browser-driven

(27:43):
UIs that I think are doing theweb a real disservice, right?
Like Alex Russell, who is wasone of the Chrome leads for a
long time and I think works onEdge now, he has a blog called
infrequently.org where he writesabout how much of an impact too
much JavaScript has on the web.
And he has a sort of publisheslike a state of the web or a

(28:05):
state of JavaScript, I think,every so often.
And his 2023 one, he talkedabout how like how much
JavaScript and CSS like we canafford to ship with our
applications so that our pagesload within a certain amount of
time for the P75 of like devicesand networks.
And that amount right now, well,back in 2023, I think it's a
little higher now, was 300 to350 KB of JavaScript.

(28:29):
Now, if you've ever seen even aregular blog page, a lot of
people write their blogs inReact or View or something, and
they're shipping many, many moremegabytes than that of
JavaScript and browser.
And the problem that this causesis not one that us developers
see very much because we usereally high-end, generally,
really high-end devices.
We're on really high-endnetworks.

(28:50):
We don't often experience, Ithink, some of the same problems
that somebody in a developingcountry would run into.
And for some applications, it'snot a big deal because you know
that most of the customers thatuse it are going to be on a
high-end network, high-enddevice.
But for a company like GitHub,which is used around the world,
or a company even like, youknow, Salesforce is a good
example, or Zoom is a goodexample of it.

(29:11):
Like they have a their splashpage is like 11 megs of
JavaScript or something.
Like it's that kind of thingthat just feels so gratuitous
and that is, I think, damagingthe web and making it hard for
countries and people in thosecountries on low-end devices,
low-end networks, to access someof these same tools that we use.
And so it's really an equalityissue.
Even for people in the UnitedStates, or even people in
developed countries wherenetworks and devices are more

(29:33):
high-end, we still see this allthe time.
I mean, who among us has notloaded a web page and had it
just blank, show up blank?
It's just a white page,nothing's rendering.
You open the JavaScript console,there's like a hundred messages
in the JavaScript console allred, like this error happened,
and like how did nobody noticethis, right?
Or you click on a button andnothing happens, right?
So many different, I think,times that that's happened to

(29:55):
me.
And I live in the United States,I'm a white guy, like I've got a
great computer, nice MacBook M2,right?
I have all this high-end stuffand on a high-end network for
them compared to other networks,of course.
And even I have experiencedthese problems.
And I think that this is inlarge part due to the fact that
we, again, are like shippingsuper huge bundles of JavaScript
to browsers and we're focusingon DX rather than UX.

(30:16):
Like a lot of the conversationthat I hear about React is not
that it is bad or goodnecessarily, but that it's
really good for developers.
Oh, this is great.
I can write everything in onefile and I can bring components
in and I can update the state.
And there's all these complexstate management tools like
Redux that I can use to queryfor my back end for data.
And all that's developerfocused.
It's not user focused.
And that conversation, I think,is just really missing the user,

(30:39):
their experience.
I don't want to rally againstReact.
I think React is super cool andit has served a great purpose
over the years.
And I write React all on thedaily at Cisco because that's
what we use for our entire frontend.
So it's not like I'm reallyanti-React.
I'm just really wanting theindustry to take a step back and
realize that like shippingmegabyte after megabyte of
JavaScript to the browser isjust not serving users well and

(31:00):
is, I think, causing a hugeinequality gap in the web.

SPEAKER_01 (31:03):
Hard to argue with that.
I mean, React is a tool and it'sa great tool for doing certain
things, but it's a tool andpeople are trying to use it for
everything.
It's like I have a screwdriver,which is great for driving
screws, but if you flip it, youcould, if you wanted, hammer in
a nail with the handle of thescrewdriver.

(31:25):
And I think too many people aredoing that instead of reaching
for the right tool, the hammer,to hammer in the nail.
That's always been how I've feltabout React.
It was like someone would belike, Well, we could do it in
React.
And it's like, but why?
Like at Podia, we have a verysmall amount of React.
We have our site builder andemail builders because you need
that high level of userinteraction.

(31:48):
User needs to click a button orslide a slider, and they need to
see immediately something changeon the page.
React is really good at that.

SPEAKER_00 (31:57):
Yes.
And I would never say don't useReact.
I would never say don't use Vue.
Whatever.
I would never say only use webbecause there's just there's
always gonna be a class ofproblems for which React and
View and Angular are really wellsuited for.
But I do think that like mostweb pages, and I'm gonna go like
that level of granular, not somuch websites, but like

(32:18):
individual pages and maybe evenindividual sections of a page
can very easily be renderedstatically.
And the other and there's onlycertain parts of those pages
that need to be fully dynamic,fully reactified, whatever.
Yeah.

SPEAKER_01 (32:31):
Nothing is more frustrating than sitting there
waiting for a blog to loadbecause it's importing React so
that I can read your staticarticle.
At some level, I get it.
It's like if that's thetechnology you know, you go with
what you know.
I do get that.
But like I think that's more ofa byproduct of what you're
explaining.
There's like the core web thatwe should be using and reaching

(32:53):
for a tool like React when it'sneeded, not oh, you want to be a
web developer?
Learn React.
Don't even bother with the restof it.

SPEAKER_00 (32:59):
Yeah.
And I mean, I also think thatlike because React is so popular
and because it is kind of the defacto standard, like everybody
uses it now for everything, thathurts the web also from a
developer perspective becausenow there's fewer people
advocating for adding featuresthat React would normally table
for you to the browser and toweb APIs and whatnot.
It just sort of weakens the web,unfortunately.
And I don't want to say thatReact shouldn't exist, that we

(33:21):
shouldn't use it.
It's more just that I want thereto be a balance, right?
Yeah.
And that's a great segue intowhat live component is.
So there's many different typesof website you could build.
Purely static, of course, isone.
You could build an applicationwith Rails where like there's
multiple routes and you're maybesubmitting forms, and that's a
certain level of dynamism.
But then I think from there, thenext step is kind of it's either

(33:43):
static or dynamic.
But I what I'm trying to sort ofadvocate for with Live Component
is that we don't have to go fromone to the other and rewrite
everything and there's nothingin between.
I think that we there areoptions in between.
One of those options could bejust having React, but having it
be just individual portions ofthe page.
One option could be using webcomponents, which I think
doesn't cover all use cases byany stretch, but is good enough

(34:06):
for a lot of use cases.
I even think something likejQuery is good for a lot of use
cases.
Like 90% of the things that Iwas doing in my work on primer
was like hiding and showingthings.
If that element is on the pageand I target it with a selector
and then say hide or show, likeyou don't need React for that.
Just like jQuery.

SPEAKER_01 (34:22):
You shouldn't need React for that.

SPEAKER_00 (34:24):
You shouldn't.
But yeah, yeah.
Anyway, that's so what I'mtrying to do with this is just
to show that there's like maybenarrow that gap a little bit or
provide another tool that canfit within that gap.
You don't need to be fullydynamic.
We also don't want to be fullystatic.
And so beating around the bushenough just to say that I can
finally talk about livecomponent.
Live component is a way torender your view components like

(34:44):
client side.
And that's a little confusingbecause it's not actually
rendering the client side, it'srendering them server side, uses
the same technique that Idescribed working on at GitHub
back in the day, where thecomponent is defined by its
state.
And the state object is just aJavaScript, like a JSON object,
which has the parameters thatthe component was initialized
with, and it has the slotinformation and the slot
parameters that you initializethe slots with.

(35:05):
And all that information is likewrapped up into a single state
object, and we can send that tothe server, render the
component, and then get theresponse back and morph the
changes into the DOM.
So you can imagine like a to-dolist application, and you can
imagine there might be your listitems, and let's say you want to
edit one of them.
It says broccoli.
So you click on the edit button.
And in a traditional Railsapplication, what that might do

(35:26):
is re-render the page andnavigate you to the edit action
of the to-do items controller,and you would then be faced with
like a whole page reload, andyou would get an edit field and
a save button.
And you would click the savebutton that would post back to
the same controller and thenredirect you to like the list
page, and you could see theedited item from there.
In the React land, of course,there would be no refreshing.
You would be using the maybe thefetch API in the browser to post

(35:50):
to the controller, and then thatwould update the item.
And then React would just takeaway the input field and render
the text back up for you to seethe item.
So those are the two paradigms.
And I think in Hotwire, it's asimilar idea.
The difference would be justthat like when I submit the
form, it's also doing a fetch,but then it's rendering like the
results being rendered by thecontroller, and then it morphs
the changes at the DOM and yourinput field goes away and you

(36:10):
get the text back.
Live component works reallysimilar to how hotware works
because it's built on hotwireand it's built on stimulus.
So let's say you have a viewcomponent, it's like a to-do
item component, and you define asidecar, JavaScript, or
TypeScript file.
And in that file, you define aclass, it inherits from live
controller.
And then just using the regularstimulus, like targeting like

(36:31):
data action and data target,well, like when this button gets
clicked, I want to call thisfunction on my controller.
So you might say to do item editor whatever, you click the edit
button, and that calls yourfunction.

(37:37):
And then inside the function,instead of firing off a fetch or
something, you would just saythis dot render, and that would
then yield to you what lookslike a component instance.
And you can saycomponent.props.editing equals
false or true, and that's allyou have to do.
And what that does is it takesthe state that the component was
rendered with initially on thepage, changes that single prop

(37:59):
editing to true or false orwhatever, sends that to the
server, gets the response, andmorphs it into the page.
So you're literally re-renderingand then re-injecting the
rendered content into the DOM.
And you didn't have to wire upany IDs or anything.
You just had to define a sidecarJavaScript file and add a couple
lines of code.
So that's the goal of it.
It's supposed to like be thislike replacement for what you

(38:20):
might use React for.

SPEAKER_01 (38:21):
You go through this to-do list idea, which is your
standard to-do list, but just atthe first glance, just on your
basic docs page, it looks likeview components.
It's view components.
Right.
But you just have this one extrasidecar controller that's feels
magical, but we know it's not.
It's conceptual compression.

(38:43):
Like it's just what Jason had todo, like to find all these IDs,
link all these IDs up.
Like it kind of, and I don'tknow, I haven't had the
opportunity to use it yet, butit feels kind of like the
biggest win is like thatboilerplate's gone.
Like we can already doeverything you're describing,
even with hot wire.
You just have an endpoint, likeit goes there, yada yada.

(39:05):
But it really needs to renderout the whole thing.
You need to pass it a bunch ofinformation and then let either
turbo frames or turbo streams dowhat you need it to do.
This feels kind of like astreamlined version of that,
where like, hey, you clicked theedit button.
We're just gonna re-render thiscomponent.
We don't need to re-render thewhole page, we don't need a
special controller.

(39:25):
I mean, we do have a specialquote unquote stimulus
controller, but like that's it.
It's sort of the same idea oflike stimulus.
Stimulus didn't solve anythingnew.
You could do all of that withjQuery, like you could totally
target things, and like it justkind of wrapped it in a way that

(39:45):
was really easy on the brain.
Like, I just know like howactions and how targets and how
things get linked up.
I understand that, and now I'vegot an organized file instead of
jQuery soup.
It feels sort of like that forthis.
Yeah.
When you have like you said youkind of you're kind of meeting
in the middle of like the twoextremes of like static and

(40:07):
dynamic.
Like, are you thinking, what isthe intended audience for this?
Is it for someone who has like amostly static page and needs
those like dynamic islands?
Is it someone who's like, man, Ireally don't want to use React,
but I need the interactivity?
What stack are you mostlythinking live component works

(40:29):
really well in?
Like I can already conceptualizeit a little bit, but I want to
hear from you.

SPEAKER_00 (40:33):
Yeah, I think the target audience is kind of
somebody who already has a lotof view components, but is now
kind of getting to the point,just like we did at GitHub,
where like they want to add someinteractivity to those
components.
So, like a good example ofGitHub was this thing called the
select panel, which is part ofprimary view components.
And when you type into thesearch box, it's supposed to go

(40:54):
to the back end and get somesearch results and display them.
And then when you select thoseitems, it remembers those
selections.
And doing that in a webcomponent was really annoying.
You know, it was just notpowerful enough to do that kind
of thing.
And a big reason for that isbecause there was no concept of
like the DOM was the source oftruth as opposed to the state
being the source of truth,right?

(41:15):
Like the back ends data modelsand whatnot being the source of
truth, which is honestly the gapbetween React and not React is
like React has it renders thepage when your state changes
because it uses that state asthe source of truth as opposed
to the DOM.
The DOM should be the source oftruth for some things, but not
for a lot of things, right?
And so I think the audience ispeople who have view components

(41:36):
and that have struggled withtrying to get dynamic content or
dynamic behavior to work withthose.
Maybe they've tried to use webcomponents.
Like GitHub, we used webcomponents as like the little
add-ons, I guess you'd say.
Like you'd have it was sidecar,but not necessarily in a direct
sense.
It was just we had likeJavaScript web component and we
had the view component, and theywould target each other based on

(41:57):
like the custom element name.
But that's how we added dynamicbehavior.
And a lot of the time thatactually works super well.
But there were other times whereit was just like, this is
clearly not the right tool forthe job.
And so I think live componentstargeted toward that.
And I think if you're alreadyusing it, you might as well use
it for the things that you alsomaybe don't need full dynamism
for too.
So, because you don't have touse the re-render capabilities.

(42:18):
It defines a stimulus controllerand it wires up that stimulus
controller belt to the componentthat you rendered automatically.
So there's utility there too.
It's not like you have tore-render the thing dynamically
and swap in the HTML.
You could also just define thatcomponent and say, I want to
connect this component towhenever I render this view
component on in the back end, Iwant to automatically wire those
things together.
And when a button gets clicked,I can, and it's a little bit

(42:41):
more automated that way thanstimulus would be.
Like it registers a componentfor you with stimulus and again
wires the things together.
And so like I could also justuse it that way.
And actually, one other likekind of nice feature I think of
Live Component is that it doeshave a React integration too.
So if I have a React componentor I need to use React, but I
want to like send that Reactcomponent props from the back
end, like inertia would do, youcan also define like a React

(43:04):
component in Ruby land, and thenit will render your React
component and update its propsfrom the back end.

SPEAKER_01 (43:10):
Yeah, we actually have our kind of a homegrown
solution for like for doingstuff like that in Podia, where
we have a view component thatessentially renders a React
component and gives us a avenuefor sending it props so it'll
re-render for our site builderand email builder, which has
worked really well.
But you know, that's our owninternal.

(43:33):
We would never inflict that uponthe world.
It works for what we needed todo.
You know, I think Hotwire gotpretty popular because it does
require a mental model shift alittle bit, but not so
drastically.
If you were doing traditionalReact server rendering, then
Hotwire doesn't change a ton.

(43:55):
You have to make some tweaks toyour mental model, but like not
nearly as much as going like,well, we were doing server
rendering, but now we're an APIbackend with a React front end.
Like that's a huge mental modelshift.
How much of a mental model shiftdo you expect it to be for
someone like a traditional Railsdeveloper to come in and use the
live component?

SPEAKER_00 (44:13):
Yeah, that's a good question.
That's a really good question.
I've thought a lot about thatactually.
There's a slight mental modelshift, but not necessarily in
the parts you might expect.
I think that if you are a viewcomponent author, you're used to
writing view components.
You're sort of already used tothe sidecar idea because you've
got the component itself, the RBfile, and then you have like the

(44:34):
template file next to it, couldbe ERB or whatever you want in
there.
So that part of it should bepretty, I think, familiar to
people.
It uses stimulus under the hood.
So like when you define yourJavaScript class and you inherit
from Live Controller, that'sreally just a stimulus
controller with some extrabaggage in there to handle, I
should say baggage, some extrafunctionality in there.

(44:56):
Sure.
To handle the dynamicre-rendering and all that.
Oh, and then also one thing thatI haven't talked about yet, that
I'll just briefly mention now,is that it actually uses the
same like underlying hotwiremechanism to update the DOM.
Like if you're doing a getrequest, like I show on the
homepage of live component.orgwith the to-do item, when you
click the edit button, it'llsend the request to the server,

(45:17):
but it uses a get for that.
But if you want to post a form,actually in the to-do item
component, when you click thesave button, that's posting a
form to a Rails controller.
The way that the response worksin that case is that like live
component provides like anoverride to the form width
helper.
And so you have your form widthand it's inside your template in
your view component, and you cansay form width and give it the

(45:38):
URL or the model.
Or whatever, and then you cansay re-render colon self.
So you can say when I submitthis form, I want you to do
whatever the controller does,but then respond with the
re-rendered version of thiscomponent that I'm in right now.
So re-render self.
You can also say re-renderparent.
You can say re-render aparticular ID.
And what that does is it meansthat in the controller, you can
then say live.re render, like inyour template, and that will

(46:01):
automatically re-render thecomponent that the form targets.
So the form targets a particularcomponent.
Like when you're in yourcontroller and you're in your
action responding to thatrequest, you can say live.re
render and it'll implicitlyunderstand, like, okay, you want
to re render this component thathas that like wraps the form,
and it will re-render thatcomponent.
You can provide new props andthings to it.

(46:21):
And that's all done with hotwirewith turboframes.
It actually renders a turboframe and then live component
will extract the content out ofthat turboframe and put it where
it needs to go.
Hopefully that's clear.
I it's hard to sort of justspeak out the code.

SPEAKER_01 (46:35):
Yeah, but the docs are good.
The docs are very good.
I felt like I had a good mentalmodel of what was happening with
live component.
It made sense to me while I waslooking through it.

SPEAKER_00 (46:46):
I did want to touch on your question about like
what's different, what mentalmodel shifts need to happen.
I described all the ways thatit's not different, but there's
all there is a way that it isdifferent.
And that is like when youprovide props to a component,
like the way the live componentworks is it tracks the
initializer arguments.
It uses that to know what you'vepassed into your component, and
then it will look for instancevariables with those same names

(47:07):
and then will track thosethings, which means that state
is entirely defined by theinitializer.
You can't provide state in anyother way.
And I think that that does, andthat's on purpose.
That's to keep things reallyobvious.
Like this is where my statecomes and this is where my state
gets set.
That it just means that derivedstate is a little bit more
difficult to sort of understandor intuit.
It's not quite the same thing aslike I'm just newing up a Ruby
object, passing some state in.

(47:27):
Like that state has to then comeback again to be used a second
time.
And keeping that in mind can bea little bit of a mental shift.
Hopefully that's described wellenough in the docs, but I do
anticipate people kind of beinga little bit surprised by that.
So hopefully it's not too big adifference that people will not
want to experiment with it.

SPEAKER_01 (47:43):
I think that's one of those spots where the
experimentation becomes veryimportant.
The actual, like, I've read thedocs now.
Do I want to do this?
It's like, well, you need toexperiment with it.
You need to understand now myinitializer needs to be the
source of truth.
We all do some things afterinitialization.
We call a method or somethingthat will set up some state

(48:07):
based on parameters for us.
And you might not be able to dothat exact thing with live
component.
You might need to take aslightly different approach.

SPEAKER_00 (48:15):
Yes.
I think especially around activerecord objects, that gets a
little confusing because Idon't, you don't necessarily
want to be doing lots of I.O.
like when you're trying tore-render a component.
And so there's those mechanismsfor serializing your active
record objects or like pullingindividual columns off of your
records and storing those in thestate object so that if I go

(48:35):
back and need to access those inmy re-render, I don't have to
hit the database for that.
And that's in the docs as well.
So the claim on the homepage isthat components can re-render in
50 milliseconds or less.
And when I was first working onthis, I know, yeah.
When I was first working onthis, that was what I was
seeing, and not just in dev.
I also deployed it to Heroku andI was seeing really good
performance there.
And for whatever reason, Itried, and I of course had added

(48:56):
features and things to it, andthis may be where the slowdown
comes from, but I don't know.
I wasn't able to figure thisout.
And I even tried the headerinstance in Oregon, it's closest
to me, and tried one in Virginiato see like what the difference
would be.
Because I live in California, solike Oregon's really close, but
like Virginia is pretty faraway.
And there is definitely a markeddifference between the latency
between those two servers.
And so what I see now is like ahundred milliseconds or less for

(49:17):
a server that's close and like120 for one that's kind of far
away.
I mean, I would love it to beless than that.
I mean, in development, you seewhen the server is cold, it's
like 50 and then it gets down tolike 18 in some cases.
Like really, really fast, yeah.
Yeah, but like obviously that'snot production, it's not live
actual workloads.
Well, and this is why I reallylike I'm trying to like not say
like this is a React replacementnecessarily.

(49:39):
I mean, I I think it for someuse cases it can be.
For some it cannot, though,because React is going to render
much faster than that.
That's why it's it's sort of aplayer in the gap between static
and dynamic.
It's not fully dynamic and it'snot fully static, right?
There's like a but I think youget a lot from that.
You get to reuse your existingcomponents, you get to use the
Rails paradigms that you alreadyknow, like stimulus and hotwire.
And the only thing you're reallydoing is paying a slight network

(50:00):
tax, like we're already payingfor so many other things.
So I think the trade-off isworth it.
And again, it's for some usecases, like not for everything.
For live component, you canchoose to either use an HTTP
transport between the front endand the back end, or you can use
WebSockets.
I found that the Russia was notany performance difference
between those two things.
Really?
And part of that is because I'mjust not that good at setting up

(50:23):
action cable servers.
I think if you were to use anycable or something that's more
efficient, it maybe would be itwould be better.
I do think HTTP is just simpler.
And so that was kind of what Iused for the most part, but it
does work with both.

SPEAKER_01 (50:36):
Is that a global setting where you're like, I use
HTTP or I use WebSockets, or canyou do that on a per component
level?
Like this component trends, youknow, uses WebSockets because
one reason, and these don't needthe WebSocket whatever.
So HTTP over here is it globalor per component?

SPEAKER_00 (50:55):
It is global right now.
It could be per page.
If you load a new page, okay,then all the JavaScript gets
reevaluated and you could swapin the transport at will.
It's still a global setting, butyou could in a component on a
page, you could swap in adifferent transport and then
swap back to the other one ifyou wanted to.
It's not like there's nothingpreventing you from just
switching objects, I suppose.

(51:16):
But that's a good point.
Maybe we should do it at thecomponent level.

SPEAKER_01 (51:20):
So performance-wise, it's it's pretty quick.
There's small network latency,as with anything.
But is there anything, hey, at acertain level, because all of
these live components are hookedup potentially via WebSockets or
HTTP?
Like you have to beconsideration.
Like, even like you'reessentially serializing state

(51:41):
through the initializer.
Is there a limit if you've got20 keywords in your initializer
now because you're serial andwe're trying to serialize a
state like now our network callsare getting very large, and
sure, this is potentially not agood use of this, or you need to
break that up more, or I have aton of slots.
Like, is there any anything toconsider like that?

(52:02):
Oh, absolutely.

SPEAKER_00 (52:03):
Yeah.
I mean, and I have not hit thosepersonally because the stuff
that I've done with this so farhas not been of huge size.
I did the to-do list app.
You can actually see that at todo dash list.licomponent.org.
There's also crosswise.rocks,which is like a little set of
mini-games, one of which is acrossword that uses live
component.
And you can pop open the networktab and see what it's doing and

(52:23):
see how fast or not fast it is.
But I do think, I mean, anytimeyou're sending data over the
network like this is doing,you're you're gonna run into
diminishing returns the more andmore data you're shoving over
the wire.
It tries to be as efficient asit can, of course.
Like it does compress requestsand responses using, I think it
uses broadly compression, whichis really good for text, which
is what this would be mostlydoing.
Sure.
Yeah, yeah.

(52:43):
So that shrinks the payloads by65% or something.
So like there's a good amount ofa win you get from that.
There is a big difference.
Like Postgres, for example, willnot store payloads larger than
64K, I think, in for WebSockets.
Uh, if you're using the PostgresiNotify system, which a lot of
people do.
If you're using that, there's alimit to how much you can a

(53:04):
message size limit.
It might be 16k.
It's it's actually pretty small.
And I actually ran into thatmyself when I was trying to test
crosswise because crosswise,it's a mini crossword puzzle,
and there are 16 squares, Ithink.
And it keeps the state for eachof those squares.
So there's like a bunch ofnested JSON structures in there.
And that turned out to be toobig for Postgres.

(53:25):
That's why I added thecompression feature.
So trading off space for computecycles there.
Fortunately, the browser hasthat built in though.
So it's you're just runningnative code to do that.
So yeah, the there aredefinitely performance and I
think implications of too manyslots.
I think you see that even withregular view components.
We actually had somebody when Iwas still working for GitHub who
was wanting to render, I thinkit was a table, and that table

(53:46):
had like hundreds of rows in it.
And the way the view componentwould have you do that is to
define like a row class, like arow component, and then on the
table you would say with row orwhatever and provide the
columns.
And he was like, this is takinglike whole seconds to render,
it's just way too slow.
And our answer to that wassorry, like we don't really have
a good answer to that.
Because it just doing anythingelse is kind of against like the

(54:07):
architecture of the componentsystem itself.
So you're there are going to belimitations like that that I
would imagine people would getto if they have too many slots.
It really depends on how biglike the number of keyword
parameters you're passing into acomponent is probably not the
limiting factor there.
The limiting factor is like howthose get serialized.
So if you're serializing astring, that's just there's a
one-to-one mapping between aRuby string and a JavaScript

(54:29):
string.
Those two things exist in bothlanguages, but active record
models might be a differentstory.
I think by default, livecomponent serializes all the
attributes.
No, that can't be right.
I don't remember the default.
It serializes a couple thingsfor you.
If you serialize too manyattributes and you have a bunch
of different active recordmodels, potentially a list of
them that you're passing in, andit has to serialize all of
those.
And yeah, that could be reallyheavy.

(54:50):
There is, I think, going to bejust discrepancies between
people's mental models now andwhat they might need to adopt to
use live component.
And another one of those thingswould be just like how much are
you serializing over the wire?
And like live component tries tolike provide a bunch of
mechanisms to limit thatserialization, like how much you
have to serialize and how muchyou have to deserialize.
But you know, if you're notpaying close attention to that,
you could definitely run intosome issues.

SPEAKER_01 (55:12):
Which actually kind of makes me think like, what's
the debugging experience like?
Because now there's an extratransport layer essentially.
I mean, when you're debuggingwith live component, is there an
extra consideration because ofthe hidden transport layer?
Or is there anything that thatthe live controller that you

(55:33):
inherit from for your sidecarcontroller that is more
complicated, or that it you haveto take into consideration when
you're trying to debug?
This wasn't exactly what Iexpected.

SPEAKER_00 (55:45):
Man, that's like one of the major reasons why I
stopped working on Nito, whichwas that fully in the browser
transpiling thing.
I didn't even mention this.
I used Opal at one point, alsogot it working on Opal,
Ruby.wasm, the Garnet thing.
Like all of those suffered fromthe same problem, which is they
were just way too complicated.
And debugging them was reallyhard unless you knew what was

(56:06):
going on.

SPEAKER_02 (56:07):
Yeah.

SPEAKER_00 (56:07):
And like I'll be honest, I barely knew what was
going on.
Especially with the thing.
Yeah, no, right.
Like Ruby.wasm in particular wasreally hard with that because
like it's this black box Wasmenvironment.
And I would like, I don't know,I'd run a line of code, it would
spit back this error that madeno sense.
Like, what do you mean?
I'm not, I wasn't even awaitinganything.
Why are you telling me that youcan't await something?
Anyway, so like thenon-debuggability of it was

(56:29):
really a factor.
And one of the things that Ilove about Live Component is
that there isn't that same sortof complexity at play.
I mean, there obviously is morethan you would normally be
getting with like a regularRails app that's just using
hotwire and stimulus.
But because it uses hotwire andstimulus behind the scenes, like
if you're familiar withdebugging those things, then
you're gonna be right at homeusing Live Component.

(56:50):
It's using the same mechanismsunder the hood.
You can also like pop open yourdeveloper tools, the network
tab, you can see what it'sactually sending and receiving
from the back end.
So hopefully that is gonna befamiliar to most Rails devs.
Where things might get a littlemore complicated is just in that
re-render loop.
If the database is getting hitfor some reason and you didn't
mean for it to get hit, or ifsomething's getting serialized

(57:13):
and then not deserializedcorrectly, like those things can
be challenging because all thoseserializers live like in the
live component gem.
They're not, I mean, you canwrite your own, of course, too,
but you might not be able to seewhat's going on behind the
scenes there.
So there could be somechallenges there.
I personally have not run intothose because you can usually
like just set a breakpoint likein your components initializer
and you can see what you'regetting back and then determine.

(57:36):
Hopefully, from there, it'senough information to determine
like what went wrong.
One thing that I have wanted toadd and have not added yet is
like an error page.
Because right now, if you clickon a button and it goes to the
server to re-render a component,but like an error happens in
that, like on the back of likesome Rails error gets thrown or
something, or you're referencinga local variable that doesn't
exist or whatever, then thaterror it comes back to you, but

(57:59):
you can't see it on the page.
You can only see it if you'vegot your developer tools open.
And if you click on like thatone network tab, it'll show you
like a Puma rendered error,which is literally just a text.
It's just like a the errormessage in a stack trace, like
that's it, right?
You don't get any special Chromeor anything.
And so what I was thinking wasit'd be super nice to have like
what React does in this case,which is or some flavors of

(58:19):
React, like Storybook will dothis, where it will like pop
open like an overlay over thetop of your page and say, here's
the error, and here's the stacktrace, and like here's where you
should go to to debug it, right?
So hopefully you can add that atsome point.
Yeah, I'm hoping that generallyspeaking, the debug experience
is pretty straightforward formost Rails devs.

SPEAKER_01 (58:37):
Going through the docs, it's like all these
questions I wanted to ask andthings.
I tried to keep it so like, allright, we'll talk about
debugging.
We're talking, but like the onepotentially deep question that
isn't super high level that youwill only understand if you've
read the docs.
So I'm sorry, listeners who Imight be confusing with this,
but so you have two life cyclehooks before update and after

(59:03):
update.
And as a Rails developer, anykind of life cycle hook in
anything kind of is like, allright, what are the foot guns?
How can I shoot myself in thefoot with these?
Like, what is your expected useof those?
And what are ways that youalready can envision someone
abusing those hooks?

SPEAKER_00 (59:21):
I think in live component, right?
I mean, there is an initializerbecause stimulus controllers
have initializers, or at leastthey have a connect function, I
think it is.
But it's not the sameinitializer that you would have
in Ruby.
Like it's not passing in props,right?
And this is also different thanthe way React would work.
Like React, you would have youdefine a function that's your

(59:42):
component, and you'd receiveyour props in that in the
functions argument list.
And in Ruby, that's the same waythat you would do things.
You get the argument list.
But in on the JavaScript side,you don't get that argument
list.
And the reason for that isbecause the state object
contains those arguments, andthat state object is serialized
as like a giant JSON object,like attached to a data property

(01:00:05):
on the web component that livecomponent renders on the back
end.
And so when that component getsinstantiated, we have to go
fetch that object and parse it.
And then we have to propagatethat state.
Oh, something I should havementioned, by the way, we were
mentioning like performanceissues is you know, a live
component contains its ownstate, but it also contains the

(01:00:26):
state for all of its children.
And when it renders, it passesthat state down to each child.
And the state, of course, itlike shaves off bits of the
state like as it goes down,because some of that state
pertains to the parent, somepertains to the child, and it
just keeps propying that statedown.
That happens every time itrenders from the server, it kind
of has to.
Anyway, so that's just to saythat that state object has to
get parsed and propagate thestate has get propagated down.

(01:00:47):
And the when that state getspropagated, there is like that's
when the lifecycle hooks getcalled.
So it gets called during thatpropagation step.
And so those two hooks are sortof designed to be like the
initializer in a sense.
Okay.
If you need to do something whenstate updates, that you would
put that code inside eitherbefore or after update.

(01:01:08):
So yeah, they're designed aslike sort of before and after
initialize.
So the things that I use themfor in my own code is to set up
derived state that I can onlyreally get from the browser.
Like if I need to call athird-party API or whatever, or
I need to call a, I'm gonnaforget the exact the specifics
of where I use this because it'sbeen long enough.
I know that Crosswise, you canlook at the code for that, by

(01:01:29):
the way, it's on GitHub.
Crosswise does this a couple oftimes where it needs to hold on
to certain state.
And so it does that in, I thinka before, before update
callback.
Yeah, hopefully that answersyour question.
I think that like two, beingthat this is a new project that
people haven't used that much,including myself.
I mean, I've built severalthings with it to like flesh out
how it should look, but youknow, it still hasn't seen that

(01:01:50):
many real-world use cases.
And so I wonder like, are thereprobably will be opportunities
to add either additional hooksor modify the ones that exist?
But to be clear, that you askedlike what are some of the foot
guns?
If you are doing a lot of workin those methods, like something
that's maybe compute intensivein your browser, that will slow
down the entire renderingprocess.

(01:02:10):
So you do need to be careful tonot do too much in those, I
think.

SPEAKER_01 (01:02:13):
Okay, that makes sense.
Yeah.
Yeah, I have so many otherridiculous questions and like
rabbit holes we could go down,but like gotta keep moving.
Because I do have anotherquestion to ask, and it's about
blockers, which I feel likecould be a good one here.
Although, I mean, I could almostguess that one of the blockers
is like, hey, this hasn't had aton of adoption yet.
So you don't have a ton of usersoutside of the person who wrote

(01:02:36):
the thing.
So you need that kind oftraction.
But like, what is another typeof blocker, whether it be
something that's blocking you onnow, or I was blocked by X and
this is how I solved it, orblockers around not the use of,
but the building of LiveComponent.

SPEAKER_00 (01:02:54):
A big blocker that I had recently, I was working on
the Snake game that's wasactually for my daughter.
She was like trying to find agood snake game for her iPad,
and like they were all like fullof ads and like way too
complicated.
We just like wanted the originallike Nokia version.
Yeah, sure.
And she actually she has thislittle like camera that she got
from her grandparents, and thecamera has like Snake on it, but

(01:03:16):
like we don't want her staringat that all the time, and like
it would be nice if it was abigger screen.
And so I was building the snakegame on crosswise.rock.
So you can go there, like Ithink right now and say slash
snakes or whatever, and you canplay the game.
But the problem that I ran intowhen I deployed that to
production was that like youwould click the button to like
make the snake go, like turn aparticular direction.

(01:03:39):
And because of that hundredmillisecond latency, if you did
that too early or too late, itwould not do what you wanted it
to do.
And the first time that sheplayed, she's only six.
So the first time she playedthat game, she got super
frustrated and like tried tolike I don't think she threw her
iPad, but she was like, Dad,this is not working.
And I was like, Oh my gosh,she's right.
This is terrible.
And so I had to go in and figureout how to make it more

(01:04:01):
consistent.

SPEAKER_02 (01:04:02):
Yeah.

SPEAKER_00 (01:04:02):
This is actually a really interesting, I think, use
case.
Because if I had done this withReact, I would never have had
these problems because the pagere-refreshes would re-render
much more quickly.
But because there's a hundredmillisecond latency and there's
a timer involved, because thesnake has to move on a timer as
well as the result of yourclicking the directional arrows,
there was a race conditionessentially in like if I click
the button, but like we'realready in the middle of a

(01:04:24):
render cycle.
Like if I'm the timer hasalready fired, but the page
hasn't updated yet.
And so I think I still have timeto click a direction arrow.
And I click that directionarrow, the way that live
component works, there's like atask queue built into it.
So anytime that you take anaction that requires a
re-render, it enqueues thattask.
And these are all async tasks.
And so I don't want them to runat the same time because one

(01:04:46):
could overwrite the otherdepending on how the server
receives them, right?
And so they're all queued behindeach other.
And we guarantee that we processthe one that was fired first
before the one that was firedsecond.
And so what you were getting waslike the timer one would
enqueue, and then the click onewould in queue, and the timer
one would go first, and then thebutton one would go next.
And what that would result inwas like the snake advancing

(01:05:08):
potentially into the wall whenyou already clicked the no go to
the right button.
Yeah.
Right.
So you would lose.
And it was confusing because youthought, oh, I've got enough
time.
I've still got what half asecond to click the button, but
then you actually didn't becausethe anyway.
So that was where the confusioncame from.
And so that was a blocker for awhile because I was trying to
give this to her as like aChristmas present.
Sure.
I think that's the first versionwas like on Christmas Day.
I like pull her iPad out and goto the site, like, okay, try

(01:05:30):
this.
And she's like, it sucks.
I'm like trying to figure itout.

SPEAKER_01 (01:05:33):
And real world user feedback.
It sucks.
Thank you.

SPEAKER_00 (01:05:39):
That's funny.
The blocker was that sort of ina nutshell.
And so the solution that I cameup with was because I didn't
know what to do initially.
I was like, this is kind of acrazy problem.
Like, and I don't think this isa problem that most people are
gonna have because most peopleare hopefully not gonna write
games with live components.
The reason that I wrote gameswith it because I wanted to like
really push like the boundariesof how real time it could be,
right?

(01:05:59):
And so the fix I ended up doingwas it was adding a flag to the
render process where you couldsay like preempt true.
And if preempt is true, then anytasks that are currently in the
queue get cleared out when thenext one comes in.
So what that meant was we whenyou click the button, that would
clear out the timer in queuedone and just process the button

(01:06:19):
one, and that pretty much solvedthe problem.

SPEAKER_01 (01:06:21):
As you were describing it, I'm like, I don't
know if game building was theuse case I was envisioning for
live components.
But that is like I liked how youwere like the reason why you
were doing it was to see howmuch you could push the real
time because 100 sub 100milliseconds is pretty damn
fast.
Yeah, but it is cool.
Like you have that experience.

(01:06:43):
This isn't what you would use itfor in production, but because
you're doing it, you've kind ofuncovered this.
If you really need this actionto supersede everything else,
now you have a mechanism fordoing that.
And I think that's right,probably what you'll end up
getting a lot of feature-wisewhen other people start to use
it and use it in ways that youweren't even necessarily

(01:07:05):
anticipating someone using live.
Like there might be, hey, I wanta feature for this, and it's
like, yeah, that's not what webuilt this for.
It's not really how you shouldbe using it.
But there's also tons of usecases where it's like, huh,
that's a use case I hadn'tanticipated.
What's a good way to fit intothe spirit of live component of

(01:07:26):
feature that allows you to dothis?

SPEAKER_00 (01:07:28):
For sure.
I mean, I do anticipate thatthere will be like some other
like timing related problemswith the library, depending on
what you're trying to do withit, just because that's not
really my area of expertise.
Like, I'm not Concurrentdistributed systems programmer
for the most part.
Sure.
But hopefully most of the of thecon edge cases are covered.
That's awesome.

SPEAKER_01 (01:07:48):
So the last question is always my favorite.
And I feel like live componentas a whole could have been the
answer to this question.
But you've already used it, soyou can't answer with live
component.
What is something cool, new, orinteresting that you've recently
built or discovered or read oranything?
Like what's something thatyou're I just want to share?

SPEAKER_00 (01:08:10):
Okay.
You've talked about hockey, Ithink, on this podcast a few
times.
Yeah, a couple of times.
I just have to shout out theSeattle Seahawks right now.

SPEAKER_01 (01:08:18):
And that's not a hockey team for anyone who
doesn't follow sports for therecord.

SPEAKER_00 (01:08:23):
No, sorry.
It's just a sports, it's asports team.
It's along the same lines as thehockey in terms of the sports
angle.
But yeah, no, I'm a big Seahawksfan, have been for a long time,
and just impressed with theircurrent run in the playoffs.
So go Seahawks.
Hopefully they can beat the Ramsthis weekend and against the
Super Bowl.
We'll see.
And sorry about the Eagles.

SPEAKER_01 (01:08:41):
I mean, I don't see, I'm not a big football guy.
So like my brother andsister-in-law are huge Eagles
fans.
So like we have a meme chatwhere everybody dumps memes
every other day, whatever.
And for at least three days, itwas all crying Eagles something,
like someone in pasting Eaglesplayers into some meme or

(01:09:03):
whatever.
But yeah, there was a bunch ofpeople in the area very upset.
I am a Flyers fan, so I'm justused to disappointment at this
point.
Okay.
Um I haven't had the experienceof like, oh, we were good for a
few years there.
Um I'm like every time we win acouple of games in a row, I'm
like, hey, this is awesome.
But yeah, it's might be ouryear.

SPEAKER_00 (01:09:25):
For the longest time, the Seahawks were not
competitive, right?
Like it was just lots of ups anddowns, mostly downs, especially
because the West Coast tends tokind of get overlooked a little
bit for a lot of things, andsports teams being one of them.
But the true mark of a fan isthat you stick with them through
all the good and bad times.
And so big respect for theFlyers fan fandom there.

(01:09:46):
Cause it's like it's just goingto make it all the sweeter when
they do put stand a cut, right?
Yeah, it'll be great.

SPEAKER_01 (01:09:50):
It'll happen.
I do think we've made some bigfront office changes, and I
think it needs a few years toreally settle in.
We have a lot of prospects thatare coming up.
Our really good players arereally young.
So as they get more and moreexperience, I think there's a
good future, but I'm also beingcautiously optimistic because
it's true.

(01:10:10):
I've said that before and beenvery wrong.

SPEAKER_00 (01:10:13):
No, I know.
It's so hard, it's impossible topredict.
Yeah.

SPEAKER_01 (01:10:17):
Yeah, sports is crazy.
I think the first year that theEagles won the Super Bowl, like
it was against the Patriots.
We had our backup quarterbackin.
Yeah.
No one expected them to win.
And then it was like theflukiest, weirdest.
I don't know what happened, butsomeone who wasn't the
quarterback threw the ball andthen the quarterback caught it,
and it was crazy.
Yeah.
Yeah.
And everyone lost their minds.
And there was rioting inPhiladelphia because our sports

(01:10:39):
team won.
Yeah.
And for some reason, that's whatwe do.
I do enjoy the Super Bowl.
And I think it's universal ofsports, like playoff sports and
especially the championship.
Like there is nothing betterthan that game.
The worst is when you have ifit's a series or if it's like
the Super Bowl is a one gamewhen it's like someone got in

(01:10:59):
there by a complete fluke andthey're not even competitive and
it's complete blowout.
Like, that's so disappointing.

SPEAKER_02 (01:11:05):
Yeah.

SPEAKER_01 (01:11:05):
I love seeing the best of the best, or like the
representative of the best faceoff against the other
representative of the best forthis is peak football,
basketball, baseball, hockey,whatever it is.
So good.
It's another level of intensityand energy.

SPEAKER_00 (01:11:24):
It's so true.
And I in football, like you doget that sometimes.
Sometimes you don't, though,because like it's always the AFC
versus the NFC in the SuperBowl, the two different
conferences.
Yeah.
And sometimes there are justbetter teams on like it's
Lopsided.
Sometimes the better teams arein the NFC, sometimes they're in
the AFC.
And so we at the Super Bowl, youdon't really get the two best

(01:11:44):
teams.
You just get like the best teamfrom one, and then like the best
team from the other, which maynot be the overall best.
Sure.
And I think that's kind of whathappened Seahawks versus Broncos
in 2013.
Not that the Broncos were a badteam, they just were in the AFC,
and so they were playingdifferent caliber teams than the
Seahawks were.
And that's why it was such ablowout.
This year, there are so manygood teams on both sides that

(01:12:07):
God knows what's going tohappen.
I mean, nobody can predict.
All the pundits are like, well,I think it could be this team
this week, and then the nextweek they're like, nope, I was
wrong.
It's gonna be this team.
You know, nobody knows.
So it's gonna be a good idea.

SPEAKER_01 (01:12:17):
And it's wild that one injury can change the entire
landscape.
Because totally that one injury,if it's a star player, oh no,
what do we do now?
But also those injuries can theperson who replaces that person
has the next man up mentality,which is you've I've seen it in
so many different sportingevents.
It's like that next man upmentality can be huge, and

(01:12:39):
otherwise a mediocre player cansuddenly turn into a superstar
just because they're likeprofessional athletes have a
different mentality in generaltoo.
It's it's wild.
Yeah, it's really fun to watch.

SPEAKER_00 (01:12:54):
Yeah, super fun to watch, yeah, for sure.

SPEAKER_01 (01:12:56):
So yeah, good call out.
Is there anything else whilewe're still chatting that you
want to talk about, whether belive components or what you're
doing at Cisco or what you'vedone at GitHub or well, really
interesting block or I missedanything.
The floor is yours if you wantit.

SPEAKER_00 (01:13:12):
Let's see.
I guess I'll just Cisco Merakiis great if you want to work
there.
I'm sure we have open roles, gocheck it out.
And it's probably one of theonly companies that's like
hiring consistently these days.
There's not always openings, butthere there often are.
So if you're looking for a RailsRuby job, check out Cisco
Meraki.
Yeah.

unknown (01:13:27):
Awesome.

SPEAKER_01 (01:13:27):
Yeah, and shout out to Alan and Fito.
I love them.
They're always spreading thegood word about Cisco Meraki at
all the conferences.

SPEAKER_00 (01:13:34):
So totally.
They're awesome.
I talk to them frequently.
The other thing I might want tosay is that the I'm also one of
the co-organizers of the SF Rubymeetup.
If you are in the area, weactually it's to as we record
this, the next meetup is today.

SPEAKER_01 (01:13:48):
Is it always the second to last Thursday?
Or is there a little variable?
How often it's pretty variable.

SPEAKER_00 (01:13:53):
You can go to like our Luma, so Lou.ma lu.ma slash
SF dash Ruby, and that's our ourmain page that talks about all
the upcoming meetups and stuff.
We're having one actually atCisco Marocki in March.
Cool.

SPEAKER_01 (01:14:05):
Check it out.
Very cool.
SF Ruby looks awesome.
If I find myself in the SanFrancisco area, I am going to
hopefully time it so that I canmake one of those meetups
because it they look awesome.

SPEAKER_00 (01:14:17):
Yeah, thank you.

SPEAKER_01 (01:14:18):
So great.
Yeah.
Shout out to SF Ruby andawesome.
So thank Cameron, thanks forcoming on and talking about all
the cool stuff going on withLive Component.
Seems like a really interestingproject.
I'm excited to use it, if not atwork, on side projects and just
tinker with it because that'salways fun when you've discover
something new and you get toplay with it.

(01:14:38):
So yeah, for sure.

SPEAKER_00 (01:14:40):
So well, thanks so much for having me on.
Super fun.
And took a long time out of yourday.
I really appreciate it.

SPEAKER_01 (01:14:44):
No worries.
It's hey, it's if we're talkingabout something cool and
interesting, I don't mind atall.
Where can people find you on theinternet if they want to learn
more about live component orjust follow you and your work?

SPEAKER_00 (01:14:55):
You can go to livecomponent.org.
There's no hyphens or spaces,it's just live component.org.
That's the doc site.
You can go to github.com slashlive component.
Again, no spaces or dashes orunderscores.
And then I am available onGitHub at github.com slash
camera tron, c A M E R T R O N.
I'm also on Mastodon atCamratron at Ruby.social.

(01:15:16):
I think that's it.
Awesome.

SPEAKER_01 (01:15:19):
I'll put all the links in the bottom so it's real
easy for people to track youdown.
And thanks again for coming on.
Listeners, I will see you in thenext one.
Bye.
Advertise With Us

Popular Podcasts

Stuff You Should Know
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

Betrayal Season 5

Betrayal Season 5

Saskia Inwood woke up one morning, knowing her life would never be the same. The night before, she learned the unimaginable – that the husband she knew in the light of day was a different person after dark. This season unpacks Saskia’s discovery of her husband’s secret life and her fight to bring him to justice. Along the way, we expose a crime that is just coming to light. This is also a story about the myth of the “perfect victim:” who gets believed, who gets doubted, and why. We follow Saskia as she works to reclaim her body, her voice, and her life. If you would like to reach out to the Betrayal Team, email us at betrayalpod@gmail.com. Follow us on Instagram @betrayalpod and @glasspodcasts. Please join our Substack for additional exclusive content, curated book recommendations, and community discussions. Sign up FREE by clicking this link Beyond Betrayal Substack. Join our community dedicated to truth, resilience, and healing. Your voice matters! Be a part of our Betrayal journey on Substack.

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

Connect

© 2026 iHeartMedia, Inc.