Welcome to Remix
Focused on web standards and modern web app UX, you’re simply going to build better websites
Remix is a full stack web framework that lets you focus on the user interface and work back through web standards to deliver a fast, slick, and resilient user experience. People are gonna love using your stuff.
export async function loader({ request }) {
return getProjects();
}
export async function action({ request }) {
const form = await request.formData();
return createProject({
title: form.get("title"),
});
}
export default function Projects() {
const projects = useLoaderData();
const { state } = useNavigation();
const busy = state === "submitting";
return (
<div>
{projects.map((project) => (
<Link to={project.slug}>
{project.title}
</Link>
))}
<Form method="post">
<input name="title" />
<button type="submit" disabled={busy}>
{busy
? "Creating..."
: "Create New Project"}
</button>
</Form>
</div>
);
}
Testimonials
![](/img/jenna.jpg)
I've been waiting for something to encourage progressive enhancement in the React space *forever* and Remix truly is so much more. Proving we don't need to sacrifice React or choose SSG for a lightning fast, accessible UI, and the DX makes it all too easy 🤤
![](/img/jkup.jpg)
holy 💩 Remix is good
![](/img/aweary.jpg)
I just rewrote my first Remix app on top of Cloudflare Workers and Supabase and it’s so damn good
![](/img/tiger.jpg)
My mind is still blown away with Remix! So easy and elegant 😩. I love how it also focuses on Accessibility (Progressive Enhancement...) 🤯, A few days ago I was like wazzup with remix, we got Next.js and Svelte 😴 ... and now I'm fired up like crazy 😂. This is so good 🤤
![](/img/sergio.jpg)
What’s really cool with Remix loaders is that you can do most of your data transformation and calculations there, like check if a list is empty, limit the number of records, only send specific attributes, so your React component just receives the data and renders it, no logic needed
![](/img/elrick.jpg)
Remix is going to put developers on the Hot Path to build accessible, scaleable, and performant apps, that have stellar user experiences and amazing developer ergonomics. It's not only going to be a win for developers, but also a big win for the end-users!
![](/img/tom.jpg)
In my opinion @remix_run will be game changer for corporate teams hesitant to adopt full stack JavaScript. The core concepts are so intuitive you can pick it up in a day, and it will even integrate into your existing stack.
![](/img/sophia.jpg)
I love what @mjackson and @ryanflorence are doing with Remix! Deploying to AWS Lambda in under 30 seconds 🤯
![](/img/jens.jpg)
Building with @remix_run has been awesome so far. Having used Next.js for applications for years, the nested layouts are a wonderful feature. I also haven't learned this much about the web in years.
![](/img/cammchenry.jpg)
I love using @remix_run for my website. Remix has improved my productivity as a front-end developer by empowering me to seamlessly switch between front-end and back-end code.
![](/img/airuyi.jpg)
If you're doing #webdevelopment you should check out Remix 🔥 It's a new (old) paradigm for web dev, which simplifies our code, especially state management😅, speeds up our page loads, and gives us a mental model and framework we can rely on to create our best work
![](/wave.png)
![](/loading.gif)
While you were waiting for your static site to build, distributed web infrastructure got really good. Break through the static.
Remix is a seamless server and browser runtime that provides snappy page loads and instant transitions by leveraging distributed systems and native browser features instead of clunky static builds. Built on the Web Fetch API (instead of Node) it can run anywhere. It already runs natively on Cloudflare Workers, and of course supports serverless and traditional Node.js environments, so you can come as you are.
Page speed is only one aspect of our true goal though. We're after better user experiences. As you’ve pushed the boundaries of the web, your tools haven’t caught up to your appetite. Remix is ready to serve you from the initial request to the fanciest UX your designers can think up. Check it out 👀
Remix has a cheat code:
Nested Routes.
Websites usually have levels of navigation that control child views.
Not only are these components pretty much always coupled to URL segments...
...they’re also the semantic boundary of data loading and code splitting.
What about loading states?
Most web apps fetch inside of components, creating request waterfalls, slower loads, and jank.
Remix loads data in parallel on the server and sends a fully formed HTML document. Way faster, jank free.
Pre-fetching Everything
Remix can prefetch everything in parallel before the user clicks a link.
Public Data. User Data. Modules. Heck, even CSS.
Zero loading states. Zero skeleton UI. Zero jank.
Alright, you caught us, they’re just prefetch link tags, #useThePlatform
Data loading
You ever notice most of the code in your app is for changing data?
Imagine if React only had props and no way to set state. What’s the point? If a web framework helps you load data but doesn’t help you update it, what’s the point? Remix doesn’t drop you off at the <form onSubmit>
cliff. (What the heck does event.preventDefault
do anyway?)
It’s so simple it’s kind of silly. Just make a form...
...and an action on a route module. It looks like traditional HTML forms but enables fully dynamic web experiences you're after.
Remix runs the action server side, revalidates data client side, and even handles race conditions from resubmissions.
Get fancy with transition hooks and make some pending UI. Remix handles all the state, you simply ask for it.
Or get jiggy with some optimistic UI. Remix provides the data being sent to the server so you can skip the busy spinners for mutations, too.
HTML forms for mutations. Who knew?
export default function NewInvoice() {
return (
<Form method="post">
<input type="text" name="company" />
<input type="text" name="amount" />
<button type="submit">Create</button>
</Form>
);
}
export async function action({ request }) {
const body = await request.formData();
const invoice = await createInvoice(body);
return redirect(`/invoices/${invoice.id}`);
}
Error Handling
Route Error Boundaries keep the happy path happy.
Each route module can export an error boundary next to the default route component.
If an error is thrown, client or server side, users see the boundary instead of the default component.
Routes w/o trouble render normally, so users have more options than slamming refresh.
If a route has no boundary, errors bubble up. Just put one at the top and chill out about errors in code review, yeah?