• Stars
    star
    141
  • Rank 259,971 (Top 6 %)
  • Language
    TypeScript
  • Created 12 months ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Federated RSC Reference Architecture

This repository contains the reference architecture for a federated RSC organization architecture. The architecture is based on a few principles:

  • HTTP is the API for the "server" layer.
  • The "server" layer exposes assets for the "client" layer to consume.
  • If you are a "client" and know how to load the assets, you can consume any "server" payload.
  • "Server" responses should be composable with "client" components and other "server" responses.
  • "Client references" are global.
  • How to load a "client reference" is a "client" concern.

Let's get on the same page

What is RSC?

RSC is a response format that, among other things, encodes a JSX tree. In that JSX tree there can be "client references". These "references" are boundaries that encode properties for a component, and an ID for "how to load" the component. In this architecture, client reference IDs are global to the application and refer to an export from an exposed module of a remote container.

..."refer to an export from an exposed module of a remote container", hahahah I know.... I'll explain.

What is a container?

A container is a collection of javascript modules. Imagine an object with keys that point to dynamic imports:

// I'm kinda a remote container...
export const moduleA = () => import("./moduleA.js");
// I'm another exposed module
export const moduleB = () => import("./moduleB.js");
// ...etc...

Beyond this, it's a a collection of dynamic imports that can be provided already loaded versions of the dependencies they need to run. To me, this is the most important part of module federation. It's globals with guarantees based on semantic versioning at the minimum, and whatever you want it to be at it's best.

The above over simplificated example of a container would fail if a library like React came into the picture that needed to have a single copy of itsself on the page.

If we could express the "sharing" of module federation as a javascript syntax, I'd probably pick import attributes:

// http://other-domain.com/moduleA.js
import * as React from "./react.js";

export function Component() {
  return React.createElement("h1", null, "Hello World");
}
// http://other-domain.com/container.js

import * as React from "./react.js";

export const moduleA = () =>
  import("./moduleA.js", {
    with: { shared: { react: React } },
  });
export const moduleB = () =>
  import("./moduleB.js", {
    with: { shared: { react: React } },
  });

The with: { shared: { react: React } } above means "when moduleB.js imports "react", use this instead.

And if we expand this into a runtime syntax for consuming a module from a container from another domain with it's own copy of React, it might look like this:

import * as React from "./react.js";

const { Component } = await import("http://other-domain.com/container.js", {
  with: {
    shared: { react: React },
    exposed: "moduleA",
  },
});

Module federation explained in a nutshell, and the type of runtime syntax I'd love to see in JS runtimes. You can already cross pollute globals, and that's mainly how federaiton is accomplised in the browser for legacy support, so why not make it explicit and predictable for the use-cases where it makes sense in modern browsers and runtimes?

What is a "Server"?

A "server" (unquoted) from here on out will refer to an HTTP server that responds with a RSC payload. The RSC payload is essentially enahnced JSON with support for JSX trees and "client references".

What is a "Client"?

A "client" consumes a server response and renders it for display to the user. There are two types of clients we will be talking about; an "ssr client" and a "browser client". These may be refered to as "the browser", "the ssr server", "the ssr client", "the browser client", etc.

Note - if you are not familiar with RSC, SSR and "ssr client" / "client that run on the server" are on in the same. It's "the way you server render a react app before RSC".

What is a "Client Reference"?

A "client reference" is a boundary in a JSX tree that encodes a "client reference ID" and "client reference properties". The "client reference ID" is a string that is globally unique for that specific component. The "client reference properties" are a set of properties that are passed to the "client reference ID" when it is loaded and rendered in a client, these properties are encoded in the RSC payload.

The Architecture

The Server Layer

The server layer is a collection of HTTP endpoints that respond with the RSC format. The RSC format encodes "client references", and also exposes the references for clients to load.

This is the layer in which you would acccess your data sources and render any markup that is not dynamic. This is also the layer in which you would expose your "client references" for clients to consume by simply by importing from a module marked use client.

