# Remix Vs Next.js

Selecting between Remix or Next.js is an endless debate among developers. Before diving into the comparison, let’s take a quick look at the below topics:

 1. What is SSR?

 2. Why SSR?

 3. Next.js

 4. Remix

## 1. What is SSR?

SSR (Server-side rendering) means using a server to create HTML from JS modules in response to a URL request. Whereas the client-side rendering uses the browser to create HTML using the DOM.

## 2. Why SSR?
SSR helps with the following:

- SEO performance

- Quick initial page access

- Supports optimal users with a slow internet connection

- Provide a better SMO (Social Media Optimisation)

## 3. Next.js

[`Next.js`](https://nextjs.org/docs/getting-started) is an open-source framework designed to work with React, created by Vercel.

### Why Next.js?
Next.js helps with the following:

- Automatic code splitting for faster page loads
- Folder-based routing
- Pre Rendering, Static Generation (SSG), and Server Side Rendering (SSR)
- API Routes.
- Support for CSS in JS library, Built-in CSS, and SASS support.

## 4. Remix

[`Remix`](https://remix.run/docs/en/v1/tutorials/blog) is an open-source framework designed to work with React.

### Why Remix?
Remix helps with the following:

- Remix is faster than Next.js in serving both static and dynamic content
- Remix has a component-based error boundary to handle errors and interruptions
- Remix supports Traditional forms
- Remix handles transition, it can handle all the loading states and what to show while loading
- Remix Supports react-router v6

Cool 😎  right? Let’s dive into the comparison!

## Routing

### Next.js

It has its own router using the file system. All the folders you name into the pages directory (individual parent under Root) become separate routes and the file inside the folder will be their child and so on

 →`pages/index.tsx`

`/product` → `pages/product/index.tsx` else `pages/product.tsx`

`/product/:id` → `pages/product/[id].tsx`

### Remix

Similar to Next.js, it follows the same folder-based routing structure. All the files inside the routes directory become separate routes here and so on. But it uses `react-router v6` as the router for the page routing.

In the latest version of the react-router, there is this new feature `<Outlet/>` which comes in handy in the nested routes. Using an `Outlet` from React Router Dom, you can build out a hierarchy of nested routes.

> The advantage Remix has over the Next.js router is that it enables nested routing with nested layouts. While in Next JS,  you need to add nested layouts you need to render the layout on each page manually and add it from the `_app` file with custom logic.

→`app/routes/index.tsx`

`/product` → `app/routes/product/index.tsx` else `app/routes/product.tsx` or you can have both and by making `product.tsx` as parent wrapping layout component.

For example,

```jsx
app/routes/product.tsx
import { Outlet } from "remix";

export default function ProductsRoute() {
  return (
    <div>
      <h1>Products Wrapper</h1>
      <main>
        <Outlet />
      </main>
    </div>
  );
}
```

The following `ProductIndexRoute` comes in the place of outlet in `product.tsx`:

```jsx
app/routes/product/index.tsx
export default function ProductIndexRoute() {
  return (
    <div>
      <p>Displaying Product:</p>
      <p>
	      Apple
      </p>
    </div>
  );
}
```

![pw.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1659942615665/zA7MWIUcR.png align="left")

You can even have a file like an adopted child `app/routes/product.help.tsx`.

It will not inherit the parent's behavior, even though it’s under the product parent's routes. It doesn’t have a parent wrapper like in the above image.


![ph.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1659942625809/CfzX2jE3b.png align="left")

`/product/:id` → `app/routes/product/$id.tsx`

Another folder inside `routes/pages`. In Remix, files that are not exporting a component is considered API file (Resource Routes).

Now, the files under `pages/API` is treated as API files based on a file name concerning the same-named `.tsx` files

## Styling

### Next.js

Next.js supports moreover all `CSS Modules` out of the box, any other framework or CSS in the JS library can be added with some configuration or plugin.

### Remix

In Remix, all the styles must be loaded with `Link Function`. By using `Link` you can load the `CSS files` which are required for the specific files to avoid CSS conflict with others. 

Kind of `File Scope` based CSS:

```jsx
import type { LinksFunction } from "remix";
import stylesUrl from "../styles/index.css";

export const links: LinksFunction = () => {
  return [{ rel: "stylesheet", href: stylesUrl }];
};

export default function IndexRoute() {
  return <div>Hello Index Route</div>;
}
```

You can write separate media query CSS for all the device sizes and can link with desired `.tsx/.jsx` files using Link Function:

- `app/styles/global.css`

- `app/styles/global-large.css`

- `app/styles/global-medium.css`

For using CSS libraries, one needs a compiler plugin. It will not be usable since it's not possible to change the compiler configuration.

You can find the examples below:

[`Remix | Jokes App`](https://remix.run/docs/en/v1/tutorials/jokes#styling)

## Data Handling

Both offer several ways to load data. 

### Next.js
Next.js supports `CSR`, `SSR`, and `SSG` to get data. 
It has functions like: 

- `getServerSideProps`,
- `getStaticProps`,
- `getInitialProps`,
- `getStaticPaths`.

```jsx
export const getServerSideProps = async ({ params }) => {
   const {id} = params
   const res = await fetch(
    `https://anyapi.com/products/${id}`
  );
  const data = await res.json();
   return {props: {id, data}}
};

export default function Home({id, data}) {
  return (
    <div>
       <span>The params is: {id}</span>
      <span>The data is: {data}</span>
    </div>
  );
}
```

### Remix

Remix supports only `SSR` and `CSR`.
It has functions like:
- `loader`,
- `useFetcher`.

```jsx
import { useLoaderData } from "remix";

export let loader = async ({ params }) => {
   const {id} = params
   const res = await fetch(
    `https://anyapi.com/products/${id}`
  );
  const data = await res.json();
   return {id,data}
};

export default function Home() {
  let {id, data} = useLoaderData();
  return (
    <div>
      <span>The params is: {id}</span>
      <span>The data is: {data}</span>
    </div>
  );
}
```

## API Handling

### Next.js

Next.js does not have any inbuilt functions to handle cookies and sessions.

### Remix

Remix comes with cookies and session handling functionality and it gives you full control over requests and responses of the API.

#### Cookies

```jsx
import { createCookie } from "remix";

export const userPrefs = createCookie("user-prefs", {
  maxAge: 604_800 // one week
});
```

#### Sessions

```jsx
import { createCookieSessionStorage } from "remix";

const { getSession, commitSession, destroySession } =
  createCookieSessionStorage({
    // a Cookie from `createCookie` or the CookieOptions to create one
    cookie: {
      name: "__session",

      // all of these are optional
      domain: "remix.run",
      expires: new Date(Date.now() + 60),
      httpOnly: true,
      maxAge: 60,
      path: "/",
      sameSite: "lax",
      secrets: ["s3cret1"],
      secure: true
    }
  });

export { getSession, commitSession, destroySession };
```

## Error Handling

`Next.js` lets you have separate screens for `error 404` and `500` to render.

`Remix` uses error boundaries to handle routes inside the files. If there's is an error in the child component it won't affect the parent.

## Handling JavaScript

`Next.js` doesn’t have proper support for disabling runtime JS on the desired page.

`Remix` allows users to enable or disable runtime JavaScript in their routes. It is helpful to disable JS on static pages and enable it required pages.

## Reloading

`Next.js` has a react fast refresh to reload the screen without losing the state.

`Remix` has Live reloading which needs to be enabled.

<aside>
📢 **Remix has other features like**

</aside>

### 1. Form handling architecture

Instead of creating a form tab adding an `onSubmit` function and calling the API services, Remix uses HTML `form` element.  It comes with a notion of a server by default. It also includes a PHP-style, server-side `GET` and `POST` handle. In this sense, the Remix form will function without the need for any JavaScript functions. A user can even have turn off the JS and they can still be able to use the website.

In Next.js:

```jsx
const onSubmit=() =>{//api handle}
<form onSubmit={onSubmit}>
  <label><input name="name" type="text" /></label>
  <label><textarea name="description"></textarea></label
</form>
```

In Remix:

```jsx
<form method="get" action="/search">
  <label>Search <input name="term" type="text" /></label>
  <button type="submit">Search</button>
</form>
```

```jsx
<form method="post" action="/projects">
  <label><input name="name" type="text" /></label>
  <label><textarea name="description"></textarea></label>
  <button type="submit">Submit</button>
</form>
```

#### Reference 

[`Data Writes`](https://remix.run/docs/en/v1/guides/data-writes)

### 2. Deployment

Remix was built to support many platforms. It has a `request handler` inside an HTTP server which helps you to utilize any server. While building a Remix app, you’re asked where you want to deploy it and you'll get the following options:

- Remix App Server
- Express Server
- Netlify
- AWS Lambda
- Cloudflare Pages
- Vercel

## Remix or Next.js

`Remix` has added many improvements to support the developer experience through their new ideas, abstractions, and user experience by shipping minimal JavaScript. It is a new framework in the web development world. It has many more features to come and has large community support too.

It has `better rendering speed` on both static and dynamic pages in comparison with Next.js.

The advantage Remix has over the Next.js router is that it enables nested routing with nested layouts. While in Next.js, you need to add nested layouts. You need to render the layout on each page manually and add it from the `_app` file with custom logic.

Remix allows having a file like an `adopted child app/routes/filename.help.tsx`  in relation to `app/routes/filename.tsx`. It will not inherit the parent's behavior, even if it is under a parent route.

`Next JS` has been in development significantly longer, has a bigger community of users, and has more resources dedicated to its development from the team at `Vercel`. It is being used in a large number of production apps.

<aside>
📢 **Comparison of Rendering an e-commerce website**

</aside>

> **Let's take look at what Remix thinks about Next JS**
> 

- Remix is as fast or faster than Next.js at serving static content
- Remix is faster than Next.js at serving dynamic content
- Remix enables fast user experiences even on slow networks
- Remix automatically handles errors, interruptions, and race conditions, Next.js doesn't
- Next.js encourages client-side JavaScript for serving dynamic content, Remix doesn't
- Next.js requires client-side JavaScript for data mutations, Remix doesn't
- Next.js build times increase linearly with your data, Remix build times are nearly instant and decoupled from data
- Next.js requires you to change your application architecture and sacrifice performance when your data scales
- We think Remix's abstractions lead to better application code

Other References: [`Remix vs Next.js`](https://remix.run/blog/remix-vs-next)

### Major Differences

| Functionalities | Remix | Next |
| --- | --- | --- |
| Form handling | ✅ | ❌ |
| React Router V6 | ✅ | ❌ |
| SSG | ❌ | ✅ |
| Cookie and Session Handling | ✅ | ❌ |
| Default Erorr Handling | ✅ | ❌ |
| Conditional Js Bundling for specific file | ✅ | ❌ |
|  |  |  |


![comp.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1659942640255/3kxj2L96H.gif align="left")

