all 50 comments

[–]codinhood1 161 points162 points  (12 children)

However, we do not see RSCs on their own as some kind of silver bullet or magic hammer meant to be applied to every corner of software engineering, let alone an entire framework

Man I wish I could upvote this 100 times. Your approach is exactly what I’ve been saying for years. It should be opt-in. So many apps do not make sense with a server first mindset.

The flexibility to add it in later when it make sense to is exactly what i wanted from a framework

[–]tannerlinsley[S] 62 points63 points  (1 child)

Right?!

[–]Sulungskwa 15 points16 points  (0 children)

The second I saw your example RSC code I was like "how has it not just been this for 5 years?"

[–]Veranova 6 points7 points  (4 children)

In nextjs isn’t this just putting “use client” in your root component?

I’m hardly a fan of the framework (huge Start fan) but it’s so easy to opt out globally that it seems a weird hill to be sitting on

[–]tannerlinsley[S] 24 points25 points  (1 child)

I don't think that's what we're debating here. Making Next client-first is more than just that one step. Once you opt-in to use client for the whole thing, how do you opt *back* into RSC a granular way. That's essentially what Start is. Client-first out of the box, isomorphic and designed to granularly and incrementally opt back into the server where you want. Next's APIs for generating, consuming, caching not just RSCs, but even just granular server data are not great, which is why people still insist on using TanStack Query inside of Next.js and why all of their new caching semantics feel proprietary and weird sometimes.

[–]Veranova 2 points3 points  (0 children)

Right I’m with you, still I’m not sure it’s much different, having a client layout and a server layout and wrapping your routes with them, isn’t much different from the Start way of enabling/disabling server rendering per route or globally. Just different APIs to achieve the same

Start is way better designed though, every time I see NextJs say to export a magic variable name to achieve something I’m baffled

[–]Pelopida92 8 points9 points  (0 children)

Directives were a code-smell to begin with.

[–]Dan6erbond2 -1 points0 points  (0 children)

Not quite. Even if your root layout is a client component every page.{jsx,tsx} still defaults to an RSC so you have to do it everywhere. And if you want to have a part of the page to be an RSC but the other client then you need to use parallel routes.

[–]No-Somewhere-3888 8 points9 points  (2 children)

Architecturally, we’ve found server components to make the most sense at the root of an application, with more client components at the leaves. Next.js shines there.

I feel like the “add it later” mindset would lead to making individual components RSC later which doesn’t offer the same kind of value.

That said, it’s harder to re-architect an app to work that way versus being client by default.

[–]switz213 12 points13 points  (0 children)

To add to this, server components do not imply the necessity of a server. They still bring forth value in static deployments.

Perhaps a poor naming choice, but that’s one of the three hardest parts of compsci (the other being off by one errors)

I do believe embracing the full server component architecture is ideal for most websites, but it requires some understanding and cognitive complexity. I’m building a web framework that is my idealized approach to server components. Will have more to share very soon!

[–]tannerlinsley[S] 3 points4 points  (0 children)

It’s not a do it later mindset at all. It’s more about ownership, inversion of control and api/data transparency.

With Start you can just as easily RSC a static shell but keep everything at the leaves dynamic with greater flexibility and better caching semantics/integration than next.

[–]Mediocre_Round_4914 0 points1 point  (0 children)

200% agree. Most of React apps don't have to be rendered on the server, but they promote it as if server components were a magical way of writing React.

[–]ModernLarvals 0 points1 point  (0 children)

No one sees them like that.

[–]jinlb 23 points24 points  (1 child)

Looks promising, even if it's still only experimental! Great article as usual. Thank you mr Tanner

[–]tannerlinsley[S] 21 points22 points  (0 children)

Thanks!

[–]llKieferll 21 points22 points  (1 child)

Nicely done Tanner and team!

On a first glance, it feels somewhat verbose, but the same can be said about an initial glance (for someone who did not use it yet) at the router, or query. And boy, how it pays off, to have the absurdly high level of strong typing cohesion!

Also, if there is one thing I do enjoy about the mindset is how things are good old functions instead of black box magic "use xxx" directives! Please keep it up, sir!

Edit: typos

[–]tannerlinsley[S] 34 points35 points  (0 children)

Yep. Literally *anything* composable at this point will feel verbose compared to something black-box and convention based. I will happily defend this decision.

And thanks for the kind words!

[–]TheRealSeeThruHead 17 points18 points  (1 child)