The Client Layer

React as today but instead of having a single entry point that looks like this:

import * as React from "./react.js";
import * as ReactDOM from "./react-dom.js";

// A component that dynamically imports components to render the data based on the URL
import { App } from "./entry.browser.js";

ReactDOM.render(
  React.createElement(App, {
    // Get the data dependencies from the server
    data: fetch(window.location.url, {
      headers: {
        Accept: "application/json",
      },
    }),
    location: window.location.url,
  }),
  document.getElementById("root")
);

You have an entrypoint that, in concept, is more like this:

import * as React from "./react.js";
import * as ReactDOM from "./react-dom.js";

// A dynamically generated entrypoint based on the URL that considers any data dependencies
const { App } = await import(window.location.url, {
  with: {
    shared: { react: React },
    exposed: "entry.browser.js",
  },
});

ReactDOM.render(React.createElement(App), document.getElementById("root"));

The "Client Reference" Layer

The client references (use client modules) are chunked off and given a global ID per application. For example if you had a source module in an app called "test" at app/components/MyComponents.js that had a Counter component that was refereced by a server module, you'd end up with a container equivilant to this:

//test_container.js
import * as React from "./react.js";

export const MyComponent = () =>
  import("./app/components/MyComponent.js", {
    with: {
      shared: { react: React },
    },
  });

And the ID for the bookend encoded into the RSC stream for loading this component would be: rsc/remote/client/test/MyComponents#Counter. At build, remote container modules are aliased, both module and chunk IDs to the global ID of the module. So our previous remote container reference module and chunk ID would be avaliable for load at RSC payload decode through: rsc/remote/client/test/MyComponents. Where that module is loaded from is a "client" concern and this openes up all sorts of opertunities.

Composing servers

Composing servers is dooable at both the ingress (SSR client) and data (RSC server) layers. The ingress layer is composable just by knowing how to load the remote containers for the servers you are consuming. The data layer is composable by encoding RSC payloads as properties to a "client references" and decoding the them in the client to a JSX tree.

More Repositories

1

remix-ecommerce

ABANDONED
TypeScript
494
star
2

remix-cloudflare-demo

A demo of Remix running on Cloudflare workers.
TypeScript
173
star
3

turbo-stream

A streaming data transport format that aims to support built-in features such as Promises, Dates, RegExps, Maps, Sets and more.
TypeScript
155
star
4

styled-components-ts

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress and the added benefits of TypeScript 💅
JavaScript
150
star
5

remix-shadcn

Remix + Vite + shadcn/ui starter template.
TypeScript
125
star
6

remix-bun-testing

TypeScript
105
star
7

remix-dashboard-d1

TypeScript
86
star
8

github-md

A markdown parser API for GitHub
TypeScript
77
star
9

remix-pwa

A template to get a Remix PWA up and running
TypeScript
67
star
10

remix-chat

A chat application build on top of Remix and Cloudflare.
TypeScript
57
star
11

hono-vite-rsc

A minimal RSC + Vite starting point.
TypeScript
56
star
12

remix-vitest

Simple example showing how to use Vitest in-source testing with Remix
CSS
53
star
13

remix-ssg

A CLI for building static sites with Remix
TypeScript
50
star
14

remix-cloudflare-worker-template

Remix + Cloudflare Workers + DO + Turborepo
TypeScript
50
star
15

remix-dashboard-template

A template to get you up and building a dashboard in Remix.
TypeScript
48
star
16

remix-deno-jit

This is an experimental interface for running a Remix application on Deno without a build step.
TypeScript
47
star
17

preact-rsc

**WIP** Preact implementation of react server components.
JavaScript
45
star
18

esbuild-federation-example

Demonstrates consuming modules from a webpack bundle from an esbuild bundle using https://github.com/jacob-ebey/esbuild-federation-share-scope.
JavaScript
44
star
19

esbuild-hmr

ESBuilld HMR Playground
JavaScript
43
star
20

bun-remix

Bun + Remix + HMR
TypeScript
42
star
21

