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. |
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…
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 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.
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 inapp/routes/login.tsx
. -
the
/article/{articleSlug}
page is rendered using the code inapp/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 inapp/routes/__feed.tsx
(layout) andapp/routes/_feed/index.tsx
(content) -
the
/feed
page is rendered using the code inapp/routes/__feed.tsx
(layout) andapp/routes/__feed/feed.tsx
(content)
There’s also the app/root.tsx
which contains the common layout for all pages.
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 inapp/routes/login.tsx
is called. -
for the
/feed
page, the loaders inapp/routes/__feed.tsx
andapp/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.
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.
-
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. -
The app is available on http://localhost:3000.