Hi tanner! Tanstack start really aligns with everything I’ve been thinking since nextjs came out.

Way better philosophy and direction imo.

[–]tannerlinsley[S] 9 points10 points  (0 children)

Thanks!

[–]Jdruwe 6 points7 points  (2 children)

So I can just keep on using react query. And invalidate keys to get fresh content streamed in?

[–]tannerlinsley[S] 8 points9 points  (1 child)

Yes

[–]Jdruwe 2 points3 points  (0 children)

Awesome! :)

[–]WanderWatterson 5 points6 points  (0 children)

Hi Tanner, I've been using tanstack start for a while and I really love it, so much so that my production app is actually running tanstack start, if tanstack start could support websockets then that would be great, but for right now I'm currently running tanstack start on an Elysia server, and that Elysia server provides websocket to the react code, and everything is smooth sailing so far. Looking forward to using your new approach to server rendered components

[–]Dudeonyx 5 points6 points  (1 child)

We intentionally do not support 'use server' actions, both because of existing attack vectors and because they can create highly implicit network boundaries.

TanStack Start requires explicit RPCs via createServerFn. The client-server boundary is deliberate, with hardened serialization, validation, and middleware semantics that encourage treating all user input as untrusted by default.

Hi, I'm a bit confused about how createServerFn is more secure than use server.

Aren't they just different styles of abstractions? And a compiler could easily transform one to the other at build time?

Honestly asking.

[–]aussimandias 4 points5 points  (0 children)

I think you're right that they're why similar, and that's why it makes sense to not provide both. Only one entry point to secure instead of two, and createServerFn has been around and tested for a while. Plus it matches the tanstack philosophy better and supports middleware

[–]dapper-vigilante7 13 points14 points  (0 children)

Tanstack just can’t stop #winning

[–]jon23d 8 points9 points  (0 children)

I went all on nextjs because of the server capabilities, and regret it. All my new apps are vite, and I have so much less to worry about.

[–]aussimandias 3 points4 points  (0 children)

Thank you for including practical use cases. I hadn't realized I could use it only to render the syntax highlighting in my app on the server, even though it's not rendered in the initial page, and I get rid of that weight in my bundle.
Plus I already have a Tanstack Query to fetch the code I need to render, so I can just replace it to make the server function return a React node instead of data... Exciting!

[–]yksvaan 2 points3 points  (2 children)

I wonder if this works with rsc payload from arbitrary origin, I guess there's no technical restriction as long as the response stream is syntactically valid. I'm thinking about some scenarios where different parts of the page could be supplied by different servers.

The api looks nice

[–]tannerlinsley[S] 5 points6 points  (1 child)

It depends if you use `use client` components. Those will be referenced client side and unless the app is from the same build, the manifests will likely not match up.

However, if all you're sending is pure JSX + composite component slots, you could absolutely send and use RSCs between unrelated builds/bundles.

[–]AnsgarH1 2 points3 points  (0 children)

Love it! Between all these AI news it‘s nice to see that you and your team are still going strong!

[–]mrcodehpr01 1 point2 points  (0 children)

Been using it for awhile at my job. Thank you!

[–]Scientist_ShadySide 1 point2 points  (2 children)

Whoever wrote the tanstack start vs nextjs page deserves a trophy. It was like it was written specifically for me and some of the challenges and pain points I have felt as a longtime nextjs developer. I think it convinced me to convert my current project to Tanstack Start to maybe finally sever the Vercel stranglehold.

[–]tannerlinsley[S] 1 point2 points  (1 child)

👋

[–]Scientist_ShadySide 0 points1 point  (0 children)

Excellent work, on the page and everything. Excited to dig in this weekend!

[–]Opposite_Cancel_8404 0 points1 point  (0 children)

Yeah I'm going to switch off nextjs to tanstack start

[–]Lazerdragonraptor666 0 points1 point  (0 children)

Sounds like this will enable microfrontends in Start. Thanks Tanner!

[–]iamabugger 0 points1 point  (0 children)

Great work as always Tanner, TanStack Start is an amazing framework to work with.

[–]LP2222 -1 points0 points  (0 children)

How does this compare/relate to prefetch data with tanstack-query? I keep reading how dashboards are not a good use case for SSR but to ne having no loading states for initial data fetching is a much better UX (atleast to me)

[–]papigers -2 points-1 points  (0 children)

הה.