remix-react-18-streaming

Remix + React 18 Streaming
TypeScript
37
star
22

remix-sentry

Example showing using Sentry with Remix
JavaScript
35
star
23

remix-sse-live-viewers

Simple example showing how to use SSE in Remix
TypeScript
35
star
24

ai-components

An AI driven chat application that is useful for prototyping layouts / components for your React application.
TypeScript
34
star
25

remix-deno

A Deno runtime for https://remix.run that doesn't require a build step
TypeScript
34
star
26

unplugin-rsc

An unplugin for framework authors to implement RSC on top of.
TypeScript
30
star
27

federated-libraries-get-started

Completed example code that accompanies https://federated-libraries.now.sh/get-started
JavaScript
29
star
28

go-graphql-boilerplate

A simple to use, deploys anywhere boilerplate to get you going in GO and GraphQL.
Go
28
star
29

oneup

Get a oneup on RSC by having everything laid out as simply as possible.
TypeScript
26
star
30

remix-d1-northwind

Northwind Traders implemented on Remix + CF Pages + D1
TypeScript
26
star
31

remix-cloudflare-stack

TypeScript
26
star
32

deno-remix

TypeScript
26
star
33

remix-cms

TypeScript
24
star
34

cf-lambda-streaming

Enable your AWS Lambda hosted applications to stream responses via Cloudflare Workers.
JavaScript
22
star
35

remix-electron-llamafile

Chat with LLMs locally utilizing llamafile as the underlying model executor.
TypeScript
21
star
36

esbuild-federation-share-scope

Enables federation share scope for interop with Webpack 5 Module Federation containers.
TypeScript
21
star
37

jbundler

wip server-component exploration on top of esbuild
JavaScript
19
star
38

enhance-remix

Playing around with Enhance SSR
JavaScript
18
star
39

remix-rsc-do-not-use

JavaScript
18
star
40

html-tagged

TypeScript
18
star
41

remix-node-cloudflare

Single codebase with some routes running in a service worker, at the edge, and others on an origin server.
TypeScript
18
star
42

webpack-federated-stats-plugin

Write out relevant federation stats to a file for further consumption.
JavaScript
17
star
43

remix-flags

Eventually* Everything you'll need for successful feature flagging
TypeScript
17
star
44

htmx-hono-store

A minimalistic storefront built with Hono and HTMX.
TypeScript
16
star
45

bun-react-router-islands

The islands pattern with on-demand compilation of assets built on top of Bun + React Router.
TypeScript
16
star
46

remix-deno-example

Example showing how to use: https://github.com/jacob-ebey/remix-deno
TypeScript
16
star
47

remix-bun

Trying out Remix on the Bun runtime
TypeScript
16
star
48

mwap

The 💰web app platform.
JavaScript
15
star
49

vite-env-api

Playing around with the alpha Vite Env API
TypeScript
15
star
50

remix-cf-pages-template-hmr

A template to try out Remix's new dev server + HMR on Cloudflare Pages
TypeScript
13
star
51

litestream-remix

TypeScript
13
star
52

remix-webpack-cli

A CLI for building https://remix.run applications with Webpack.
CSS
13
star
53

cf-image-service

A simple image transform service for use by other workers through service bindings.
TypeScript
12
star
54

micro-graphql-monorepo

A tiny, simple to use GraphQL client with SSR support.
TypeScript
12
star
55

ebey-me-remix

TypeScript
12
star
56

joe-dom

A server-first virtual DOM that supports a wire format, async components, and client references out of the box.
TypeScript
12
star
57

remix-auth-layouts-example

An example showing how to build a simple login flow utilizing actions, transitions, layout routes and more that works with and without JavaScript enabled.
TypeScript
12
star
58

remix-preact-mpa-sprinkles

Remix + Preact for SSR, Preact + Islands + On Demand Compilation for client side interactions.
TypeScript
12
star
59

snowpack-playground

A snowpack + webpack + module federation SSR playground
JavaScript
11
star
60

