{"id":21277621,"url":"https://github.com/lithdew/dew","last_synced_at":"2025-04-14T12:22:16.578Z","repository":{"id":263510930,"uuid":"890635075","full_name":"lithdew/dew","owner":"lithdew","description":"My go-to full-stack end-to-end type-safe React project template.","archived":false,"fork":false,"pushed_at":"2024-12-02T17:33:17.000Z","size":121,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T15:07:00.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lithdew.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-11-18T23:10:03.000Z","updated_at":"2025-02-12T16:11:42.000Z","dependencies_parsed_at":"2024-11-19T00:24:56.451Z","dependency_job_id":"3e414077-262f-4ffe-a10d-52006056a3fa","html_url":"https://github.com/lithdew/dew","commit_stats":null,"previous_names":["lithdew/dew"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lithdew%2Fdew","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lithdew%2Fdew/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lithdew%2Fdew/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lithdew%2Fdew/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lithdew","download_url":"https://codeload.github.com/lithdew/dew/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248878240,"owners_count":21176301,"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":[],"created_at":"2024-11-21T10:06:29.256Z","updated_at":"2025-04-14T12:22:16.539Z","avatar_url":"https://github.com/lithdew.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dew\n\nMy go-to full-stack end-to-end type-safe React project template.\n\n```bash\n$ bun create lithdew/dew [project-name]\n```\n\n```bash\n# Install dependencies\nbun install\n\n# Run dev server\nbun dev\n\n# Build production bundle\nbun run build\n\n# Run production bundle\nbun start\n```\n\n## Libraries\n\n- Bun\n- Vinxi\n- React 19\n- TanStack Start\n- TanStack Router\n- TanStack Query v5\n- TailwindCSS v4\n- ElysiaJS\n- devalue\n\n## Stack\n\n- `backend` contains the backend API code.\n- `web` contains the frontend SPA code.\n- `stack` contains shared code between the backend and frontend.\n\n## Guidelines\n\n1. Define your shared entities, business logic, and global variables in `stack`.\n2. Define your server-side controllers, workers, API routes, secrets, and global variables in `backend`.\n3. Define your client-side components, routes, hooks, styles and global variables in `web`.\n\n## Design Decisions\n\n### ElysiaJS instead of TanStack Start's Server Functions and API Routes\n\nTanStack Start's server functions and API routes are intentionally NOT used because:\n\n1. the API surface around server functions and API routes is still a heavy work in progress,\n2. there is no way to work around current limitations with server functions/API routes because its internals (i.e. configuring how requests/responses get transformed when invoking a server function) are not exposed.\n\nElysiaJS is integrated as an alternative to TanStack Start. ElysiaJS provides end-to-end type safety for both the frontend and backend.\n\nElysiaJS has been a pleasure to work with. ElysiaJS comes out of the box with support for:\n\n- dependency injection via. \"plugins\"\n- end-to-end type safety with thousands of routes and plugins\n- lots of useful official/community-backed plugins (OpenAPI, GraphQL, JWT, Streaming, Server Timing, OpenTelemetry, etc.)\n\nAn isomorphic type-safe API client (a client that may be invoked on the client/server) for interacting with the built-in ElysiaJS server is available in the `stack` library. The client is built using ElysiaJS' Eden Treaty and `vite-env-only`.\n\n### Disabling SSR\n\nI intentionally set up the project to not server-side render any HTML DOM elements.\n\nThe only server-side rendering that occurs is the initial HTML shell that is sent to the client. This shell contains the necessary scripts, meta tags, stylesheets, and TanStack Router loader data to bootstrap the client-side React application.\n\nFor the purposes of projects I work on, they generally feature _a lot_ of highly dynamic data (data that is likely to change very frequently). It is generally pointless to server-side render the HTML DOM elements of pages whose contents frequently changes because the HTML provided by the server is likely to be stale/outdated in terms of contents by the time it is fully delivered to the client.\n\nDisabling SSR also gives peace of mind to frontend developers in your team. They are free to use any client-side libraries and generally do not need to worry about how their frontend code runs along the SSR boundary. This saves A LOT of headaches when working with a team of developers.\n\n### Hydrate/dehydrate loader data with `devalue`\n\nThe TanStack Router loader data is hydrated/dehydrated with `devalue`. `devalue` was chosen for its benchmarks and for its support for a large variety of data types and references.\n\n`devalue` is intentionally, for security purposes, not used to hydrate/dehydrate user input. User input is instead hydrated/dehydrated with `JSON.parse` and `JSON.stringify`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flithdew%2Fdew","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flithdew%2Fdew","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flithdew%2Fdew/lists"}