Whereas not as nicely often called a number of the bigger JavaScript frameworks, Remix has earned a fame as one which stands out. A few of the good concepts first launched by Remix, which went open supply in 2021, have been absorbed into different frameworks, as nicely.
On the highest stage, Remix is a full-stack JavaScript framework within the fashion of Subsequent.js: it helps server-side rendering (SSR) of a full-stack, reactive JavaScript software. Past that similarity, Remix takes a distinct method from Subsequent in a number of methods that we’ll discover on this article.
Not simply React
Maybe essentially the most vital departure from Subsequent.js is that Remix is designed to summary its front-end implementation. In different phrases, it’s decoupled from React. Though Remix with React is the usual method at present, it’s doable to make use of totally different front-end frameworks like Svelte and Vue.
Remix seems to be the primary JavaScript framework that makes an attempt to summary the Reactive entrance finish. This method—of creating the front-end framework a pluggable piece of structure inside a bigger software framework—might develop into extra mainstream sooner or later. (JHipster is analogous in that it abstracts the JavaScript entrance finish whereas utilizing a Java again finish.)
Co-located server and shopper code
Remix makes it straightforward to co-locate the code that renders the entrance finish alongside the code that gives its information. As you’ll see, Remix features a <Type>
part, which is sort of a <type>
aspect however with superpowers for interacting with server-side logic. That makes it straightforward to encapsulate your complete information CRUD cycle throughout the similar file.
Constructing on net requirements
If you happen to have a look at Remix’s philosophy, one in all its fundamental tenets is to construct upon present net requirements like HTTP and HTML and increase them with a layer of JavaScript that doesn’t obscure the underlying applied sciences. Evolving in shut cooperation with net requirements is a good suggestion as a result of they do a remarkably good job of staying present with the altering growth panorama. Fashionable net requirements are additionally impressively strong and succesful.
An excellent instance of Remix counting on requirements whereas additionally increasing on them is its use of the Fetch API. The Fetch API is a part of fashionable browsers and has develop into the usual mechanism for issuing community requests. It has largely obviated the necessity to depend on third-party libraries for communication within the browser (it absorbed many of the good concepts from these libraries). Remix makes use of the Fetch API within the browser. It then goes a step additional by implementing an HTTP shopper that makes use of the Fetch API on the server. The web result’s builders can use the identical acquainted API throughout the stack.
One other fascinating method Remix leverages requirements is to make use of <hyperlink rel="prefetch">
. Utilizing the <hyperlink rel="prefetch">
parts lets Remix preload pages when the hyperlink to them is seen, even when the web page itself is dynamic. Subsequent’s <hyperlink>
part can solely prefetch statically generated pages.
Progressive enhancement and varieties
Progressive enhancement is the concept that JavaScript must be a pleasant addition to an software however not a vital aspect. If the JavaScript is just not obtainable for some purpose (which is extra frequent than many individuals notice) the web site ought to nonetheless perform. A technique that Remix embraces that concept is by accepting and incorporating varieties and type information into the full-stack association, whereas implementing a write API on the again finish. If JavaScript is just not obtainable, the varieties will nonetheless work within the old-school method: simply submit and reload the web page.
Limiting community payloads
Slicing down on the quantity of knowledge—JavaScript, JSON, you title it—going over the wire is a giant space of analysis and growth within the JavaScript neighborhood. Remix has some concepts right here, particularly with respect to limiting the information and JavaScript that’s despatched.
For instance, Remix can do issues like load endpoints and filter their information units on the server and bundle the consumable JSON together with the UI, as an alternative of downloading and processing the entire set on the shopper. That is achieved by defining a loader()
perform alongside the React part that wants the information. The loader perform runs on the again finish, which reduces each the information and the UI scaffolding that should be despatched and rendered or re-rendered.
Different frameworks like Subsequent and SvelteKit have analogous options. Remix’s use of the loader perform brings it in keeping with present concepts about methods to handle information loading throughout the stack.
Remix and the BFF sample
Remix helps the Backend For Your Frontend (BFF) sample, which lets you use the front-end and its API consumption code with any suitable again finish, not simply the JavaScript one which comes with Remix. Remix’s embracing of the BFF sample acknowledges that architectures are complicated. Utilizing a again finish server to orchestrate the varied providers that go into making an software work is commonly the easiest way to go.
Fingers-on with Remix
I’ve described a few of Remix’s most compelling options, together with areas the place it’s a mannequin for brand new concepts and prospects for JavaScript growth. Now, let’s create a easy software and get a way for the way Remix does its factor.
In a command immediate, use npx
to run the Remix software creator proven in Itemizing 1. You’ll be able to fill your software utilizing the identical enter seen right here.
Itemizing 1. Create a brand new Remix App
$ npx create-remix@newest
? The place would you prefer to create your app? ./my-remix-app
? What sort of app do you wish to create? A pre-configured stack prepared for manufacturing
? Which Stack would you like? (Be taught extra about these stacks: 'https://remix.run/stacks') Indie
? TypeScript or JavaScript? JavaScript
? Would you like me to run `npm set up`? Sure
⠙ Migrating template to JavaScript…Processing 10 information...
Preconfigured stacks
It’s value mentioning the idea of stacks, which you’ll see in my choice of the “Indie” stack in Itemizing 1. Stacks are preconfigured know-how stacks with totally different deployment profiles. The Indie stack we’re utilizing is a well-recognized Node plus SQLite (with Prisma) again finish. Additionally, stacks are usually not hard-and-fast decisions; they’re only a pre-configuration of changeable choices—you may migrate the Indie stack to make use of an edge deployment like Vercel, for instance. See the Remix documentation for extra about stacks.
Now we are able to run the appliance by coming into: npm run dev
. As soon as the dev server spins up, we are able to go to the appliance at localhost:3000. It’s best to see the touchdown web page proven in Determine 1.
Remix has created a easy sign-up/log-in stream. When you create a dummy consumer and log in, you may click on the “View Notes” hyperlink to entry a traditional TODO app.
If you happen to have a look at the listing created on disk, you’ll see an /app
listing; that is the place the majority of the code lives. Alongside /app
are just a few different directories: /prisma
holds the mappings for the ORM framework; /cypress
accommodates the testing config; /public
has the general public belongings like favicon
; /construct
accommodates the manufacturing construct output.
Wanting contained in the /app
listing, you’ll see a number of utility information utilized by the framework and a handful of directories:
/fashions
accommodates the JavaScript information fashions for Prisma./routes
accommodates the route definitions for the appliance./kinds
is the place you will see that the app kinds (by default, Remix makes use of Tailwind).
Of those, the /routes
file is an important, because it defines each the obtainable routes and the code that implements them. That is analogous to Subsequent.js’s /app
or /pages
listing, the place the listing construction fashions the URL routes.
For instance, the principle web page we see in Determine 1 is rendered by the /app/routes/index.jsx
file. If you happen to have a look at the contents, it’s normal React with solely a contact of Remix-specific code within the type of the <Hyperlink>
part used for routing between the Remix pages.
If you happen to look in /notes
you’ll see a file like /notes/'$noteId.jsx'
. That’s the Remix conference for dealing with URL parameters, the $nodeId
token will probably be changed with what seems within the URL the consumer is accessing and made obtainable to the web page in a particular params
object as params.nodeId
(params
is out there to the server-side loader() perform)
).
If you happen to have a look at the /app/routes/notes/index.jsx
file, you may get a way of how the appliance handles shopper/server information interactions, as proven in Itemizing 2.
Itemizing 2. notes/index.jsx
import { json, redirect } from "@remix-run/node";
import { Type, useActionData } from "@remix-run/react";
import * as React from "react";
import { createNote } from "~/fashions/word.server";
import { requireUserId } from "~/session.server";
export async perform motion({ request }) {
const userId = await requireUserId(request);
const formData = await request.formData();
const title = formData.get("title");
const physique = formData.get("physique");
const word = await createNote({ title, physique, userId });
return redirect(`/notes/${word.id}`);
}
export default perform NewNotePage() {
const actionData = useActionData();
const titleRef = React.useRef(null);
const bodyRef = React.useRef(null);
React.useEffect(() => {
if (actionData?.errors?.title) {
titleRef.present?.focus();
} else if (actionData?.errors?.physique) {
bodyRef.present?.focus();
}
}, [actionData]);
return (
<Type
methodology="submit"
fashion={{
show: "flex", flexDirection: "column", hole: 8, width: "100%" }}>
<div>
<label className="flex w-full flex-col gap-1">
<span>Title: </span>
<enter ref={titleRef} title="title" className="flex-1 rounded-md border-2 border-blue-500 px-3 text-lg leading-loose" aria-invalid={actionData?.errors?.title ? true : undefined} aria-errormessage={ actionData?.errors?.title ? "title-error" : undefined } />
</label>
{actionData?.errors?.title && (
<div className="pt-1 text-red-700" id="title-error">
{actionData.errors.title}
</div>
)}
</div>
<div>
<label className="flex w-full flex-col gap-1">
<span>Physique: </span>
<textarea ref={bodyRef} title="physique" rows={8} className="w-full flex-1 rounded-md border-2 border-blue-500 py-2 px-3 text-lg leading-6" aria-invalid={actionData?.errors?.physique ? true : undefined} aria-errormessage={ actionData?.errors?.physique ? "body-error" : undefined }8 />
</label>
{actionData?.errors?.physique && (
<div className="pt-1 text-red-700" id="body-error">
{actionData.errors.physique}
</div>
)}
</div>
<div className="text-right">
<button sort="submit" className="rounded bg-blue-500 py-2 px-4 text-white hover:bg-blue-600 focus:bg-blue-400">Save</button>
</div>
</Type>
);
}
Itemizing 2 is a typical purposeful React part named NewNotePage. It defines some JavaScript features and returns the JSX markup for the template. (Word that I’ve eliminated extraneous code like validation to simplify issues.)
Discover that the template makes use of the Remix-specific <Type>
part, which works carefully with the particular Remix motion()
perform. This perform is definitely a server-side perform. It takes a request object, which fashions the request data despatched by the <Type>
part. Discover that Remix makes use of a Request object that mimics the browser API even within the server features.
The motion()
methodology makes use of the data from the Request object to make a name to the createNote()
perform that’s imported from "~/fashions/word.server"
, the place Remix has generated the shared-back-end Prisma code. That is the final sample of accessing the shared server code from the server features outlined within the routes. Discover that the useEffect
hook is harnessed to set the physique and title of the doc primarily based on the Remix useActionData()
perform.
Conclusion
Though you have had only a fast tour of Remix’s capabilities, I hope the instance offers you a way of the flavour Remix brings to reactive full-stack growth. Remix can do much more than we have lined right here. It’s positively a framework to observe for future developments in JavaScript.
See the Remix documentation to study extra about Remix’s philosophy. Additionally see A Look At Remix And The Variations With Subsequent.js for extra about Remix compared to Subsequent.js.
Copyright © 2023 IDG Communications, Inc.