remix-federation

An example I spent 15 minutes putting together as a POC a while ago.
JavaScript
11
star
61

cf-vite-plugin

WIP
TypeScript
11
star
62

ssr-react-streaming-example

React SSR Streaming Example
JavaScript
11
star
63

htmx_tagged

TypeScript
10
star
64

tailwind-tagged

A way to use tailwind by writing standard CSS.
JavaScript
10
star
65

rsc-webpack-playground

RSC On Webpack + @remix-run/router
TypeScript
10
star
66

react-hook-utils

Utilities for working with react-hooks.
JavaScript
9
star
67

federated-blog

A case study in creating a blog utilizing Webpack 5 Module Federation.
JavaScript
9
star
68

remix-wasm-example

TypeScript
9
star
69

preact-webpack-prerender

POC of pre-rendering Preact applications via a webpack plugin using preact-iso.
JavaScript
9
star
70

remix-webpack-cli-example

Example using the remix-webpack-cli https://github.com/jacob-ebey/remix-webpack-cli
CSS
8
star
71

pwrc-react

JavaScript
8
star
72

ai-coder

JavaScript
8
star
73

remix-preact

Example using preact-compat with Remix
TypeScript
8
star
74

remix-css-modules

Example of using CSS modules with Remix.run
TypeScript
8
star
75

remix-htmx-hyperscript

Template to use Remix for building HTMX / Hyperscript based applications.
TypeScript
8
star
76

router-trie

@remix-run/router matching algorithm re-worked as a trie
TypeScript
8
star
77

stupid-simple-remix-deferred-demo

W3C layout of a blog to demo deferred data loading
TypeScript
8
star
78

federated-gql

An example of using Webpack 5 Module Federation to orchestrate an Apollo Federation Gateway
JavaScript
7
star
79

bun-rsc

TypeScript
7
star
80

on-demand-bundler

The start of a platform agnostic on-demand asset bundler.
TypeScript
7
star
81

webpack-module-federation-node-esm-example

This project serves as a straightforward and illustrative demonstration of how two Node.js processes can collaborate by federating modules through HTTP dynamic imports using Webpack. The main goal is to showcase how you can achieve module sharing and dynamic loading in a Node.js environment.
JavaScript
7
star
82

consume-versioned-federated-module

Example of consuming federated module hosted on npm / unpkg
JavaScript
7
star
83

typescript-fetch

TypeScript
6
star
84

remix-react-18

TypeScript
6
star
85

rsc-by-hand

RSC without a bundler to help understand the moving parts.
JavaScript
6
star
86

versioned-federated-module

Example of a federated module hosted on npm / unpkg
JavaScript
6
star
87

remix-deferred-infinite-scroll

Example of a deferred infinite scrolling list.
TypeScript
6
star
88

remix-edgedb

A simple app demoing Remix + EdgeDB
TypeScript
6
star
89

turbo-stream-react-example

An example of how to integrate turbo-stream with a SSR'd React application.
TypeScript
6
star
90

remix-hn-deferred

HN clone in Remix utilizing deferrable data
TypeScript
6
star
91

hooks-todo

A simple todo app built using react hooks.
JavaScript
6
star
92

jacob-thoughts

Maybe my new blog / portfolio site?
TypeScript
6
star
93

turbo-stream-react

TypeScript
6
star
94

remix-express-rsc

Yo
TypeScript
5
star
95

cf-pages-faunadb-stack

TypeScript
5
star
96

react-use-example

Remix + React.use() experimental example
TypeScript
5
star
97

dynamic-css-with-remix-resource-routes

Use resource routes to generate user provided CSS themes.
TypeScript
5
star
98

tiny-graphql

A tiny GraphQL suite for making your dev and user experience better than ever.
TypeScript
5
star
99

remix-chakra

Example using chakra with Remix
TypeScript
5
star
100

minimal-remix-webpack-compiler

A VERY minimal remix webpack compiler to show the touch points.
JavaScript
5
star