This is a premium alert message you can set from Layout! Get Now!

create-t3-app vs. RedwoodJS: Comparing full-stack React frameworks

0

Nowadays, speed and productivity are the key factors in beating the competition when it comes to app and web development. This is why full-stack frameworks have gained popularity, providing devs with a solid base to efficiently implement projects that require both frontend and backend development.

In this article, we will be comparing two full-stack React frameworks: create-t3-app and RedwoodJS.

The former is a CLI for full-stack Next.js projects, while the latter is a full-stack React framework with an integrated CLI. Both have open-source codebases on GitHub, meaning anyone can explore the code and contribute.

We will take a look at the main technologies they are based on, learn how to set them up, explore the internal build structure for both, see how to work with frontend and backend development, and review what API solutions they support.

Let’s get started.

Jump ahead:

Overview

create-t3-app

One of the main cornerstones of create-t3-stack – besides simplicity and modularity – is type safety, therefore the project requires users to use TypeScript.

The project is built on top of Next.js, so if you are familiar with its file structure and features, it will be easier to get started with create-t3-app, or T3 Stack.

The recommended styling solution is Tailwind, which is a utility-first framework based on concise classes that can be efficiently composed directly in the markup.

Prisma is suggested as a database client, while tRPC is offered as the core solution for API calls. The user can also use NextAuth to speed up the authentication for the project.

The original creator of T3 Stack itself is Theo, and the create-t3-app CLI tool was made by nexxeln. If you want an indication of the popularity of this project, look no further than its progress towards the end of 2022:

Theo popularity graph.

Impressive, right?

RedwoodJS

The typed syntax for RedwoodJS is optional. The user has a chance to bootstrap the project either with Vanilla JS or TypeScript by adding the --ts flag in the installation command.

RedwoodJS follows the patterns of React and is not further based on any other framework – the styling libraries can be optionally added with a single terminal command.

Instead of using tRPC, RedwoodJS uses GraphQL for its API solution. Similarly, Prisma is used as a database client.

On top of that, users can utilize Storybook as a UI component catalog, test all of the code paths with Jest, and do logging with Pino.

RedwoodJS was founded by Tom Preston-Werner, Peter Pistorius, Rob Cameron, and David Price. It has grown steadily since 2020, reaching 14K+ stars in about 3 years:

RedwoodJS popularity graph.

Setup

create-t3-app

To set up a create-t3-app project, users can use either npx, yarn, or pnpm by running the following commands in the terminal, respectively:

lang=bash
npx create-t3-app@latest
yarn create t3-app
pnpm dlx create-t3-app@latest

For the purpose of this article, we will use npx. Run npx create-t3-app@latest t3app in your terminal.

That will take you through a simple terminal wizard, asking you to configure the project. We will select all the available technologies in the wizard, which are; Prisma, tRCP, NextAuth, and Tailwind.

Terminal wizard

Once the setup is complete, change the working directory to the newly created project folder by cd t3app, then push the Prisma database instance via npx prisma db push and run npm run dev to start the development server.

To preview the application, open your browser, paste http://localhost:3000 in the URL bar, and execute. You should be presented with this:

Application preview

RedwoodJS

Setting up RedwoodJS is equally simple, although there are some differing nuances. For RedwoodJS, yarn is a requirement, there is no interactive terminal wizard, and by default the app runs on a different port.

Run yarn create redwood-app --ts ./redwoodapp to start the setup:

Start setup

Once the installation is complete, change the working directory into the newly created folder via cd ./redwoodapp and run yarn rw dev to start the development server.

It should bring up your default browser and present you with the RedwoodJS welcome page. If this does not happen, enter http://localhost:8910 in your browser URL and execute:

RedwoodJS startup page

File structure

create-t3-app

At the root level, both the frontend and backend live in the src folder. The only things that are separated are the database schema in the prisma folder and the public assets like favicon, images, audio, and related files.

The src folder is further divided into six subfolders: env, pages, server, styles, types, and utils.

  • The env folder contains the code to ensure the app is built with valid env vars
  • pages is used to create new pages and API endpoints
  • server holds the information about the database client and the router configuration
  • styles is for the external stylesheet files
  • types is for NextAuth type definitions
  • utils is for additional tRCP configuration

The overall schema of the file system should look like this:

Schema of the file system for T-3.

RedwoodJS

In RedwoodJS, the frontend is fully separated from the backend. All the frontend code is stored in the web folder, while the backend code is in the api folder.

The frontend is then divided further into the public folder, which holds all the public assets for the app, and the src folder, which is further divided into components, layouts, and pages that allow the user to create individual components and common layouts and import them into the pages.

The rest of the individual files in the src folder are meant to implement the root-level logic of the application, style it and provide the routing between pages.

The backend is further divided into:

  • A db folder for database schema
  • A dist folder for compiled code
  • A types folder for compiled GraphQL types
  • The src folder

