{"id":20087025,"url":"https://github.com/ahoward2/personal-dashboard","last_synced_at":"2026-04-12T06:31:09.577Z","repository":{"id":37033507,"uuid":"489791475","full_name":"ahoward2/personal-dashboard","owner":"ahoward2","description":"Composable personal dashboard. 🔌","archived":false,"fork":false,"pushed_at":"2022-10-15T21:56:35.000Z","size":4919,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-02T14:35:39.220Z","etag":null,"topics":["dashboard-application","nestjs","react-location","react-query","reactjs","webpack"],"latest_commit_sha":null,"homepage":"https://composable-dashboard.fly.dev","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/ahoward2.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}},"created_at":"2022-05-07T22:08:42.000Z","updated_at":"2023-02-12T14:20:50.000Z","dependencies_parsed_at":"2022-06-25T13:39:43.739Z","dependency_job_id":null,"html_url":"https://github.com/ahoward2/personal-dashboard","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ahoward2/personal-dashboard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahoward2%2Fpersonal-dashboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahoward2%2Fpersonal-dashboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahoward2%2Fpersonal-dashboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahoward2%2Fpersonal-dashboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahoward2","download_url":"https://codeload.github.com/ahoward2/personal-dashboard/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahoward2%2Fpersonal-dashboard/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31706764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-12T06:22:27.080Z","status":"ssl_error","status_checked_at":"2026-04-12T06:21:52.710Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["dashboard-application","nestjs","react-location","react-query","reactjs","webpack"],"created_at":"2024-11-13T16:03:38.842Z","updated_at":"2026-04-12T06:31:09.548Z","avatar_url":"https://github.com/ahoward2.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Composable Personal Dashboard\n\n\u003e Composable dashboard application displaying information about a variety of\n\u003e user accounts. Aggregate data on the Node server from vendor API's and fit the\n\u003e REST API to the frontend client. The Node server also serves the client.\n\n## The Server\n\n- Backend for frontend server built with [Nest.js](https://nestjs.com/).\n- A functional approach to Nest with simple route handler functions instead of\n  Nest's traditional providers model (inspired by my\n  [easier-nest-server](https://github.com/ahoward2/easier-nest-server) project).\n- Custom in-memory caching (no package dependencies).\n  - Cache cleanup for old / unused cache entries with a cron job to save memory.\n- External data retrieved:\n  - General github profile information.\n  - Github repositories stats.\n  - General gitlab profile information.\n  - General twitter information.\n  - Last 90 tweets twitter stats.\n  - Last 30 tweets timeline data.\n\n## The Client\n\n- User interface built with [React](https://reactjs.org/).\n  - Custom Webpack configuration with\n    [esbuild-loader](https://github.com/privatenumber/esbuild-loader) for ⚡️.\n    - Suspense boundary on pages for tiny main bundle (could load pages from\n      remote locations - module federation 😉).\n- Client routing with [React Location](https://react-location.tanstack.com/).\n  - All data requirements handled at the route level to decouple initiating data\n    fetching from component rendering.\n- Client queries and caching with\n  [React Query](https://react-query.tanstack.com/).\n  - Caching handled at the route level.\n- Terminal inspired design.\n  - Styled with [tailwindcss](https://tailwindcss.com/) because it's awesome and\n    super easy to be fast with.\n  - Light \u0026 dark modes.\n- Data visualization \u0026 charting with\n  [chartjs](https://www.chartjs.org/docs/latest/).\n\n## Deployment\n\n- Deployed as an edge container with [fly.io](https://fly.io/).\n  - 1 region (Miami Florida, US).\n\n## Considerations\n\n- Caching on the server in-memory could eventually result in needing to increase\n  the memory capacity of the server. Redis or a CDN could probably do a better\n  job of this so I'm looking at what is the most inexpensive option. The\n  temporary solution is to clean up any long running cached objects that aren't\n  really being used for a while with a cron job.\n- Rate limits on external API's may get hit which could result in all users not\n  being able to request new data if it's not already cached on the server. This\n  will take some trial and error to see what the right combination of\n  client/server caching and rate limiting on the server to avoid hitting limits.\n- I originally wanted to use Nest JS to learn how to use it but I think it's a\n  little overkill for this. The size of the docker image could probably be\n  smaller and the server could be faster using something like\n  [fastify](https://www.fastify.io/).\n\n## Local Development\n\n- We are using [MSW](https://mswjs.io/) during development to intercept API\n  requests from the browser to the server so as to not hit live upstream APIs at\n  all. MSW is great!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahoward2%2Fpersonal-dashboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahoward2%2Fpersonal-dashboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahoward2%2Fpersonal-dashboard/lists"}