{"id":26260457,"url":"https://github.com/evanbacon/expo-router-spotify","last_synced_at":"2025-10-17T23:24:13.103Z","repository":{"id":282102754,"uuid":"947494922","full_name":"EvanBacon/expo-router-spotify","owner":"EvanBacon","description":"Spotify API demo built with Universal React Server Components in Expo Router","archived":false,"fork":false,"pushed_at":"2025-03-12T19:51:26.000Z","size":832,"stargazers_count":128,"open_issues_count":1,"forks_count":11,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-30T13:41:34.831Z","etag":null,"topics":["demo","expo","mobile","oauth","react-native","react-server-components","template"],"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/EvanBacon.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":"2025-03-12T19:23:36.000Z","updated_at":"2025-03-30T04:12:01.000Z","dependencies_parsed_at":"2025-03-12T20:41:25.666Z","dependency_job_id":null,"html_url":"https://github.com/EvanBacon/expo-router-spotify","commit_stats":null,"previous_names":["evanbacon/expo-router-spotify"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvanBacon%2Fexpo-router-spotify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvanBacon%2Fexpo-router-spotify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvanBacon%2Fexpo-router-spotify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvanBacon%2Fexpo-router-spotify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EvanBacon","download_url":"https://codeload.github.com/EvanBacon/expo-router-spotify/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247492513,"owners_count":20947544,"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":["demo","expo","mobile","oauth","react-native","react-server-components","template"],"created_at":"2025-03-13T23:14:57.660Z","updated_at":"2025-10-17T23:24:13.003Z","avatar_url":"https://github.com/EvanBacon.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Expo Router Spotify Demo\n\nThis is a demo project that uses [React Server Components in Expo Router](https://docs.expo.dev/guides/server-components/) to securely authenticate and make requests to the Spotify API.\n\nhttps://github.com/user-attachments/assets/8f9740eb-2ee2-4b26-b6cb-93b0b3a8461b\n\nData is fetched at the edge, rendered on the server, and streamed back to the client (iOS, Android, and web).\n\nThis template demonstrates how you can setup a cookies-like system for making the client authentication results automatically available to the server.\n\nServer action results are also cached in-memory for 60 seconds to demonstrate reducing the number of requests to the server.\n\nThis demo requires environment variables in the `.env` file. You can get these in the [Spotify developer portal](https://developer.spotify.com/dashboard).\n\n```\nEXPO_PUBLIC_SPOTIFY_CLIENT_ID=xxx\nSPOTIFY_CLIENT_SECRET=xxx\n```\n\nThe client secret will never be available in the client bundle for any platform and will only ever be used on the server. This ensures malicious actors cannot access your API.\n\nTry it in the browser with EAS Hosting https://rsc-spotify.expo.app/ (pending Spotify API approval)\n\n## Authentication\n\nI use a global provider to setup [expo-auth-session](https://docs.expo.dev/guides/authentication/#spotify) then store the results using a `localStorage` polyfill. The code exchange is then performed securely in a React server function with the client secret, this gives us a long-lived access token. \n\nThe request object is sent to server functions which are wrapped with a helper layer that ensures the access token is refreshed when it becomes invalid, this all happens behind the scenes which is pretty nice and scales well across all requests.\n\nThis ability to wrap server calls on both the client and server-side in a composable way is a super powerful concept. Being able to abstract away the entire authentication system across all platforms and frontend/backend is magical. Likely a lot of untapped potential here.\n\n## Data fetching\n\nData is fetched in the server and passed to client components for rendering interactive elements. Using server actions makes these sections composable so we can use them in different parts of the app. For example, search is inlined on native but uses a standalone route on web.\n\nTo memoize the React Server Function calls, I've enabled React compiler. This ensures server calls only happen when the arguments of a server function are called.\n\n## UI\n\nFor the components, I'm using this template https://github.com/EvanBacon/expo-router-forms-components. I've added some header animations on native to brighten up the app and give it some personality.\n\nFor web, I use a custom header that looks and acts more like what you'd expect from a website. The authentication modal uses a customized version of vaul that works better in desktop screens.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanbacon%2Fexpo-router-spotify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevanbacon%2Fexpo-router-spotify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanbacon%2Fexpo-router-spotify/lists"}