{"id":16523318,"url":"https://github.com/hviana/faster_react","last_synced_at":"2025-04-07T09:17:34.738Z","repository":{"id":257649180,"uuid":"858918027","full_name":"hviana/faster_react","owner":"hviana","description":"Tiny Full-Stack React framework. Avoid Overengineering. Automatic routes, reload and component bundle. It uses its own RSC engine, combining SSR and CSR. 100% Deno, no Node dependencies. Fully compatible with Deno Deploy and Serverless Environments.","archived":false,"fork":false,"pushed_at":"2025-03-24T13:17:46.000Z","size":102,"stargazers_count":110,"open_issues_count":0,"forks_count":7,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-31T08:08:12.342Z","etag":null,"topics":["deno","full-stack-web-development","react","rsc"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hviana.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-17T18:56:28.000Z","updated_at":"2025-03-29T07:29:32.000Z","dependencies_parsed_at":"2024-10-27T11:49:13.927Z","dependency_job_id":"a5e2c3c4-db0d-4b82-a0ce-15e6f1433d0c","html_url":"https://github.com/hviana/faster_react","commit_stats":{"total_commits":1,"total_committers":1,"mean_commits":1.0,"dds":0.0,"last_synced_commit":"1dab02010e5252f417b2dc70fc7094c7eed89d13"},"previous_names":["hviana/faster_react"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hviana%2Ffaster_react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hviana%2Ffaster_react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hviana%2Ffaster_react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hviana%2Ffaster_react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hviana","download_url":"https://codeload.github.com/hviana/faster_react/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247622986,"owners_count":20968575,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","full-stack-web-development","react","rsc"],"created_at":"2024-10-11T17:01:05.626Z","updated_at":"2025-04-07T09:17:34.717Z","avatar_url":"https://github.com/hviana.png","language":"TypeScript","readme":"![](https://img.shields.io/badge/development_stage-stable-blue)\n![](https://img.shields.io/badge/tests-pass-green)\n\n\u003cimg src=\"https://raw.githubusercontent.com/hviana/faster_react_core/refs/heads/main/docs/programmer-man.gif\" width=\"125\"\u003e\n\n# 🚀 **faster_react**\n\n\u003e [!IMPORTANT]\\\n\u003e **Please give a star!** ⭐\n\n---\n\n## 🌟 Introduction\n\n`faster_react` is a tiny Full-Stack React framework. He avoids Overengineering.\nThis framework **uses its own RSC engine, combining SSR and CSR**, and\nautomatically generates routes for React components. To utilize this, you must\nuse the routes helper provided by the framework\n([React Router](#-react-router)). The framework's configuration file is located\nat `options.json`.\n\n### 🎯 **What Does `faster_react` Do for You?**\n\nFocus solely on development! This framework handles:\n\n- 🛣️ **Automatic route generation** for React components.\n- 🔄 **Automatic inclusion** of new React components when\n  `framework =\u003e \"dev\": true`.\n- 📦 **Automatic frontend bundling** when `framework =\u003e \"dev\": true`.\n- ♻️ **Automatic browser reload** when `framework =\u003e \"dev\": true`.\n- 🗜️ **Automatic frontend minification** when `framework =\u003e \"dev\": false`.\n- 🚀 **Automatic backend reload** when changes are detected and\n  `framework =\u003e \"dev\": true`.\n- 🌐 **Automatic detection** of Deno Deploy environment. Test in other\n  serverless environments by setting `framework =\u003e \"serverless\": true`.\n\n\u003e **Note:** The project includes a simple application example demonstrating each\n\u003e functionality. The example uses Tailwind CSS, but this is optional. You can\n\u003e use whatever CSS framework you want.\n\n---\n\n### ⚡ **About Faster**\n\nThis framework uses a middleware library called Faster. Faster is an optimized\nmiddleware server with an incredibly small codebase (~300 lines), built on top\nof native HTTP APIs with no dependencies. It includes a collection of useful\nmiddlewares:\n\n- 📄 **Log file**\n- 🗂️ **Serve static**\n- 🌐 **CORS**\n- 🔐 **Session**\n- ⏱️ **Rate limit**\n- 🛡️ **Token**\n- 📥 **Body parsers**\n- 🔀 **Redirect**\n- 🔌 **Proxy**\n- 📤 **Handle upload**\n\nFully compatible with Deno Deploy and other enviroments. Examples of all\nresources are available in the [README](https://github.com/hviana/faster).\nFaster's ideology is simple: all you need is an optimized middleware manager;\nall other functionality is middleware.\n\n---\n\n## 📚 **Contents**\n\n- [⚡ Benchmarks](#-benchmarks)\n- [🏗️ Architecture](#%EF%B8%8F-architecture)\n- [📂 App Structure](#-app-structure)\n  - [📦 Get Deno Kv and Deno Kv Fs](#-get-deno-kv-and-deno-kv-fs)\n  - [📝 Backend API](#-backend-api)\n  - [🧩 Backend Components](#-backend-components)\n  - [📁 Backend Files](#-backend-files)\n  - [🖥️ Frontend Components](#%EF%B8%8F-frontend-components)\n  - [🎨 Frontend CSS](#-frontend-css)\n  - [📜 Frontend Files](#-frontend-files)\n  - [🌎 Frontend Translations](#-frontend-translations)\n  - [🗂️ Static](#%EF%B8%8F-static)\n- [🧭 React Router](#-react-router)\n- [📦 Packages Included](#-packages-included)\n- [🛠️ Creating a Project](#%EF%B8%8F-creating-a-project)\n- [🚀 Running a Project](#-running-a-project)\n- [🌐 Deploy](#-deploy)\n- [📖 References](#-references)\n- [👨‍💻 About](#-about)\n\n---\n\n## ⚡ **Benchmarks**\n\n`faster_react` has only **0.9%** of the code quantity of Deno Fresh.\n\n**Benchmark Command:**\n\n```bash\n# Deno Fresh\ngit clone https://github.com/denoland/fresh.git\ncd fresh\ngit ls-files | xargs wc -l\n# Output: 104132 (version 1.7.3)\n\n# faster_react\ngit clone https://github.com/hviana/faster_react.git\ncd faster_react\ngit ls-files | xargs wc -l\n# Output: 1037 (version 20.1)\n```\n\n---\n\n## 🏗️ **Architecture**\n\nThis framework utilizes **Headless Architecture** [[1]](#1) to build the\napplication, combined with the **Middleware Design Pattern** [[2]](#2) for\ndefining API routes in the backend.\n\n- **Headless Architecture** provides complete freedom to the developer, reducing\n  the learning curve. Despite this freedom, there is an **explicit separation\n  between backend and frontend**, which aids in development.\n- The **Middleware Design Pattern** offers a practical and straightforward\n  method for defining API routes.\n\n![Architecture Diagram](https://raw.githubusercontent.com/hviana/faster_react_core/refs/heads/main/docs/graph.svg)\n\n---\n\n## 📂 **App Structure**\n\nAll application folders are inside the `app` folder.\n\n### 📦 **Get Deno Kv and Deno Kv Fs**\n\nOn the backend, if a **Deno KV** instance is available, access instances via\n`Server.kv` and `Server.kvFs`:\n\n```typescript\nimport { Server } from \"faster\";\n```\n\nSee **Deno KV** settings in `options.json`.\n\n- **Deno KV File System (`Server.kvFs`):** Compatible with Deno Deploy. Saves\n  files in 64KB chunks. Organize files into directories, control the KB/s rate\n  for saving and reading files, impose rate limits, set user space limits, and\n  limit concurrent operations—useful for controlling uploads/downloads. Utilizes\n  the Web Streams API.\n\nMore details: [deno_kv_fs](https://github.com/hviana/deno_kv_fs)\n\n---\n\n### 📝 **Backend API**\n\n- **Imports:** Import your backend libraries here.\n- **Organization:** Files can be organized into subdirectories.\n- **File Extension:** Use `.ts` files.\n- **Structure:** Flexible file and folder structure that doesn't influence\n  anything.\n- **Routing:** Define routes using any pattern you prefer.\n- **Exports:** Must have a `default export` with a function (can be\n  asynchronous).\n- **Function Input:** Receives an instance of `Server` from `faster`.\n- **Usage:** Perform backend manipulations here (e.g., fetching data from a\n  database), including asynchronous calls.\n- **Routes:** Define your custom API routes. For help, see:\n  [faster](https://github.com/hviana/faster)\n\n---\n\n### 🧩 **Backend Components**\n\n- **Optionality:** A backend component is optional for a frontend component.\n- **Imports:** Import your backend libraries here.\n- **Organization:** Organize files into subdirectories.\n- **File Extension:** Use `.ts` files.\n- **Correspondence:** Each file should have the same folder structure and name\n  as the corresponding frontend component but with a `.ts` extension.\n\n  - **Example:**\n    - Frontend: `frontend/components/checkout/cart.tsx`\n    - Backend: `backend/components/checkout/cart.ts`\n\n- **Exports:** Must have a `default export` with an object of type\n  `BackendComponent`:\n\n  ```typescript\n  import { type BackendComponent } from \"@helpers/backend/types.ts\";\n  ```\n\n- **Usage:** Intercept a frontend component request:\n  - **Before Processing (`before?: RouteFn[]`):** List of middleware functions\n    (see: [faster](https://github.com/hviana/faster)). Use to check headers\n    (`ctx.req.headers`) or search params (`ctx.url.searchParams`), like tokens,\n    impose rate limits etc.\n\n    \u003e **Note:** To cancel page processing, do not call `await next()` at the end\n    \u003e of a middleware function.\n\n    \u003e **Important:** If you want the page to be processed, **do not** consume\n    \u003e the `body` of `ctx.req`, or it will cause an error in the framework.\n\n  - **After Processing\n    (`after?: (props: JSONObject) =\u003e void | Promise\u003cvoid\u003e`):** Function receives\n    the `props` that will be passed to the component. Add backend data to these\n    `props`, such as data from a database. Can be asynchronous.\n    \u003e **Note:** Only use props data in JSON-like representation, or hydration\n    \u003e will fail.\n\n---\n\n### 📁 **Backend Files**\n\n- **Imports:** Import your backend libraries here.\n- **Organization:** Organize files into subdirectories.\n- **File Extension:** Use `.ts` files.\n- **Usage:** Free to make exports or calls (including asynchronous).\n- **Purpose:** Group common functions/objects for `backend/api`,\n  `backend/components`, and other `backend/files`, such as user validations.\n\n---\n\n### 🖥️ **Frontend Components**\n\n- **Imports:** Use only frontend libraries.\n- **Organization:** Organize files into subdirectories.\n- **File Extension:** Use `.tsx` files.\n- **Rendering:** Rendered on the server and hydrated on the client.\n- **Routes Generated:** Two routes per file (e.g.,\n  `frontend/components/checkout/cart.tsx`):\n  - **Page Route:** For rendering as a page, e.g., `/pages/checkout/cart`.\n  - **Component Route:** For rendering as a component, e.g.,\n    `/components/checkout/cart`.\n- **Initial Route (`/`):** Points to `frontend/components/index.tsx`.\n- **Exports:** Must have a `default export` with the React Function/Component.\n- **Props Passed to Component:**\n  - Form-submitted data (or JSON POST).\n  - URL search parameters (e.g., `/pages/myPage?a=1\u0026b=2` results in\n    `{a:1, b:2}`).\n  - Manipulations from `backend/components`.\n\n---\n\n### 🎨 **Frontend CSS**\n\nApplication CSS style files.\n\n- **Multiple Files:** Automatically compiled.\n- **Organization:** Organize files into subdirectories.\n\n---\n\n### 📜 **Frontend Files**\n\n- **Imports:** Use only frontend libraries.\n- **Organization:** Organize files into subdirectories.\n- **File Extensions:** Use `.ts` and `.js` files.\n- **Usage:** Free to make exports or calls (including asynchronous).\n- **Difference from Components:** Scripts are not automatically delivered to the\n  client. They need to be imported by the `frontend/components`.\n- **Purpose:** Group common functions/objects for React Functions/Components,\n  like form field validations. Can have `frontend/files` common to other\n  `frontend/files`.\n\n---\n\n### 🌎 **Frontend Translations**\n\n- **File Extensions:** Use `.json` files.\n- **Correspondence:** Each file should have the same folder structure and name\n  as the corresponding frontend component but with a `.json` extension.\n\n  - **Example:**\n    - Frontend: `frontend/components/checkout/cart.tsx`\n    - Backend: `frontend/translations/en/checkout/cart.json`\n    \u003e **Note:** Change **en** to your language.\n- **Usage:**\n\nIn `frontend/components/index.tsx`:\n\n```jsx\nimport {\n  detectedLang,\n  useTranslation,\n} from \"@helpers/frontend/translations.ts\";\nconst Home = () =\u003e {\n  const t = useTranslation();\n  //Any .init parameter of i18next (minus ns) is valid in useTranslation.\n  //Ex: useTranslation({ lng: [\"es\"], fallbackLng: \"en\" }) etc.\n  //On the client side, the language is automatically detected (if you don't specify).\n  //On the server, the language is \"en\" (if you don't specify).\n  //The \"en\" is also the default fallbackLng.\n  return (\n    \u003cdiv className=\"app-name\"\u003e\n      {t(\"index.appName\", { endExample: \"!\" })}\n    \u003c/div\u003e\n  );\n};\nexport default Home;\n```\n\nIn `frontend/translations/en/index.json`:\n\n```json\n{\n  \"appName\": \"My SaaS App {{endExample}}\"\n}\n```\n\nThe framework translation is just a wrapper over i18next. See the i18next\ndocumentation if you have questions.\n\n---\n\n### 🗂️ **Static**\n\nFiles served statically. Routes are generated based on the folder and file\nstructure.\n\n- **Example:** `localhost:8080/static/favicon.ico` matches `static/favicon.ico`.\n\n---\n\n## 🧭 **React Router**\n\nSince the framework has its own routing system, a third-party routing library is\nunnecessary. Use the framework helper:\n\n\u003e **Note:** Direct form submissions for page routes path also work.\n\n```typescript\nimport { getJSON, route } from \"@helpers/frontend/route.ts\";\n```\n\n### **Interface Parameters:**\n\n```typescript\ninterface Route {\n  headers?: Record\u003cstring, string\u003e; // When routing to a page, headers are encoded in the URL. Intercept them in ctx.url.searchParams in a backend/components file.\n  content?:\n    | Record\u003cany, any\u003e\n    | (() =\u003e Record\u003cany, any\u003e | Promise\u003cRecord\u003cany, any\u003e\u003e);\n  path: string;\n  startLoad?: () =\u003e void | Promise\u003cvoid\u003e;\n  endLoad?: () =\u003e void | Promise\u003cvoid\u003e;\n  onError?: (e: Error) =\u003e void | Promise\u003cvoid\u003e;\n  disableSSR?: boolean; //For component routes. Disables SSR; defaults to false.\n  elSelector?: string; // Required for component routes.\n  method?: string; // Only for API routes. Optional; defaults to GET or POST.\n}\n```\n\n### **Examples**\n\n**Navigating to a Page with Search Params:**\n\n```jsx\n// URL search params passed as properties to the page. Props receive `{a:1}`\n\u003cbutton onClick={route({ path: \"/pages/test?a=1\" })}\u003e\n  Go to Test Page\n\u003c/button\u003e;\n```\n\n**Passing Additional Parameters:**\n\n```jsx\n// Props receive `{a:1, example:\"exampleStr\"}`\n\u003cbutton\n  onClick={route({\n    path: \"/pages/test?a=1\",\n    content: { example: \"exampleStr\" },\n  })}\n\u003e\n  Go to Test Page with Extra Data\n\u003c/button\u003e;\n```\n\n**Using Asynchronous Content:**\n\n```jsx\n// Props receive `{a:1, ...JSONResponse}`\n\u003cbutton\n  onClick={route({\n    path: \"/pages/test?a=1\",\n    content: async () =\u003e {\n      return await getJSON({\n        path: \"/example/json\",\n        content: {\n          test: \"testData\",\n        },\n      });\n    },\n  })}\n\u003e\n  Go to Test Page with Async Data\n\u003c/button\u003e;\n```\n\n**Programmatic Routing:**\n\n```typescript\n(async () =\u003e {\n  if (user.loggedIn) {\n    await route({\n      path: \"/pages/dash\",\n      content: { userId: user.id, token: token },\n    })();\n  } else {\n    await route({ path: \"/pages/users/login\" })();\n  }\n})();\n```\n\n**Loading a Component:**\n\n```jsx\n\u003cbutton\n  onClick={route({\n    path: \"/components/parts/counter\",\n    elSelector: \"#counter\",\n  })}\n\u003e\n  Load Counter Component\n\u003c/button\u003e;\n```\n\n**Making an API Call:**\n\n```jsx\n\u003cbutton\n  onClick={async () =\u003e {\n    const res = await getJSON({\n      path: \"/example/json\",\n      content: {\n        test: \"testData\",\n      },\n    });\n    console.log(res);\n    alert(JSON.stringify(res));\n  }}\n\u003e\n  Fetch JSON Data\n\u003c/button\u003e;\n```\n\nIn the case of page routes, you can use this example to pass the URL parameters\nfor the headers in the backend (if you really need it):\n\n```typescript\nconst signupBackendComponent: BackendComponent = {\n  before: [\n    async (ctx: Context, next: NextFunc) =\u003e {\n      ctx.req = new Request(ctx.req, {\n        headers: {\n          ...Object.fromEntries(ctx.req.headers as any),\n          \"Authorization\": `Bearer token ${ctx.url.searchParams.get(\"token\")}`,\n        },\n      });\n      await next();\n    },\n  ],\n};\nexport default signupBackendComponent;\n```\n\nForms submit for page routes work. For components, you can use the following:\n\n```tsx\n\u003cform\n  method=\"POST\"\n  action=\"\"\n  encType=\"multipart/form-data\"\n  onSubmit={async (event) =\u003e {\n      event.preventDefault();\n      const data: any = new FormData(event.target as any);\n      const formObject = Object.fromEntries(data.entries());\n      await route({\n        startLoad: () =\u003e setLoading(true), //useState\n        endLoad: () =\u003e setLoading(false),\n        path: \"/components/register\",\n        elSelector: \"#dash-content\",\n        content: formObject,\n      })();\n  }}\n\u003e\n```\n\n---\n\n## 📦 **Packages Included**\n\nSeveral packages are included to assist in developing React applications. Here\nare some examples of imports you can use without additional configuration:\n\n```typescript\nimport {/* your imports */} from \"react\";\nimport {/* your imports */} from \"react/\";\nimport {/* your imports */} from \"i18next\";\nimport {/* your imports */} from \"react-dom\";\nimport {/* your imports */} from \"react-dom/server\";\nimport {/* your imports */} from \"react-dom/client\";\nimport {/* your imports */} from \"react/jsx-runtime\";\ns;\nimport {/* your imports */} from \"@helpers/frontend/route.ts\";\nimport {/* your imports */} from \"@helpers/frontend/translations.ts\";\nimport {/* your imports */} from \"@helpers/backend/types.ts\";\nimport {/* your imports */} from \"faster\";\nimport {/* your imports */} from \"deno_kv_fs\";\nimport {/* your imports */} from \"jose\"; //manage tokens\nimport { options, server } from \"@core\"; // Useful for accessing the server instance.\n```\n\n---\n\n## 🛠️ **Creating a Project**\n\nYou can simply download this repository. Alternatively, use the command\n(requires `git` installed and configured):\n\n```bash\ndeno run -A -r \"https://deno.land/x/faster_react_core/new.ts\" myProjectFolder\n```\n\nCustomize and configure the server in `options.json`.\n\n---\n\n## 🚀 **Running a Project**\n\nExecute the command:\n\nDevelopment:\n\n```bash\ndeno task serve\n```\n\nProduction:\n\n```bash\ndeno serve main.ts #Add your permissions, port, certificate etc. see: https://docs.deno.com/runtime/reference/cli/serve\n```\n\n---\n\n## 🌐 **Deploy**\n\n- **Install Deployctl:**\n\n  ```bash\n  deno install -A --global jsr:@deno/deployctl\n  ```\n\n- **Deploy Your Project:**\n\n  ```bash\n  deployctl deploy\n  ```\n\n\u003e **Note:** For production, set `framework =\u003e \"dev\": false` in `options.json`.\n\n---\n\n## 📖 **References**\n\n\u003ca id=\"1\"\u003e[1]\u003c/a\u003e Dragana Markovic, Milic Scekic, Alessio Bucaioni, and Antonio\nCicchetti. 2022. _Could Jamstack Be the Future of Web Applications Architecture?\nAn Empirical Study._ In _Proceedings of the 37th ACM/SIGAPP Symposium on Applied\nComputing_ (SAC '22). Association for Computing Machinery, New York, NY, USA,\n1872–1881. DOI:\n[10.1145/3477314.3506991](https://doi.org/10.1145/3477314.3506991)\n\n\u003ca id=\"2\"\u003e[2]\u003c/a\u003e Brown, Ethan. _Web Development with Node and Express:\nLeveraging the JavaScript Stack_. O'Reilly Media, 2019. URL:\n[http://www.oreilly.com/catalog/9781492053484](http://www.oreilly.com/catalog/9781492053484)\n\n---\n\n## 👨‍💻 **About**\n\n**Author:** Henrique Emanoel Viana, a Brazilian computer scientist and web\ntechnology enthusiast.\n\n- 📞 **Phone:** +55 (41) 99999-4664\n- 🌐 **Website:**\n  [https://sites.google.com/view/henriqueviana](https://sites.google.com/view/henriqueviana)\n\n\u003e **Improvements and suggestions are welcome!**\n\n---\n","funding_links":[],"categories":["Modules"],"sub_categories":["Web framework"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhviana%2Ffaster_react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhviana%2Ffaster_react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhviana%2Ffaster_react/lists"}