Skip to content

BenoitAverty/realworld-remix.run

Repository files navigation

RealWorld Example App

remix.run codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld spec and API.

This codebase was created to demonstrate a fully fledged fullstack application built with remix.run including CRUD operations, authentication, routing, pagination, and more.

We’ve gone to great lengths to adhere to the remix.run philosophy & best practices.

For more information on how to this works with other frontends/backends, head over to the RealWorld repo.

Note
All the features from the Realworld spec are not implemented yet. Head to the issues to see what’s missing.

Philosophy

Warning
I’m not a Remix developer. This section describes what I’ve understood and liked about the Remix way of doing things. This may not reflect the view of the developers.

When I discovered about remix I was immediately very interested in the choices they have made. The Remix philosophy can be summarised by "Use the platform". The framework encourages the developer to adopt a programming model that’s very consistent with how the browsers and other internet components (like CDNs) work.

  • Using html forms instead of useState / useEffect (but with a better UX using JS)

  • Modeling user interactions with the app as navigations and form submits (but without reloading the entire page thanks to modern client-side transitions)

  • Loading data intelligently, enabling proper cache control

  • Letting you, the dev, control the entry point of the app and the entire dom (enabling better customization and edge-case scenarios as other frameworks like next.js)

  • Letting you, the dev, use advanced browser features like preloading of assets instead of abstracting it away.

  • Ensuring the browser and CDN get sent proper status codes when data is not available

Head to https://docs.remix.run/ to learn more.

I’ve tried, in this app, to embrace that philosophy.

To help me do that, I have decided that this application should function with javascript completely disabled. This does not mean it’s a good idea for a real app, or that javascript is bad. The fact that it’s been relatively easy to do so is a nice way to show that the programming model of a Remix app is consistent with the way internet works.

With javascript disabled, the app should function perfectly fine, without any missing feature. With javascript enabled, you get smoother transitions on page changed (client side navigation), infinite scrolling on the article page, better form UX, automatic refresh of the feed…​

How it works

Deployed on Fly.io with a Dockerfile

Remix can be deployed pretty much anywhere, including function as a service providers like Vercel or AWS Lambda. In this repo, I chose the simplest deployment option, which is to use the remix server. It can run anywhere a node application can run, including any service that can deploy a docker container. Most of the code would be the same for any Remix app.

The Remix app

The Remix app is in the app folder. When you run npm run build (or npm run dev), the server bundle ends up in build/, and the browser bundle ends up in public/build.

This section is not meant to replace Remix documentation, but only to help navigating the code in the repo. For more information, head to remix.run documentation and consider subscribing to their newsletter.

Routing

Much like Next.js, Remix does filesystem based routing. The routes of the application correspond to the files in app/routes. For example :

  • the /login page is rendered using the code in app/routes/login.tsx.

  • the /article/{articleSlug} page is rendered using the code in app/routes/article.$articleSlug.tsx.

Remix also has "nested routes". They are used by placing subfolders inside the routes folder.

  • the / page is rendered using the code in app/routes/__feed.tsx (layout) and app/routes/_feed/index.tsx (content)

  • the /feed page is rendered using the code in app/routes/__feed.tsx (layout) and app/routes/__feed/feed.tsx (content)

There’s also the app/root.tsx which contains the common layout for all pages.

Data

Remix is a Server Side Rendering framework. To load the data needed to render pages, Remix uses "Loaders" that are defined in the route files, alongside the page components.

When a page is rendered on the server, Remix calls all the loaders of the matched routes

  • for the /login page, the loader in app/routes/login.tsx is called.

  • for the /feed page, the loaders in app/routes/__feed.tsx and app/routes/__feed/feed.tsx are called.

There’s also the loader in app/root.tsx that’s called for all pages.

These loaders are meant to be the single source of truth for the data needed to render a page. To enable this, Remix calls the same loaders when doing client-side navigation to a page. This means there is no need to fetch the data ourselves in the code if it’s already fetched in the loader.

React

Remix is a React framework, and this app is a React app above all else. I’ve done my best to make this app a good example of a well-structured React app.

Components live in the app/components folder. app/lib contain other JS/TS modules. For both these folders, there are subfolders organized roughly by feature.

Local development

Start the development server

  1. Install the dependencies and start the incremental build of the remix app (npm install; npm run dev). You need a Remix token to do this step.

  2. The app is available on http://localhost:3000.

Tests

  • Run the unit tests with npm run test:unit

Contributing

feel free to open a PR for any missing feature or improvement. Keep in mind I’d like the app to function with javascript completely disabled in the browser.