{"id":19924482,"url":"https://github.com/giacomorebonato/fastrat","last_synced_at":"2025-05-03T07:31:36.443Z","repository":{"id":212048424,"uuid":"730580485","full_name":"giacomorebonato/fastrat","owner":"giacomorebonato","description":"Fullstack starter kit, using Fastify + React = FastRat","archived":false,"fork":false,"pushed_at":"2025-04-24T13:58:54.000Z","size":6703,"stargazers_count":45,"open_issues_count":12,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-24T14:49:11.995Z","etag":null,"topics":["fastify","playwright","pwa","react","typescript","vite"],"latest_commit_sha":null,"homepage":"https://www.fastrat.dev","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/giacomorebonato.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,"zenodo":null}},"created_at":"2023-12-12T08:32:23.000Z","updated_at":"2025-03-29T03:14:12.000Z","dependencies_parsed_at":"2023-12-20T15:13:40.927Z","dependency_job_id":"d0b7ce06-100b-4870-a7b7-ff7330357bd3","html_url":"https://github.com/giacomorebonato/fastrat","commit_stats":null,"previous_names":["giacomorebonato/fastrat"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomorebonato%2Ffastrat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomorebonato%2Ffastrat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomorebonato%2Ffastrat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomorebonato%2Ffastrat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giacomorebonato","download_url":"https://codeload.github.com/giacomorebonato/fastrat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252156944,"owners_count":21703379,"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":["fastify","playwright","pwa","react","typescript","vite"],"created_at":"2024-11-12T22:17:42.219Z","updated_at":"2025-05-03T07:31:36.435Z","avatar_url":"https://github.com/giacomorebonato.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fastify + React = FastRat! \u003c!-- omit from toc --\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg \n    src=\"https://github.com/giacomorebonato/fastrat/blob/main/src/images/logo.jpg?raw=true\" \n    alt=\"A rat on a skateboard\"\n    width='200'\n    height='200'\n  /\u003e\n\u003c/p\u003e\n\n## Quickstart \u003c!-- omit from toc --\u003e\n\n```bash\ngh repo clone giacomorebonato/fastrat-test # clone the repository\npnpm install # install dependencies\nnode --run dev     # start the project in dev mode\n```\n\nTo enable authentication and a production database, rename `.env.example` to `.env` and fill the fields properly.  \nIn a production environment, you should set those environment variables directly.\n\n[Example with Fly.io](https://fly.io/docs/reference/secrets/)\n\n\n- [Authentication](#authentication)\n- [libSQL (SQLite fork) on Turso](#libsql-sqlite-fork-on-turso)\n- [SSR and Routing](#ssr-and-routing)\n- [tRPC](#trpc)\n- [Server side data fetching](#server-side-data-fetching)\n- [Testing](#testing)\n- [Deploy](#deploy)\n- [Credits](#credits)\n\n## Based on these libraries \u003c!-- omit from toc --\u003e\n\n* [Fastify](https://fastify.dev): a fast well maintained web framework\n* [Vite](https://vitejs.dev): for frontend tooling and bundling\n* [tRPC](https://trpc.io/docs/server/adapters/fastify): for end points with E2E type safety\n* [Tanstack Router](https://tanstack.com/router/latest): for filesystem based routes with type safety\n* [Vavite](https://github.com/cyco130/vavite): use Vite to compile and bundle both client and server code\n* [Fly.io](https://fly.io): for deployment\n\n\nThanks to Vavite, any change to frontend or backend code will be reflected immediately, without manually restarting the server.\n\n## Authentication\n\nProvide `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` into the `.env` file to allow Google authentication ([instructions](https://www.balbooa.com/help/gridbox-documentation/integrations/other/google-client-id)).  \nYou can check how authentication is achieved in [src/features/auth/google-auth.ts](src/auth/google-auth.ts) by leveraging [fastify-oauth2](https://github.com/fastify/fastify-oauth2).  \nIt should be easy for you to re-use this example to add other authentication providers.\n\n## libSQL (SQLite fork) on Turso\n\n1. install the [turso CLI](https://docs.turso.tech/cli/installation)\n2. login and create a database `turso db create fastrat`\n3. get an authentication token with `turso db tokens create fastrat`\n4. [set Fly.io secrets accordingly](https://fly.io/docs/flyctl/secrets-set/)\n\n## SSR and Routing\n\nSSR is achieved by following [Tanstack router examples](https://github.com/TanStack/router/tree/main/examples/react/basic-ssr-streaming-file-based).\nThe page content is streamed and meta tags in `\u003chead /\u003e` are rendered following [react-helmet-async examples](https://github.com/staylor/react-helmet-async?tab=readme-ov-file#streams).\n\n\n## tRPC\n\nThis project comes with [tRPC](https://trpc.io) ready to be used.\nCheck [note-router.ts](src/notes/note-api.ts) to see how queries, mutations and subscriptions can be implemented.  \nAll the routers are collected in [api-router.ts](src/server/api-router.ts), but you can organise files in the way you prefer.\n\n## Server side data fetching\n\nServer side data fetching is needed if you want to render HTML on server side (for SEO for example).  \nIt happens in the [route loader function](src/routes/notes/$noteId.tsx) defined in Tanstack router.  \nAs in the link you have to be mindful that the loader runs both server and client side, hence you should guard dynamic server only import inside of the `if (import.meta.env.SSR)` condition.  \nYou can then assign the fetched data to React-Query `initialData` parameter, like this:\n\n```typescript\nconst loaderData = Route.useLoaderData()\n\nconst noteQuery = trpcClient.note.get.useQuery(\n  { id: noteId },\n  {\n    initialData: loaderData?.note,\n  },\n)\n```\n\nWith this practice we ensure that:\n\n* HTML is rendered if the page is accessed through server side routing\n* a request is made to fetch data if the page is accessed through client side routing\n\nThis probably looks less magical than `getServerSideProps`, but still gives you full control over the rendering process.\n\n## Testing\n\nThis starter contains a few unit tests and an E2E test.\n\n```bash\nnode --run test        # uses Vitest to run unit tests\nnode --run e2e         # uses PlayWright to run E2E tests\nnode --run e2e:headed  # uses PlayWright to run E2E tests opening the browser\n```\n\nThe present E2E tests verify that the page is server rendered and that websockets are working.\n\n\n## Deploy\n\nYou can deploy FastRat everywhere Docker runs.\n\n* This website deploys automatically to Fly.io\n  * https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/\n  * [GitHub action](.github/workflows/fly.yml)\n* [Environment variables](src/features/server/env.ts)\n  * https://fly.io/docs/rails/the-basics/configuration/\n  * [fly.toml](fly.toml)\n\n## Credits\n\nThis project has been inspired by other starter kits:\n\n- [create-t3-app](https://github.com/t3-oss/create-t3-app)\n- [epic-stack](https://github.com/epicweb-dev/epic-stack)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomorebonato%2Ffastrat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiacomorebonato%2Ffastrat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomorebonato%2Ffastrat/lists"}