How exactly is Tanstack Start is "client side first"
I'll be giving a talk tomorrow on Tanstack Start, and why I'm upgrading my remix app to it. One of the things I'd like to talk about that I don't know how to explain on a fundemental level but can just kind of feel when I use it for now is the whole "Client Side First" principle of it
Right now the best I can do is show that certain client side libraries just work out of the box with Tanstack Start that were a massive pain to get to work in Remix...
- react-hot-toast
- react-tooltip
- styled components
I'd love to be able to explain this on a mechanical level but right now the best that I can do is...
Both Remix and Tanstack Start first create your react components on the server, then hydrate them on the client, but for some reason in Tanstack Start... it just works better. I know that's not a great answer, I can demonstrate this pretty easily, but would love to back this up with a bit better of an understanding on exactly how that is achieved.
If I can't get a good explanation it's not a big deal, still got tons of cool stuff to demo, but I thought it would be worth a quick ask!
74 Replies
ratty-blush•9mo ago
Sup Jon
I subbed to your talk tomorrow
I'll take a stab at a few points:
- It's isomorphic (which is harder to explain than client-first)
inland-turquoiseOP•9mo ago
I was told, I've been kicking it into overdrive ever since finding out
ratty-blush•9mo ago
So everything that runs on the client, runs on the server
But not the other way
So there can be server code that stays on the server (via createServerFn or
use server
RPCs)
So that's a big departure from Next, which is very server-first
So much of it is API design
In Next, you have to opt-in to the client (with use client
)
In TSS, you have to opt-in to server-only (with cSF/use server
)
Remix is also very client-side first in practice
However, their APIs are not designed to surface that
e.g. loader
is essentially a createServerFn
inc-lavender•9mo ago
loader is server only IIRC in remix
Yeah that
inland-turquoiseOP•9mo ago
I thought I was going to have to learn a new tech term with IIRC 😂
ratty-blush•9mo ago
Basically, TanStack Start APIs are completely optional and opt-in to the already SPA experience of the Router
Remix is also "opt in", but it doesn't feel that way, because of how their APIs are designed to become "server first" (loader) as soon as you go into framework mode. Every navigation will hit the server (you can get around this easily, but that's the point, it's the default)
It's very nuanced
FYI, Remix and RR people don't like that I'm using "client-side first" because they are technically client-side first too
It would be better to describe it as "client-side APIs that feel at home to SPAs, but without compromsing full-stack capabilities"
inland-turquoiseOP•9mo ago
So is effectively all the magic starting with the fact that createServerFn can be serialized to a url and fetched from the frontend?
ratty-blush•9mo ago
Yeah, it's generated RPC instead of generated REST
At the end of day too, I just think we're doing less weird stuff compared to Remix. Better defaults, caching, infinitely better types, and routing features that RR will never consider adding that make life so much easier
The router is so much more important to compare than the full-stack stuff
inland-turquoiseOP•9mo ago
All this I'm rock solid on
ratty-blush•9mo ago
RPC vs REST is not a big difference
But it's a nice one IMO
inland-turquoiseOP•9mo ago
Here's my slide that will be accompanied by alot of talking that just goes over cool features

ratty-blush•9mo ago
Get rid of Vinxi
We're moving away from it
Same capabilities, just no Vinxi
inland-turquoiseOP•9mo ago
Is that because of new vite stuff?
v6
ratty-blush•9mo ago
That's part of it
But mostly, just a stalled project
Need more control and better cadence
At the end of the day, you know better than anyone the differences
inland-turquoiseOP•9mo ago
I also imagine it's a better sell to say you're not a framework built on a framework built on a framework
ratty-blush•9mo ago
Even if it comes down to "TSS is more intuitive and flexible for me than Remix"
Yep
Doesn't matter that much though
Meta frameworks are just layers of abstraction
inland-turquoiseOP•9mo ago
Ok, is it ok if I take a real quick attempt at making a chart to explain the "why remix doesn't feel good client side"
ratty-blush•9mo ago
Removing middlemen from those abstractions is a good idea always
inland-turquoiseOP•9mo ago
working on something in excalidraw now
ratty-blush•9mo ago
Sure!
inland-turquoiseOP•9mo ago
Also one quick thing, I was planning on AB'ing remix vs tanstack for a slide (also going to do this with some real code examples that I'm throwing together tonight)
fascinating-indigo•9mo ago
Will this talk be streamed? I'm interested in seeing it
inland-turquoiseOP•9mo ago
And I have one big difference between the two as far as what they both offer and do well
inland-turquoiseOP•9mo ago

