Remix Vs Next.js

Remix Vs Next.js

Let's Dive Deeper to Know What Differentiates These Two Trend-Setting Technologies

Featured on Hashnode

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 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 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

/productpages/product/index.tsx else pages/product.tsx

/product/:idpages/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

/productapp/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,

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:

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

pw.png

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

/product/:idapp/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:

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

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.
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.
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

import { createCookie } from "remix";

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

Sessions

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.

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:

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

In Remix:

<form method="get" action="/search">
  <label>Search <input name="term" type="text" /></label>
  <button type="submit">Search</button>
</form>
<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

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.

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

Major Differences

FunctionalitiesRemixNext
Form handling
React Router V6
SSG
Cookie and Session Handling
Default Erorr Handling
Conditional Js Bundling for specific file

comp.gif