{"id":50746970,"url":"https://github.com/zitadel/remix-auth","last_synced_at":"2026-06-10T22:01:39.041Z","repository":{"id":360005609,"uuid":"1248284918","full_name":"zitadel/remix-auth","owner":"zitadel","description":"Official Zitadel auth integration for Remix.","archived":false,"fork":false,"pushed_at":"2026-06-08T13:44:08.000Z","size":882,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T15:27:55.031Z","etag":null,"topics":["auth","authentication","authn","authorization","authz","iam","identity","login","nodejs","remix","sso","typescript","zitadel"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@zitadel/remix-auth","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zitadel.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-24T12:47:00.000Z","updated_at":"2026-06-08T13:44:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zitadel/remix-auth","commit_stats":null,"previous_names":["zitadel/remix-auth"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/zitadel/remix-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fremix-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fremix-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fremix-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fremix-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zitadel","download_url":"https://codeload.github.com/zitadel/remix-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fremix-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34172196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["auth","authentication","authn","authorization","authz","iam","identity","login","nodejs","remix","sso","typescript","zitadel"],"created_at":"2026-06-10T22:01:38.164Z","updated_at":"2026-06-10T22:01:39.035Z","avatar_url":"https://github.com/zitadel.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Remix Auth\n\nA [Remix](https://remix.run/) / [React Router v7](https://reactrouter.com/)\nintegration that provides seamless\nauthentication with multiple providers, session management, and Remix-native\nloader and action patterns.\n\nThis integration brings the power and flexibility of OAuth to Remix 3+\napplications with full TypeScript support, native Fetch API handling, and\nidiomatic Remix patterns for server-side loaders and resource routes.\n\n### Why?\n\nModern web applications require robust, secure, and flexible authentication\nsystems. Integrating OAuth and session management with Remix applications requires careful consideration of\nframework patterns, server-side rendering, and TypeScript integration.\n\nHowever, a direct integration isn't always straightforward. Different types\nof applications or deployment scenarios might warrant different approaches:\n\n- **Resource Route Integration:** OAuth and auth flows operate at the HTTP level, while\n  Remix uses resource routes with `loader` and `action` exports. A proper\n  integration should bridge this gap by providing GET and POST handlers that\n  plug directly into Remix's routing system.\n- **HTTP Request Handling:** Remix 3 uses the native Fetch API, so no\n  request/response conversion is needed. This integration wraps the auth handler\n  with Remix's `LoaderFunctionArgs` and `ActionFunctionArgs` shapes.\n- **Session and Request Lifecycle:** Proper session handling in Remix requires\n  utilities that work with server-side loaders, giving routes access to\n  authentication state without additional boilerplate.\n- **Route Protection:** Many applications need fine-grained authorization\n  beyond simple authentication. `getSession()` provides a clean server-side\n  primitive suitable for protecting loaders and actions.\n\nThis integration, `@zitadel/remix-auth`, aims to provide the flexibility to\nhandle such scenarios. It allows you to leverage the full OAuth provider ecosystem\nwhile maintaining Remix best practices, ultimately leading to a more effective\nand less burdensome authentication implementation.\n\n## Installation\n\nInstall using NPM by using the following command:\n\n```sh\nnpm install @zitadel/remix-auth\n```\n\n## Usage\n\nTo use this integration, call `RemixAuth()` with your authentication configuration\nand export the resulting handlers from your catch-all auth resource route.\n\nFirst, create your auth server module:\n\n```ts\n// app/auth.server.ts\nimport { RemixAuth } from '@zitadel/remix-auth';\nimport Zitadel from '@auth/core/providers/zitadel';\n\nexport const { handlers, getSession } = RemixAuth({\n  providers: [\n    Zitadel({\n      clientId: process.env.ZITADEL_CLIENT_ID,\n      clientSecret: process.env.ZITADEL_CLIENT_SECRET,\n      issuer: process.env.ZITADEL_DOMAIN,\n    }),\n  ],\n  secret: process.env.AUTH_SECRET,\n  trustHost: true,\n});\n\nexport const { GET, POST } = handlers;\n```\n\nThen wire up the resource route:\n\n```ts\n// app/routes/api.auth.$.ts\nexport { GET as loader, POST as action } from '~/auth.server';\n```\n\n#### Using the Authentication System\n\nThe integration provides several functions and hooks for handling\nauthentication:\n\n**Server Utilities:**\n\n- `RemixAuth(config)`: Creates `{ handlers: { GET, POST }, getSession }`\n- `getSession(request)`: Retrieves the current session from a request\n\n**Basic Usage in a Loader:**\n\n```ts\n// app/routes/_index.tsx\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { getSession } from '~/auth.server';\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n  const session = await getSession(request);\n  return { session };\n}\n\nexport default function Index() {\n  const { session } = useLoaderData\u003ctypeof loader\u003e();\n\n  return (\n    \u003cmain\u003e\n      {session ? (\n        \u003c\u003e\n          \u003cp\u003eWelcome, {session.user?.name}\u003c/p\u003e\n          \u003ca href=\"/api/auth/signout\"\u003eSign out\u003c/a\u003e\n        \u003c/\u003e\n      ) : (\n        \u003ca href=\"/api/auth/signin\"\u003eSign in\u003c/a\u003e\n      )}\n    \u003c/main\u003e\n  );\n}\n```\n\n**Protecting a Route:**\n\n```ts\n// app/routes/profile.tsx\nimport { redirect } from 'react-router';\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { getSession } from '~/auth.server';\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n  const session = await getSession(request);\n  if (!session) throw redirect('/api/auth/signin');\n  return { user: session.user };\n}\n```\n\n##### Example: Advanced Configuration with Multiple Providers\n\nThis example shows how to use the integration with multiple OAuth\nproviders and custom session configuration:\n\n```ts\n// app/auth.server.ts\nimport { RemixAuth } from '@zitadel/remix-auth';\nimport Zitadel from '@auth/core/providers/zitadel';\nimport Google from '@auth/core/providers/google';\n\nexport const { handlers, getSession } = RemixAuth({\n  providers: [\n    Zitadel({\n      clientId: process.env.ZITADEL_CLIENT_ID,\n      clientSecret: process.env.ZITADEL_CLIENT_SECRET,\n      issuer: process.env.ZITADEL_DOMAIN,\n    }),\n    Google({\n      clientId: process.env.GOOGLE_CLIENT_ID,\n      clientSecret: process.env.GOOGLE_CLIENT_SECRET,\n    }),\n  ],\n  secret: process.env.AUTH_SECRET,\n  trustHost: true,\n  session: {\n    strategy: 'jwt',\n    maxAge: 30 * 24 * 60 * 60, // 30 days\n  },\n  callbacks: {\n    async jwt({ token, user }) {\n      if (user) (token as any).roles = (user as any).roles;\n      return token;\n    },\n    async session({ session, token }) {\n      (session.user as any).roles = (token as any).roles as\n        | string[]\n        | undefined;\n      return session;\n    },\n  },\n});\n\nexport const { GET, POST } = handlers;\n```\n\n## Known Issues\n\n- **Remix 3 / React Router v7 Required:** This integration targets Remix 3+\n  (which uses React Router v7 under the hood with native Fetch API). Older\n  Remix versions that use Node.js `Request`/`Response` are not supported.\n- **Environment Configuration:** The integration relies on `AUTH_SECRET` and,\n  in many hosting scenarios, `AUTH_TRUST_HOST`. Ensure these are correctly set\n  in your environment for production.\n- **Callback URLs:** OAuth providers must be configured with the correct\n  callback URL: `[origin]/api/auth/callback/[provider]`.\n- **Type Augmentation:** If you attach additional properties (e.g., roles) to\n  the user session object, extend your app's types accordingly so consumers of\n  `session.user` remain type-safe.\n- **Redirect Semantics:** OAuth providers expect real browser navigations during\n  sign-in. The client helpers handle this for you — avoid manual `fetch()` calls\n  to provider endpoints unless you know you need credential/email flows.\n\n## Useful links\n\n- **[Remix / React Router](https://reactrouter.com/):** The framework this\n  integration targets.\n\n## Contributing\n\nIf you have suggestions for how this integration could be improved, or\nwant to report a bug, open an issue — we'd love all and any contributions.\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzitadel%2Fremix-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzitadel%2Fremix-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzitadel%2Fremix-auth/lists"}