Home

Awesome

faster_react

This framework does SSR + Hydration of all React components, and generates routes for these. But for that, you must use the routes helper of this framework (React Router). The framework configuration file is at options.json.

You only need to worry about developing. This framework does for you:

The project has a simple application example demonstrating each functionality.

About Faster, it is an optimized middleware server with an absurdly small amount of code (300 lines) built on top of Deno's native HTTP APIs with no dependencies. It also has a collection of useful middlewares: log file, serve static, CORS, session, rate limit, token, body parsers, redirect, proxy and handle upload. Fully compatible with Deno Deploy. In "README" there are examples of all the resources. Faster's ideology is: all you need is an optimized middleware manager, all other functionality is middleware. See more at: https://github.com/hviana/faster

Contents

Benchmarks

It has 0.9% of the code quantity of Deno Fresh. Benchmanrk command:

git clone https://github.com/denoland/fresh.git
cd fresh
git ls-files | xargs wc -l
# 104132 on version 1.7.1

git clone https://github.com/hviana/faster_react.git
cd faster_react
git ls-files | xargs wc -l
# 1037 on version 13.1

Architecture

This framework uses Headless Architecture [1] to build the application as a whole. Along with this, the Middleware Design Pattern [2] is used to define API routes in the Backend. Headless Architecture gives complete freedom to the developer. This freedom reduces the learning curve of the framework. Despite the freedom, there is an explicit separation between Backend and Frontend. This explicit separation helps programmers. In addition to this, the Middleware Design Pattern is very practical and simple for defining API routes.

<img src="https://raw.githubusercontent.com/hviana/faster_react/refs/heads/main/docs/graph.svg">

App structure

All these application folders are inside the app folder.

Get Deno Kv and Deno Kv Fs

On the Backend, if a Deno kv instance is possible, access instances in Server.kv and Server.kvFs => (import { Server } from "faster"). See Deno kv settings in options.json. Deno KV file system (Server.kvFs) is compatible with Deno deploy. Saves files in 64kb chunks. You can organize files into directories. You can control the KB/s rate for saving and reading files, rate limit, user space limit and limit concurrent operations, useful for controlling uploads/downloads. Makes use of Web Streams API. See more at: https://github.com/hviana/deno_kv_fs

The project has a simple application example demonstrating each functionality.

backend api

backend components

backend files

frontend components

frontend css

Application css style files.

frontend files

static

Files that will be served statically. Routes are generated automatically based on the folder and file structure, for example localhost:8080/static/favicon.ico will match the file static/favicon.ico.

React Router

Since the framework has its own routing system, a third-party routing library is not used. For this, there is a framework helper:

import { getJSON, route } from "@helpers/frontend/route.ts";

These helpers have the following interface as input parameters:

interface Route {
  headers?: Record<string, string>; //When a route is to a page, the headers are encoded in the URL. In this case, you can still intercept them in ctx.url.searchParams in a backend/components file.
  content?:
    | Record<any, any>
    | (() => Record<any, any> | Promise<Record<any, any>>);
  path: string;
  startLoad?: () => void | Promise<void>;
  endLoad?: () => void | Promise<void>;
  onError?: (e: Error) => void | Promise<void>;
  elSelector?: string; //Required for component routes.
  method?: string; //Only for API routes. It is optional, if not specified it will automatically use GET or POST.
}

Examples:

//URL Search params will be passed as properties to the page. In the example, the page props will receive `{a:1}`
<button onClick={route({ path: "/pages/test?a=1" })}></button>;

In addition to the URL Search params (which are optional), you can pass more parameters outside of url encoding:

//The page props will receive {a:1, "example":"exampleStr"}
<button
  onClick={route({
    path: "/pages/test?a=1",
    content: { "example": "exampleStr" },
  })}
>
</button>;

The parameter must be a JSON-serializable JavaScript object.

//The page props will receive `{a:1, ...JSONResponse}}`
<button
  onClick={route({
    path: "/pages/test?a=1",
    content: async () => {
      return await getJSON({
        path: "/example/json",
        content: {
          "test": "testData",
        },
      });
    },
  })}
>
</button>;

The result of the function must be a JSON-serializable JavaScript object.

Programmatically:

(async () => {
  if (user.loggedIn) {
    await route({
      path: "/pages/dash",
      content: { "userId": user.id, "token": token },
    })();
  } else {
    await route({ path: "/pages/users/login" })();
  }
});

More examples:

//component
<button
onClick={route({
  path: "/components/Counter",
  elSelector: "#myAnotherCounter",
})}>
</button>
//api
<button
onClick={async () => {
  const res = await getJSON({
    path: "/example/json",
    content: {
      "test": "testData",
    },
  });
  console.log(res);
  alert(JSON.stringify(res));
}}>
</button>

Packages included

There are several packages included to help you develop React applications. Here are some examples of imports that you can use without configuring anything:

import {/* your imports */} from "react";
import {/* your imports */} from "react/";
import {/* your imports */} from "react-dom";
import {/* your imports */} from "react-dom/server";
import {/* your imports */} from "react-dom/client";
import {/* your imports */} from "react/jsx-runtime";
import {/* your imports */} from "render";
import {/* your imports */} from "htm/react";
import {/* your imports */} from "@helpers/frontend/route.ts";
import {/* your imports */} from "@helpers/backend/types.ts";

/*
About Faster, it is an optimized middleware server with an absurdly small amount
of code (300 lines) built on top of Deno's native HTTP APIs with no
dependencies. It also has a collection of useful middlewares: log file, serve
static, CORS, session, rate limit, token, body parsers, redirect, proxy and
handle upload. Fully compatible with Deno Deploy. In "README" there are examples
of all the resources. Faster's ideology is: all you need is an optimized
middleware manager, all other functionality is middleware. See more at:
https://deno.land/x/faster
*/
import {/* your imports */} from "faster";

import { options, server } from "@core"; //Useful for accessing the server instance.

Creating a project

You can simply download this repository. There is also the command, which requires the git command installed and configured. Command: deno run -A -r "https://deno.land/x/faster_react/new.ts" myProjectFolder. You can make your customizations and configure the server in options.json.

Running a project

It is necessary to execute the command: deno task serve

Deploy

References

<a id="1">[1]</a> Dragana Markovic, Milic Scekic, Alessio Bucaioni, and Antonio Cicchetti. 2022. Could jamstack be the future of web applications architecture? an empirical study. In Proceedings of the 37th ACM/SIGAPP Symposium on Applied Computing (SAC '22). Association for Computing Machinery, New York, NY, USA, 1872–1881. DOI: https://doi.org/10.1145/3477314.3506991

<a id="2">[2]</a> Brown, Ethan. Web development with node and express: leveraging the JavaScript stack. O'Reilly Media, 2019. URL: http://www.oreilly.com/catalog/9781492053484

About

Author: Henrique Emanoel Viana, a Brazilian computer scientist, enthusiast of web technologies, cel: +55 (41) 99999-4664. URL: https://sites.google.com/view/henriqueviana

Improvements and suggestions are welcome!