{"id":27724399,"url":"https://github.com/jaykaycodes/remix-chop-suey-stack","last_synced_at":"2025-04-27T16:02:38.922Z","repository":{"id":37526022,"uuid":"488832873","full_name":"jaykaycodes/remix-chop-suey-stack","owner":"jaykaycodes","description":"Remix+EdgeDB+Tailwind+Fly.io=🖤","archived":false,"fork":false,"pushed_at":"2023-01-24T08:07:55.000Z","size":2594,"stargazers_count":72,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-19T17:24:18.502Z","etag":null,"topics":["edgedb","flyio","react","remix","remix-stack","tailwindcss"],"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/jaykaycodes.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-05T04:37:42.000Z","updated_at":"2025-01-12T17:17:04.000Z","dependencies_parsed_at":"2023-02-13T19:16:52.472Z","dependency_job_id":null,"html_url":"https://github.com/jaykaycodes/remix-chop-suey-stack","commit_stats":null,"previous_names":["jaykaycodes/remix-chop-suey-stack"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaykaycodes%2Fremix-chop-suey-stack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaykaycodes%2Fremix-chop-suey-stack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaykaycodes%2Fremix-chop-suey-stack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaykaycodes%2Fremix-chop-suey-stack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaykaycodes","download_url":"https://codeload.github.com/jaykaycodes/remix-chop-suey-stack/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251166191,"owners_count":21546172,"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":["edgedb","flyio","react","remix","remix-stack","tailwindcss"],"created_at":"2025-04-27T16:02:37.874Z","updated_at":"2025-04-27T16:02:38.913Z","avatar_url":"https://github.com/jaykaycodes.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./public/assets/soad.webp\" width=\"100%\" /\u003e\n  \u003ch1 align=\"center\"\u003eRemix Chop Suey Stack\u003c/h1\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nForked from \u003ca href=\"https://github.com/rphlmr/supa-fly-stack\"\u003eSupa Fly Stack\u003c/a\u003e.\n\u003cbr /\u003eLearn more about \u003ca href=\"https://remix.run/stacks\"\u003eRemix Stacks\u003c/a\u003e.\n\u003c/p\u003e\n\n## Quickstart\n```\nnpx create-remix --template jkcorrea/remix-chop-suey-stack\n```\n\n## What's in it?\n\nThe hits:\n- [EdgeDB](https://www.edgedb.com/) newfangled graph-relational database\n- [Fly.io](https://fly.io) app deployment\n- [TailwindCSS](https://tailwindcss.com/) for styling, plus\n  - [HeadlessUI](https://headlessui.dev/)\n  - [DaisyUI](https://daisyui.com/)\n- [Clerk](https://clerk.dev/) for simple auth\n- [TypeScript](https://typescriptlang.org), [Prettier](https://prettier.io), [ESLint](https://eslint.org)\n  - w/ my opinionated configs :)\n\nBonus tracks:\n- Test/Release\n  - [Vitest](https://vitest.dev) - unit testing\n  - [Cypress](https://cypress.io) - e2e testing\n  - [MSW](https://mswjs.io) - mock network requests\n  - [Testing Library](https://testing-library.com) - test helpers\n  - [GitHub Actions](https://github.com/features/actions) for deploy on merge to production and staging environments\n- [Zod](https://github.com/colinhacks/zod) + [Remix Params Helper](https://github.com/kiliman/remix-params-helper) - client \u0026 server form validation\n- [React Hot Toast](https://react-hot-toast.com/) - toast notification manager\n- [React Icons](https://react-icons.github.io/react-icons) for easy, tree-shakable icon sets\n- [lodash-es](https://www.npmjs.com/package/lodash-es) - tree-shakable lodash\n- [Tiny Invariant](https://github.com/alexreardon/tiny-invariant) - nice little helper for use in loaders \u0026 actions\n- [Remix Utils](https://github.com/sergiodxa/remix-utils) - various remix helpers\n- Healthcheck endpoint for [Fly backups region fallbacks](https://fly.io/docs/reference/configuration/#services-http_checks)\n\nNot a fan of bits of the stack? Fork it, change it, and use `npx create-remix --template your/repo`! Make it your own.\n\n### Alternatives from the community\nIf you want to try out EdgeDB and Remix but don't like this particular stack, check out these amazing starters:\n- [edgedb/remix](https://github.com/edgedb/remix)\n- [jacob-ebey/remix-edgedb](https://github.com/jacob-ebey/remix-edgedb)\n\n## Why?\n\nI run my startup on [Redwood](https://redwoodjs.com/) + [Supabase](https://supabase.com/) + [Prisma](https://www.prisma.io/). All great projects that I still recommend, but a few things have been paining me:\n- Prisma can feel janky. Migrations occasionally get out of sync, rollbacks are a mess, schemas aside from `public` aren't supported in migrations, generated queries can start to suck for complex logic.\n- Supabase, as of today, requires a minor in SQL to get shit done (though, [I do agree](https://twitter.com/jkcorrea_/status/1507155640635981844?s=20\u0026t=c1JQQpk2_ZtnIB3-2xHRiA) it is the right approach, I just don't have time to think about DB management right now)\n- My Redwood codebase got a bit bloated. There's more \"state\" in the system than I'd like, making it difficult to add new code without breaking old code. I didn't make use of many of the niceties of Redwood (Cells, Storybook, tests, etc), and so have a lot of bloat for no reason in the project now.\n\nMy thought is that EdgeDB will take care of the shaky migration + SQL management problems, while Remix may help me reduce the state \u0026 logic to reason about between the front \u0026 back ends.\n\nIt ended up being a lot of exploratory work to get all these technologies working together since they're all fairly new, so I figured I should package it up as a template while I'm at it 🤠\n\n\n\u003e PRO TIP: For extra productivity, the author recommends listening to [System of a Down](https://open.spotify.com/playlist/4pfHVoX09Ej6rzFjsBnXfg?si=7cea59c42d234ade) while developing on this stack 🤘\n\n## TODO\n\na.k.a. things that will never get done\n\n- [ ] Deploy to Fly w/ EdgeDB (\u0026 document)\n- [ ] Database dev/test seeds\n- [ ] Setup some actual unit tests\n- [ ] Mock auth (so we don't have to create/delete users on the real Clerk api)\n- [ ] Consider moving over to [Playwright](https://playwright.dev/) for e2e tests\n\n## Setup\n\n### EdgeDB\n\nFirst install the cli via the [EdgeDB installation guide](https://www.edgedb.com/docs/guides/quickstart), then in this project directory run (the initializer prompts to do this for you):\n\n  ```sh\n  edgedb project init # Initialize a local db instance\n  yarn generate:edgeql # Generate the query builder\n  ```\n\n### Clerk Auth\n\nSetup an account at [Clerk.dev](https://clerk.dev) to your liking. When ready, copy the relevant API keys into your `.env`.\n\n## Development\n\nThis starts your app in development mode, rebuilding assets on file changes.\n\n```sh\nyarn dev\n```\n\n### Migrations\n\nWhen [adding migrations](https://www.edgedb.com/docs/guides/migrations/index), you'll want to re-generate your EdgeDB query builder with a `yarn edgedb-js --output-file ./app/db/edgeql --force-overwrite`. Or, simply apply your migrations via:\n\n```sh\nyarn db:migrate # will apply migration AND regenerate the query builder\n```\n\n### Relevant Files\n\nThis is a pretty simple CRUD app, but it's a good example of how you can build a full stack app with Prisma, Supabase and Remix. The main functionality is creating users, logging in and out (handling access and refresh tokens + refresh on expire), and creating and deleting notes.\n\n- DB\n  - `app/db/db.server.ts` - initializes the EdgeDB client\n  - `app/db/edgeql/` - contains the [generated EdgeQL](https://www.edgedb.com/docs/clients/01_js/generation) query builder.\n  - `app/models/` - abstracts away EdgeQL queries to keep loaders/actions simple\n  - `dbschema/` - contains your EdgeQL schema \u0026 migrations\n- Auth\n  - `app/routes/__auth` - login \u0026 signup pages, wrapped by a Remix layout route. Clerk makes auth really simple.\n  - `app/settings` - I wanted users to have a unified settings page for everything account + non-account related, so this shows how to do that with Clerk components\n- App\n  - `app/__app` - Realizing this is a poor naming choice now. Basically just wanted to demo some simple CRUD with toasts \u0026 loading state transitions.\n- Test\n  - `cypress/` - e2e tests live here\n  - `mocks/` - not yet implemented, but could use this to mock out db/3rd-party requests (e.g. mocking auth without connecting to Clerk)\n  - TODO: implement some unit tests to demo vitest.\n\n## Deployment\n\n\u003e Do what you know if you are a Fly.io expert.\n\n\u003e NOTE: Deploying EdgeDB is left as [an exercise to the reader](https://www.edgedb.com/docs/guides/deployment/index). I have not flushed out the best way to deploy it yet and it seems the EdgeDB maintainers have plans for a cloud-hosted version of it coming soon, so I'm waiting for that. In the meantime, you'll have to host your own and supply the `EDGEDB_DSN` to your Fly app.\n\nThis Remix Stack comes with GitHub Actions that automatically deploy your app to production and staging environments on Fly.\n\nPrior to your first deployment, you'll need to do a few things:\n\n- [Install Fly](https://fly.io/docs/getting-started/installing-flyctl/)\n\n- Sign up and log in to Fly\n\n  ```sh\n  fly auth signup\n  ```\n\n  \u003e **Note:** If you have more than one Fly account, ensure that you are signed into the same account in the Fly CLI as you are in the browser. In your terminal, run `fly auth whoami` and ensure the email matches the Fly account signed into the browser.\n\n- Create two apps on Fly, one for staging and one for production:\n\n  ```sh\n  fly create remix-chop-suey-stack\n  fly create remix-chop-suey-stack-staging\n  ```\n\n  - Initialize Git.\n\n  ```sh\n  git init\n  ```\n\n- Create a new [GitHub Repository](https://repo.new), and then add it as the remote for your project. **Do not push your app yet!**\n\n  ```sh\n  git remote add origin \u003cORIGIN_URL\u003e\n  ```\n\n- Add a `FLY_API_TOKEN` to your GitHub repo. To do this, go to your user settings on Fly and create a new [token](https://web.fly.io/user/personal_access_tokens/new), then add it to [your repo secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) with the name `FLY_API_TOKEN`.\n\n- Add your other secrets from `.env` to your Fly app. You can do this with a command similar to:\n\n  ```sh\n  # staging\n  fly secrets set CLERK_FRONTEND_API=\"CLERK_FRONTEND_API\" --app remix-chop-suey-stack-staging\n  fly secrets set CLERK_API_KEY=\"CLERK_API_KEY\" --app remix-chop-suey-stack-staging\n  fly secrets set CLERK_JWT_KEY=\"CLERK_JWT_KEY\" --app remix-chop-suey-stack-staging\n  fly secrets set EDGEDB_DSN=\"EDGEDB_DSN\" --app remix-chop-suey-staging-stack # See above note about deploying EdgeDB\n\n  # production\n  fly secrets set CLERK_FRONTEND_API=\"CLERK_FRONTEND_API\" --app remix-chop-suey-stack\n  fly secrets set CLERK_API_KEY=\"CLERK_API_KEY\" --app remix-chop-suey-stack\n  fly secrets set CLERK_JWT_KEY=\"CLERK_JWT_KEY\" --app remix-chop-suey-stack\n  fly secrets set EDGEDB_DSN=\"EDGEDB_DSN\" --app remix-chop-suey-stack # See above note about deploying EdgeDB\n  ```\n\n\nNow that everything is set up you can commit and push your changes to your repo. Every commit to your `main` branch will trigger a deployment to your production environment, and every commit to your `dev` branch will trigger a deployment to your staging environment.\n\n## GitHub Actions\n\nWe use GitHub Actions for continuous integration and deployment. Anything that gets into the `main` branch will be deployed to production after running tests/build/etc. Anything in the `dev` branch will be deployed to staging.\n\n👉 **You have to add some env secrets for cypress.** 👈\n\nAdd the same secrets as above to your GitHub actions (https://docs.github.com/en/actions/security-guides/encrypted-secrets).\n\n## Testing\n\n### Cypress\n\nWe use Cypress for our End-to-End tests in this project. You'll find those in the `cypress` directory. As you make changes, add to an existing file or create a new file in the `cypress/e2e` directory to test your changes.\n\nWe use [`@testing-library/cypress`](https://testing-library.com/cypress) for selecting elements on the page semantically.\n\nTo run these tests in development, complete your `.env` and run `yarn test:e2e:dev` which will start the dev server for the app as well as the Cypress client. Make sure the database is running in docker as described above.\n\nWe also have a utility to auto-delete the user at the end of your test. Just make sure to add this in each test file:\n\n```ts\nafterEach(() =\u003e {\n  cy.teardownAuth();\n});\n```\n\nThat way, we can keep your test db clean and keep your tests isolated from one another.\n\n### Vitest\n\nFor lower level tests of utilities and individual components, we use `vitest`. We have DOM-specific assertion helpers via [`@testing-library/jest-dom`](https://testing-library.com/jest-dom).\n\n### Type Checking\n\nThis project uses TypeScript. It's recommended to get TypeScript set up for your editor to get a really great in-editor experience with type checking and auto-complete. To run type checking across the whole project, run `yarn typecheck`.\n\n### Linting\n\nThis project uses ESLint for linting. That is configured in `.eslintrc.js`.\n\n### Formatting\n\nWe use [Prettier](https://prettier.io/) for auto-formatting in this project. It's recommended to install an editor plugin (like the [VSCode Prettier plugin](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)) to get auto-formatting on save. There's also a `yarn format` script you can run to format all files in the project.\n\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaykaycodes%2Fremix-chop-suey-stack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaykaycodes%2Fremix-chop-suey-stack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaykaycodes%2Fremix-chop-suey-stack/lists"}