The src folder is then further divided into directives for GraphQL schema directives:

  • functions for lambda functions generated by Redwood
  • graphql for GraphQL schema
  • lib for configuring auth, database, and logging
  • services for business logic related to your data

The overall schema of the file system looks as follows:

Schema file for RedwoodJS

Frontend

create-t3-app

Since create-t3-app is based on the Next.js file structure; all the pages are stored as a separate file in the pages folder.

Once you give the file a name, it automatically becomes a route. For navigating between pages, you can use the built-in Link component.

To create a new page test that links back to the home, you can create test.tsx in the src folder and include the following code:

lang=typescript
import type { NextPage } from "next";
import Link from "next/link";

const Test: NextPage = () => {
  return (
    <>
      <ul className="flex">
        <li className="mr-6">
          <Link href="/">
            <a>Back to home</a>
          </Link>
        </li>
        <li className="mr-6">
          <Link href="/test">
            <a>Test</a>
          </Link>
        </li>
      </ul>
      <p>This is a test page</p>
    </>
  );
};

export default Test;

We chose to install Tailwind in the setup wizard and already used it in the code snippet above to configure the flex layout for navigation.

In order to preview the result, open your browser and navigate to http://localhost:3000/test.

Tailwind for T-3

RedwoodJS

To create a new page in RedwoodJS, it is recommended to use their scaffold command yarn redwood generate page test, where test would be your desired page title and route.

It will automatically create a new file web/src/pages/Testpage/Testpage.tsx with the following code:

lang=typescript
import { Link, routes } from '@redwoodjs/router'
import { MetaTags } from '@redwoodjs/web'

const TestPage = () => {
  return (
    <>
      <MetaTags title="Test" description="Test page" />
      <p>
        Find me in <code>./web/src/pages/TestPage/TestPage.tsx</code>
      </p>
      <p>
        This route is named <code>test</code>, link to me via `
        <Link to={routes.test()}>Test</Link>`
      </p>
      <p>
        The link to home `<Link to={routes.home()}>Back to Home</Link>`
      </p>
    </>
  )
}

export default TestPage

Notice that the routing is imported from @redwoodjs/router and then the path name is used as a method on the routes. For the home route, you would first create a new page via yarn redwood generate page home / and then use the routes.home() method.

The scaffold command will also populate the web/src/pages/TestPage with two additional files: TestPage.test.tsx for testing purposes and TestPage.stories.tsx for allowing you to work with Storybook.

If you would like to style the page with Tailwind, you would first need to run yarn rw setup ui tailwind and then use it as in any other React app.

In order to preview the result, open your browser and navigate to http://localhost:8910/test.

Tailwind for RedwoodJS

Database

create-t3-app

The suggested way of handling the communication between the app and the database is via the Prisma client.

To do this, create-t3-app already has a bootstrapped scheme, which is available in prisma/schema.prisma. For the purpose of this tutorial, open it and include the code:

lang=prisma scheme language (PSL)
generator client {
    provider = "prisma-client-js"
}

datasource db {
    provider = "sqlite"
    url      = env("DATABASE_URL")
}

model Post {
    id    Int   @id @default(autoincrement())
    title String?
}

To save any changes in the Prisma schema, run a migration using the command npx prisma migrate dev --name init. The --name flag allows you to assign the migration name right from the terminal command.

That will create the migrations folder inside the prisma directory, including the migrations file with SQL commands to update the database.

After the migration is complete, generate the Prisma client via npx prisma generate.

Now, you can view the database in Prisma studio. You can access it by running npx prisma studio, which will start it on http://localhost:5555.

Database in Prisma studio (T-3).

RedwoodJS

Redwood uses Prisma as the ORM as well, so it follows a similar structure for the scheme.

The only difference is that in RedwoodJS it is located at api/db/schema.prisma. For the purpose of this tutorial, open it and include the code:

lang=prisma scheme language (PSL)
datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator client {
  provider      = "prisma-client-js"
  binaryTargets = "native"
}

model Post {
  id    Int   @id @default(autoincrement())
  title  String?
}

To migrate the changes in the schema, you have to run yarn rw prisma migrate dev --name init. It will create a new path, api/db/migrations, and include the SQL file with queries to update the database according to the schema.

Similarly, you should be able to access the Prisma studio. Run yarn rw prisma studio and it should start it on http://localhost:5555 if the port is available.

Database for Prisma studio

Server side

create-t3-app

The communication with the backend in create-t3-app is provided via tRPC. To give you an idea of how it works, we will create a simple read functionality for the posts in the database.

First, open the Prima studio and create a few records in the Post table so we have some sample data to work with:

Sample data in Prima studio (T-3).

Then, create a new file /src/server/router/post.ts, initialize a new postRouter instance, use the query() method to add an all endpoint to the router, and query all the posts via Prisma’s findMany() method:

