Logo
    Login
    Hackerspace
    • Learn
    • Colleges
    • Hackers
    Career
    • Jobs
    • Applications
    Profile
    • Login as Hacker
    Paul College

    Clash of Frameworks

    0 / 10 chapters0%
    Course Introduction
    Next.js
    Configuration
    Creating a chat list
    Creating an AI chat
    Next steps
    Tanstack Start
    Configuration
    Creating a chat list
    Creating an AI chat
    Next steps
    React SPA
    Configuration
    Comparison
    1. Clash of Frameworks
    2. Creating a chat list

    Creating a chat list

    In this chapter, we'll redesign our layout to include a sidebar with a chat list on the left and chat content as the main area. For now, the main content will remain empty as we focus on building the chat list functionality.

    Need Help?

    If you encounter any difficulties, you can always reference the complete code from this GitHub repository:

    https://github.com/pouljohn1/tanstack-chat

    Note

    Some parts of this chapter are similar to or the same as the previous Next.js module

    Prerequisites

    First, we need to install some shadcn components. Run this command in your terminal:

    bash

    If the CLI doesn't install icons automatically, run bun add lucide-react.

    This creates new components in the components/ui folder. Feel free to explore them to see how they're built.

    Cleaning Up the Default Content

    Now we need to remove Tanstack Start example web page content. First let's move to src/routes/index.tsx and remove everything and leave just simple div component:

    typescript

    index.tsx is a main web page of the tanstack app.

    Configuring the Layout

    Now let's configure the main layout. In Next.js there was a layout.tsx file that contained the layout of the whole app.

    In the TanStack Start app we have it in the src/routes/__root.tsx file. When you open it you will see that it exports one property called Route which is being created by calling createRootRoute. createRootRoute has a shellComponent property that is basically an equivalent to layout.tsx in Next.js.

    Let's change our RootDocument to match what we had in the Next.js app. Replace the whole content with:

    src/routes/__root.tsxtypescript

    You'll see an error about a missing @/components/ChatSidebar file. Let's create it!

    Create a new file ChatSidebar.tsx in the src/components/ folder with the following content:

    src/components/ChatSidebar.tsxtypescript

    Great! Now we have the backbone of our application. In your browser, you should see something like this:

    Basic Layout

    Creating the Chat Storage

    Next, we'll create the code for storing chats. First, we need to define a Chat type. Create a new folder and file at src/types/chat.ts with this content:

    src/types/chat.tstypescript

    Next, we'll add a simple in-memory storage with database functions. Create src/db/chat.ts with the following content:

    src/db/chat.tstypescript

    Contents of the file seems to be obvious - we've created two functions here:

    • getChats - Retrieves chats from the local chats array.
    • createChat - Creates a new chat.

    Creating Server Functions

    Now we have database-related code, let's add some Server Functions (remember that Next.js had also server functions?). Differently from Next.js we will create a folder /src/api and will create chat.ts file in it with a content:

    src/api/chat.tstypescript

    The first thing you'll notice is the createServerFn method. This is similar to Next.js's use server directive but written in a more functional style with the ability to specify which HTTP method it should use.

    Also, we've created two Server Functions instead of one as it was in Next.js. getChatsFn also needs to be created and we cannot use getChats directly like we could with Next.js Server Components.

    Fetching Data

    Now we have all the infrastructure needed to connect it to our components. Go to src/routes/__root.tsx and add getChatsFn as follows:

    src/routes/__root.tsxtypescript

    As you can see, we made several changes:

    • added loader prop to createRootRoute function. loader is an async function where we need to fetch all backend related data. That data is then passed to component
    • Added Route.useLoaderData() located in react component which get's previously fetched data in loader
    • Passed the chats data to ChatSidebar

    Remember how it worked in Next.js?

    In Chapter 2 of the Next.js module, we discussed whether it was safe to call database functions directly in components.

    Here in TanStack Start, we need to create and call a Server Function that is explicitly passed to a component. This brings us to the most important thing to understand about TanStack Start:

    All code in TanStack Start is isomorphic by default - meaning that all of the code you write here runs on both the client and the server. There's no automatic magic like in Next.js Server Components. You must be explicit about what runs where. If you want to learn more look at Tanstack Router documentation.

    Displaying Chats

    Now let's update ChatSidebar.tsx to display the chats:

    /src/components/ChatSidebar.tsxtypescript

    What we've done here is iterate over the received chats and create an item for each one. If there are no chats, we display a "no chats" message.

    You should see something like this:

    No chats image

    Creating a New Chat

    Now let's add the ability to create new chats! We will create a section at the start of the <SidebarContent> component with an add button and will make use of server functions to add new chats:

    /src/components/ChatSidebar.tsxtypescript

    Let's review what we did here:

    1. First, we imported all necessary components, icons, and function requirements
    2. We added an Add Chat section with a button that calls the submitChat function
    3. The submitChat function calls the addChatFn Server Function and then invalidates the page, which causes the loader function to be called again and the data to be refreshed

    Now you can test it! Click the New Chat button in your browser. After a few clicks, you should see a similar view:

    Chats image

    Better Storage

    Now we can create and view chats, but there are some problems with our current approach:

    Chats are not persistent after page refresh

    Why does this happen? The issue is that we're storing chats in an in-memory array that lives only for the lifetime of the server process. In development, the server may restart, and in production deployments (especially serverless environments like Vercel, Cloudflare Workers, or Netlify), each function invocation may get a fresh instance with a new empty chats array. This means our data disappears on every refresh or deployment.

    TanStack Start can run in both traditional Node.js servers and serverless environments, but in-memory storage is ephemeral in both cases. We need persistent storage.

    We need a better approach for this. Normally you would use a database or cloud storage, but for this course we'll store data locally as a file. This will persist through refreshes and across server function calls.

    Let's get started! First, we need to create utilities for file storage. Create src/lib/fileUtils.ts with the following content:

    src/lib/fileUtils.tstypescript

    This utility provides two functions:

    • readContent - Reads and parses JSON data from a file, creating the directory if it doesn't exist
    • writeContent - Writes data to a file as formatted JSON

    Next, we need to update our src/db/chat.ts functions to use these utilities:

    src/db/chat.tstypescript

    Key changes we made:

    • Removed the in-memory chats array
    • getChats() now reads from the chats.json file
    • createChat() reads existing chats, adds the new chat, and writes back to the file

    Now when you add chats and refresh the page, they should persist. Great work!

    Next Steps

    Great! We now have our first working feature. Users can create and view chat objects. Remember, this isn't just frontend code - we already have a backend with React components, server functions, and persistent storage!

    Ready to move on?

    Mark this chapter as finished to continue

    Ready to move on?

    Mark this chapter as finished to continue

    LoginLogin to mark
    Chapter completed!
    NextGo to Next Chapter

    © 2025 Hacklab

    • Privacy
    • Terms