inland-turquoiseOP•9mo ago

inc-lavender•9mo ago
The way I see it the big difference is what happens after the first page load. Tanstack Start gives you the tool to have every navigation after that be client first. RR is "reload every page Server Side" by default instead
Or at least Remix was
inland-turquoiseOP•9mo ago
@Tanner Linsley While I had ya just wanted to make sure that you were cool with this framing. Specifically for me I remember one frustration with remix was having to write
form.get
and how maybe striving to make the framework feel like old school html wasn't necessarily the most ergonomic choice for complex applicationsinland-turquoiseOP•9mo ago
I Upgraded My Remix App... To Tanstack Start
Remix was an awesome framework, but Tanstack Starts' extremely pragmatic approach to web development has won me over!
inc-lavender•9mo ago
Yeah Remix's obsession with FormData just because its "pure HTTP" puts me off
inland-turquoiseOP•9mo ago
works great right up until it doesn't then it's either unusable, un-agreed upon how to do things correctly, etc...
inc-lavender•9mo ago
The fact that it's untyped by default makes me feel all dirty
If I wanted to use "pure HTTP" I'd unironically choose PHP. I've heard great things about it recently
inland-turquoiseOP•9mo ago


inc-lavender•9mo ago
Tanstack doesn't have RSC yet AFAIK
inland-turquoiseOP•9mo ago
The "I'm not Tanner Linsley, but did talk to him" explanation of why Tanstack feels better on the frontend is because at it's core once your frontend is loaded it's just a frontend, where remix at default is still trying to do a bunch of magic to SSR everything after that first load.
inc-lavender•9mo ago
And you wouldn't invalidate the entire page like Remix but just the queries you need to re invalidate if you are using Tanstack Query
inland-turquoiseOP•9mo ago
I'll have the react query = TSS demo pulled up and ready to go if someone asks about that, I hope they do 🙂
inc-lavender•9mo ago
But maybe with actions. Tbh I don't know I never use them
ratty-blush•9mo ago
Yeah, forms are optional in TSS
Remix loves to flex that they're progressively enhanced and that it's all "the platform"
But sometimes.. the platform isn't great
Or the happy path is an abstraction
In this case, I would rather assume users have JS
e.g. URLSearchParams sucks
HTML forms aren't type safe (by default)
inland-turquoiseOP•9mo ago
One of the big Code A -> Code B comparisons I want to try and get ready by tomorrow is how I made my own custom modal-rendering-through-url engine, and how Tanstack is built to fix that
ratty-blush•9mo ago
yeah
That's a good one
inland-turquoiseOP•9mo ago
But the problem is I haven't actually fixed that part yet, so I'm going to crank that out tonight
ratty-blush•9mo ago
And when we do parallel routes, it'll be even easier
inland-turquoiseOP•9mo ago
That's one I'm excited for too
inc-lavender•9mo ago
Tbh I don't think these no-JS users actually exist. Crawlers for sure, but that's what SSR is there for.
inland-turquoiseOP•9mo ago
Well my thinking is if they do they probably shouldn't be using remix anyways
ratty-blush•9mo ago
Their claim is that every user is a "No JS" user until JS is loaded
inland-turquoiseOP•9mo ago
Like probably astro or something
ratty-blush•9mo ago
Which is fair... if you have terrible connections and massive bundles and interactive elements that get SSRd in
There is a chance someone will click a button before it's ready
inc-lavender•9mo ago
Yeah Astro for sure if those are your constraints
ratty-blush•9mo ago
Yep
Apps are generally behind an auth
And nothing really useful can (or should be able to) happen before JS is loaded
I won't say it doesn't happen or exist as an issue
But it's not one that I'm concerned about
And not one that I'm willing to obsess over and brand an entire framework and it's APIs around
I would so much rather make anything interactive be disabled out of the box until ready than do double duty to make it work without any JS AND with JS
exhausting.
inc-lavender•9mo ago
Sounds exhausting ye
ratty-blush•9mo ago
It is
Nice to just skip a lot of that and just... call functions, RPCs and handle responses
Do away with actions, GET/POST/PUT/PATCH/DELETE
And focus on fine-grained invalidation
inland-turquoiseOP•9mo ago
I have to say I'm extremely impressed with how quickly the middleware/validations feels like the best out of any react metaframework by a landslide to use
inc-lavender•9mo ago
The whole "submit a form" for every action is so 2004
I did that. I'm glad we don't do that anymore.
AJAX was what unironically got me extremely interested in the web at the time
I remember the Facebook chat the first time it came out. Magic
Oh yeah let's talk middleware. IIRC the Remix team is opposed to it in principle. I'll never understand that
TSS it just works out of the box and it has embedded type safety. Similarly to tRPC
inland-turquoiseOP•9mo ago
Full disclosure, the only two negatives I'll be mentioning about my entire experience porting things over are:
1. Some weird error messages, the worst one being
import {z} from "vinxi"
2. Some mild type conversion issues with serverFns, that are actively being worked on and corrected
Both of which are extremely forgiveable in genera, not to mention that start is still in Beta.... I honestly can say I feel like I'll experience more stability on a beta product given how remix upgrades have gone in the past (plus the fact that they basically deprecated remix)
Nearly everything else has been not only tolerable but legitimately pleasant to work oninc-lavender•9mo ago
I've got my maybeAuth, requireAdmin, requireAuth middlewares and I use them everywhere. Just plug and play
inland-turquoiseOP•9mo ago
The auth story is another thing I've been super impressed by
The experience of defining something in the beforeLoad of a route, then being able to access that in nested routes is insane
I think the hardest part of this presentation will be that I can't do all the things I really want to... The goal is very much to code something live because I want people to see what typesafety means not just take my word for it
inc-lavender•9mo ago
Coding live sounds fun
😅
The thrill of live demos
inland-turquoiseOP•9mo ago
At least the framework author won't be monitoring my every mistake 🤣
inc-lavender•9mo ago
😅
inland-turquoiseOP•9mo ago
Side note, I have a lot of experience doing this kind of thing because I was a teacher for 2 years (coding specifically)... but I've never ever done a slideshow presentation in front of actually knowledgeable devs before
inc-lavender•9mo ago
Anyway, it's been fun. If you have recordings please post them somewhere. I'd love to watch it. Good luck 🤞
inland-turquoiseOP•9mo ago
Will do 🙂
Thank y'all so much for the help, this is a very very kind community and I deeply appreciate it
ratty-blush•9mo ago
Excited!!
tame-yellow•9mo ago
I woke up late in the night and followed your talk. Thank you @Jon Higger (He / Him) 👏
fascinating-indigo•9mo ago
Had to drop but yeah nice work. I haven't delved much into search params and stuff
broad-brown•9mo ago
Actually a good point. You’re using a JS framework already anyway.. why pretend we’re still in 98?
Yeah so happy with this counter argument. I feel most frameworks (Remix, Next) lately are optimizing for very edge case (or even invented) scenarios at the expense of general (99%) UX and DX. Glad there’s still a community with common sense
Care to share? I’m about to start porting over a project and these sound useful
inc-lavender•9mo ago
Sure. As soon as I find the courage to get out of bed
If you use
maybeAuth
in server functions then viewer.user
is possibly null. If you use one of the other two then it's guaranteed to be non null.broad-brown•9mo ago
Noice, smart. Thanks!
inc-lavender•9mo ago
I have sort of a complicated viewer object:
but you get the gist.
national-gold•8mo ago
@Jon Higger (He / Him) is it possible to still watch your talk or perhaps you can share the slides? I am interested on pitching a very similar talk within my company and it would be great to get some ideas
inland-turquoiseOP•8mo ago
@diegogb_08 https://www.youtube.com/watch?v=mM6mbOzvTpY
React Denver
YouTube
React Denver - January 7th - I Upgraded from Remix to TanStack Start
Have you heard of TanStack? If you loved the Remix framework but found some parts of it challenging to work with, you won't want to miss this talk! Jon Higger, a developer who's been there, will be sharing his insights on why TanStack Start has won him over. After a rocky experience with the Vite plugin for Remix 2, Jon found TanStack’s pragmati...
national-gold•8mo ago
thanks @Jon Higger (He / Him) great talk ❤️
inland-turquoiseOP•8mo ago
I really appreciate that 🙂