lang=typescript
import { prisma } from "../db/client";
import { createRouter } from "./context";

export const postRouter = createRouter().query("all", {
  async resolve() {
    return prisma.post.findMany();
  },
});

After that, import the postRouter in /src/server/router/index.ts and merge all routers into a single appRouter via merge() method:

lang=typescript
import { createRouter } from "./context";
import superjson from "superjson";

import { postRouter } from "./post";

export const appRouter = createRouter()
  .transformer(superjson)
  .merge("post.", postRouter);

export type AppRouter = typeof appRouter;

To display the posts, use the useQuery() method and access the all endpoint of the posts, and then map through the received data. To achieve this, change the /src/pages/index.tsx to the following code:

lang=typescript
import type { NextPage } from "next";
import { trpc } from "../utils/trpc";

const Home: NextPage = () => {
  const { data, isLoading } = trpc.useQuery(["post.all"]);

  if (isLoading) {
    return <p>Loading...</p>;
  }

  return (
    <div>
      {data?.map((post, index: number) => {
        return <p key={index}>{post.title}</p>;
      })}
    </div>
  );
};

export default Home;

In order to preview the result, open your browser and navigate to http://localhost:3000.

Preview of the result in T-3.

We can also make use of the api folder in the pages directory.

Create a new file, /src/pages/api/posts.ts and include the following code, which will create an API endpoint on posts and fetch all the posts:

lang=typescript
import type { NextApiRequest, NextApiResponse } from "next";
import { prisma } from "../../server/db/client";

const posts = async (req: NextApiRequest, res: NextApiResponse) => {
  const posts = await prisma.post.findMany();
  res.status(200).json(posts);
};

export default posts;

Now, open your browser and navigate to http://localhost:3000/api/posts, and you should be able to retrieve the data in the JSON format:

Data in the JSON format

RedwoodJS

RedwoodJS offers a scaffold command to create a basic CRUD operation boilerplate with the dedicated route.

To do this, run yarn rw g scaffold post. The post is the name of the route – make sure you have the corresponding model with the same name in the Prisma schema file.

After that, navigate to http://localhost:8910/posts and you should see a page with create, read, update, and delete functionality.

Create, read, update, and delete functionality

Make sure to add some records and then view the first entry separately. You should be taken to http://localhost:8910/posts/1.

Viewing the first entry separately.

To understand how the backend works, we will take a closer look at how the data was fetched from the database.

First, by running the scaffold command in the beginning, a new file web/src/components/PostCell/PostCell.tsx was created that uses GraphQL to fetch the data:

lang=typescript
import type { FindPostById } from 'types/graphql'

import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web'

import Post from 'src/components/Post/Post'

export const QUERY = gql`
  query FindPostById($id: Int!) {
    post: post(id: $id) {
      id
      title
    }
  }
`

export const Loading = () => <div>Loading...</div>

export const Empty = () => <div>Post not found</div>

export const Failure = ({ error }: CellFailureProps) => (
  <div className="rw-cell-error">{error?.message}</div>
)

export const Success = ({ post }: CellSuccessProps<FindPostById>) => {
  return <Post post={post} />
}

Then the component was imported in the web/src/pages/post/PostPage/PostPage.tsx and the specific post ID from the URL got passed to the GraphQL as a prop to query the particular post:

lang=typescript
import PostCell from 'src/components/Post/PostCell'

type PostPageProps = {
  id: number
}

const PostPage = ({ id }: PostPageProps) => {
  return <PostCell id={id} />
}

export default PostPage

To test it out, try to switch between http://localhost:8910/posts/1 to http://localhost:8910/posts/2 and notice the changes.

Switching between entries test.

Conclusion

Create-t3-app is built on top of Next.js, meaning the developers get a heavily optimized environment to work with. By setting TypeScript as a requirement, create-t3-app also makes sure it will be easier to detect errors in the app. In Redwood, the typed syntax is optional, by comparison.

Both are easy to set up, though create-t3-app offers more flexibility to configure what technologies the user wants to include through the setup wizard. In comparison, in RedwoodJS, the user is required to work with GraphQL, and Storybook is already integrated.

If you are a fan of scaffolding, RedwoodJS could help to speed up the development process when there are lots of pages, layouts, components, and routes to create. It allows users to create basic CRUD functionality quickly.

Overall, I would recommend crete-t3-app for those that are strong advocates of TypeScript, love to work with Next.js, and want more flexibility.

For those seeking optional Vanilla JS support, prefer to work with GraphQL, and need quick scaffolding, RedwoodJS could be a good fit for your projects.

The post create-t3-app vs. RedwoodJS: Comparing full-stack React frameworks appeared first on LogRocket Blog.



from LogRocket Blog https://ift.tt/06THQV8
Gain $200 in a week
via Read more

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment

Search This Blog

To Top