Eric Bower
·
26 Aug 24
getting-started.md
1---
2title: Getting Started
3description: Use starfx with deno, node, or the browser
4toc: 1
5---
6
7# Motivation
8
9We think we need a react framework and server-side rendering (SSR) because
10that's where money is being made. If we are building a highly dynamic and
11interactive web application then we probably don't need SSR. These frameworks
12sell us that they are an easier way to build web apps, but that's not strictly
13true. Just think of it this way: if we can build a web app using **only** static
14assets, isn't that simpler than having static assets **and** a react framework
15server?
16
17React hook-based fetching and caching libraries dramatically simplify data
18synchronization but are so tightly coupled to a component's life cycle that it
19creates waterfall fetches and loading spinners everywhere. We also have the
20downside of not being able to normalize our cache which means we have to spend
21time thinking about how and when to invalidate our cache.
22
23Further, all of these data caching libraries don't handle data normalization. In
24many similar libraries we are going to see a line like: "Data normalization is
25hard and it isn't worth it." Their libraries are not built with data
26normalization in mind so they claim it's an anti-feature. Why do we want to
27normalize data in the backend but not the frontend? Data normalization is
28critically important because it makes CRUD operations automatically update our
29web app without having to invalidate our cache.
30
31So what if we are building a highly interactive web app that doesn't need SEO
32and we also need more control over data synchronization and caching?
33
34Are you frustrated by the following issues in your react app?
35
36- Prop drilling
37- Waterfall fetching data
38- Loading spinners everywhere
39- Extraneous network calls
40- Business logic tightly coupled to react component lifecycle hooks
41- State management boilerplate
42- Lack of state management
43- Lack of async flow control tooling
44
45We built `starfx` because we looked at the web app landscape and felt like there
46was something missing.
47
48The benefits of using this library:
49
50- The missing model and controller (MC) in react (V)
51- Designed for single-page applications (SPAs)
52- Makes data normalization easy and straightforward
53- Tools to preload and refresh data
54- Has a powerful middleware system similar to `express` to handle requests and
55 responses
56- Reduces state management boilerplate to its absolute essentials
57- Has a robust side-effect management system using structured concurrency
58- Has data synchronization and caching separated from `react`
59
60# When to use this library?
61
62The primary target for this library are SPAs. This is for an app that might be
63hosted inside an object store (like s3) or with a simple web server (like nginx)
64that serves files and that's it.
65
66Is your app highly interactive, requiring it to persist data across pages? This
67is the sweet spot for `starfx`.
68
69This library is **not** a great fit for ecommerce, tiny projects, or blogs. This
70is for web apps that are generally behind a login screen that require a
71desktop-class user experience. This library is designed to scale, so it might
72feel a little overwhelming. Just know if you use this library, your code will be
73easier to read, easier to write, easier to refactor, all while handling a
74massive amount of business complexity.
75
76# Code
77
78Here we demonstrate a complete example so you can glimpse at how `starfx` works.
79In this example, we will fetch a github repo from an API endpoint, cache the
80`Response` json, and then ensure the endpoint only gets called at-most once
81every **5 minutes**, mimicking the basic features of `react-query`.
82
83[Codesanbox](https://codesandbox.io/p/sandbox/starfx-simplest-dgqc9v?file=%2Fsrc%2Findex.tsx)
84
85```tsx
86import { createApi, createSchema, createStore, mdw, timer } from "starfx";
87import { Provider, useCache } from "starfx/react";
88
89const [schema, initialState] = createSchema();
90const store = createStore({ initialState });
91
92const api = createApi();
93// mdw = middleware
94api.use(mdw.api({ schema }));
95// where `fetchRepo` will be placed inside the middleware stack
96api.use(api.routes());
97api.use(mdw.fetch({ baseUrl: "https://api.github.com" }));
98
99const fetchRepo = api.get(
100 "/repos/neurosnap/starfx",
101 { supervisor: timer() },
102 api.cache(),
103);
104
105store.run(api.register);
106
107function App() {
108 return (
109 <Provider schema={schema} store={store}>
110 <Example />
111 </Provider>
112 );
113}
114
115function Example() {
116 const { isInitialLoading, isError, message, data } = useCache(fetchRepo());
117 if (isInitialLoading) return "Loading ...";
118 if (isError) return `An error has occurred: ${message}`;
119
120 return (
121 <div>
122 <h1>{data.name}</h1>
123 <p>{data.description}</p>
124 <strong>👀 {data.subscribers_count}</strong>{" "}
125 <strong>✨ {data.stargazers_count}</strong>{" "}
126 <strong>🍴 {data.forks_count}</strong>
127 </div>
128 );
129}
130```
131
132# Install
133
134```bash
135npm install starfx
136```
137
138```bash
139yarn add starfx
140```
141
142```ts
143import * as starfx from "https://deno.land/x/starfx@0.13.2/mod.ts";
144```
145
146# Effection
147
148This library leverages structured concurrency using
149[`effection`](https://frontside.com/effection). It is highly recommended that
150you have a brief understanding of how its API because it is used heavily within
151`starfx`.