{"id":13719691,"url":"https://github.com/hyper63/alternative-stack","last_synced_at":"2025-07-25T09:13:37.433Z","repository":{"id":37525663,"uuid":"479125616","full_name":"hyper63/alternative-stack","owner":"hyper63","description":"A Remix Stack using hyper cloud as a services tier","archived":false,"fork":false,"pushed_at":"2022-09-16T15:59:59.000Z","size":3070,"stargazers_count":17,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-06T10:39:36.399Z","etag":null,"topics":["architect","hyper","hyper-cloud","remix-stack"],"latest_commit_sha":null,"homepage":"https://hyper.io","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/hyper63.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-04-07T19:41:42.000Z","updated_at":"2024-08-19T00:08:28.000Z","dependencies_parsed_at":"2023-01-17T16:01:25.522Z","dependency_job_id":null,"html_url":"https://github.com/hyper63/alternative-stack","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hyper63/alternative-stack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper63%2Falternative-stack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper63%2Falternative-stack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper63%2Falternative-stack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper63%2Falternative-stack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyper63","download_url":"https://codeload.github.com/hyper63/alternative-stack/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper63%2Falternative-stack/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266983523,"owners_count":24016559,"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","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"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":["architect","hyper","hyper-cloud","remix-stack"],"created_at":"2024-08-03T01:00:54.273Z","updated_at":"2025-07-25T09:13:37.410Z","avatar_url":"https://github.com/hyper63.png","language":"TypeScript","readme":"# Alternative Stack\n\n![The Alternative Stack](./docs/alternative-stack.png)\n\nThe Alternative Stack is a [Remix Stacks](https://remix.run/stacks) using\n[Hyper](https://hyper.io) as a services tier\n\nLearn more about [Hyper](https://hyper.io)\n\nLearn more about [Remix Stacks](https://remix.run/stacks).\n\n## Blog Post\n\nCheck out\n[our blog post](https://blog.hyper.io/introducing-the-alternative-stack/) on the\nAlternative Stack\n\n```\nnpx create-remix --template hyper63/alternative-stack\n```\n\n## What's in the stack\n\n- [AWS deployment](https://aws.com) with [Architect](https://arc.codes/)\n- [Hyper Cloud](https://hyper.io) integration via\n  [`hyper-connect`](https://www.npmjs.com/package/hyper-connect)\n- Zero-setup ⚡️ local development using\n  [`hyper nano`](https://github.com/hyper63/hyper/tree/main/images/nano)\n- [Hyper Vision](https://docs.hyper.io/hyper-vision) support, to peer into your\n  hyper services\n- [GitPod integration](https://gitpod.io/) for developing in ephermeral cloud\n  environments\n- [GitHub Actions](https://github.com/features/actions) for deploy on merge to\n  production and staging environments\n- Email/Password Authentication with\n  [cookie-based sessions](https://remix.run/docs/en/v1/api/remix#createcookiesessionstorage)\n- Styling with [Tailwind](https://tailwindcss.com/)\n- End-to-end testing with [Cypress](https://cypress.io)\n- Local third party request mocking with [MSW](https://mswjs.io)\n- Unit testing with [Vitest](https://vitest.dev) and\n  [Testing Library](https://testing-library.com)\n- Code formatting with [Prettier](https://prettier.io)\n- Linting with [ESLint](https://eslint.org)\n- Static Types with [TypeScript](https://typescriptlang.org)\n\nNot a fan of bits of the stack? Fork it, change it, and use\n`npx create-remix --template your/repo`! Make it your own.\n\n## Prerequisites\n\nThis Remix stack sets up a local development stack using\n[`hyper nano`](https://github.com/hyper63/hyper/tree/main/images/nano) ⚡️ an\nin-memory instance of [hyper](https://hyper.io). `hyper nano` works great for\nlocal development or short-lived, ephemeral environments like GitHub Workspaces\nor GitPod\n\n\u003e At hyper, we exclusively develop using short-lived ephemeral environments\n\nIf you choose **_not_** to use `hyper nano`, you will need to create a\n[`hyper cloud application`](https://docs.hyper.io/applications) on\n[hyper cloud](https://dashboard.hyper.io):\n\n- Create a free starter account on [hyper cloud](https://dashboard.hyper.io)\n- Create a free hyper cloud application. Learn more\n  [here](https://docs.hyper.io/applications)\n  - The application should at least have a\n    [hyper data service](https://docs.hyper.io/data-api)\n- Take your application's connection string and use it to set your `HYPER`\n  environment variable in your `.env`, during setup. Learn more\n  [here](https://docs.hyper.io/app-keys)\n\n## Development\n\n- Start dev server:\n\n  ```sh\n  npm run dev\n  ```\n\nThis starts your app in development mode, rebuilding assets on file changes. All\ndata will be persisted to your hyper application based on your `HYPER`\nconnection string environment variable.\n\n### Relevant code:\n\nThis is a pretty simple note-taking app, but it's a good example of how you can\nbuild a full stack app with Hyper and Remix, and deploy it using Architect. The\nmain functionality is creating users, logging in and out, and creating and\ndeleting notes.\n\n- creating users, finding a user, and deleting a user and their data\n  [./app/services/user.server.ts](./app/services/user.server.ts)\n- creating, and deleting notes\n  [./app/services/note.server.ts](./app/services/note.server.ts)\n- user sessions, and verifying them\n  [./app/session.server.ts](./app/session.server.ts)\n\n### Gitpod Integration\n\nThe Alternative Stack comes with support for cloud based development, using\n[GitPod](https://gitpod.io). Just initialize the Alternative Stack using the\nRemix CLI, push to Github, and then open in Gitpod by visiting:\n\n```\nhttps://gitpod.io/#your-repo-url\n```\n\n\u003e You can also use\n\u003e [Gitpod's browser extension](https://www.gitpod.io/docs/browser-extension)\n\nThis will build a containerized cloud environment, install dependencies, and\nstart up your services for you, a complete **sandboxed** environment. We use a\n[GitPod `.gitpod.yml`](https://www.gitpod.io/docs/config-gitpod-file) to set up\nour Cloud environment and expose our services.\n\nBotch a feature and need to wipe the data? Just open a new Gitpod!\n\nNeed to fix a bug? Create an issue and then\n[open the issue in Gitpod](https://www.gitpod.io/docs/context-urls)!\n\nWith Gitpod, you no longer have to maintain a local environment. Just spin up a\nnew one every time!\n\n### Hyper Sevice Vision 🕶\n\nIf you'd like to see what is being stored in your hyper services, you can use\n[Hyper Vision](https://docs.hyper.io/hyper-vision) to peer into your services.\n\nHyper Vision is a hosted, read-only, hyper service explorer that you can use to\nview your services. Just provide Hyper Vision with your application's hyper\nconnection string (`process.env.HYPER`) and it will introspect your services!\n\n\u003e If you're running `hyper nano` locally, you will need to use a proxy to make\n\u003e it accessible on the internet. [ngrok](https://ngrok.com/) is a great tool for\n\u003e this (though if you develop in ephemeral cloud environments like Gitpod, you\n\u003e get this out of the box 😎).\n\n## Clean Architecture With Hyper\n\nHyper embraces the\n[Clean Architecture](https://blog.hyper.io/the-perfect-application-architecture/)\napproach to building software. This means separating side effects from business\nlogic and striving to keep business logic separated from other details of the\napplication.\n\nThis has lots of benefits:\n\n- Business logic is _framework_ agnostic\n- Business logic is _infrastructure_ agnostic\n- Easier to test business logic (unit tests and TypeScript cover most of it!)\n- Separation of concerns\n\n**All of the business logic for this application can be found in\n[./app/services](./app/services)**. Each service receives its side effects via\n[dependency injection](https://martinfowler.com/articles/refactoring-dependencies.html#DependencyInjection)\nwhich are then easy to stub during unit testing.\n\nOur business `models` are simple schemas built on\n[zod](https://github.com/colinhacks/zod) used to validate the correctness of\ndata flowing in and out of our business logic layer.\n\n\u003e You could use anything to validate the contracts with your business logic, I\n\u003e chose `zod` because it's what we use at hyper. `Joi`, `Yup`, there are tons of\n\u003e options out there.\n\nBecause all side effects are injected via dependency injection, the business\nlogic is incredibly easy to test. The business logic is practically fully tested\nusing **just unit tests**. (run `npm run test --coverage` to see for yourself)\n\nYou can also see dependency injection in [./server.ts](./server.ts), which uses\nRemix's\n[`getLoadContext`](https://remix.run/docs/en/v1/other-api/adapter#createrequesthandler)\nto inject our business services and session handling into our `loaders` and\n`actions`, via `context`.\n\nLearn more\n[from our blog post](https://blog.hyper.io/introducing-the-alternative-stack/#cleanarchitecturewithhyper)\n\n## Deployment\n\nThis Remix Stack comes with two GitHub Actions that handle automatically\ndeploying your app to production and staging environments. By default, Arc will\ndeploy to the `us-west-2` region, if you wish to deploy to a different region,\nyou'll need to change your\n[`app.arc`](https://arc.codes/docs/en/reference/project-manifest/aws)\n\nAlternatively, you can set `AWS_REGION` in\n[your GitHub repo's secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)\n\n### Hyper Setup\n\nEach environment will need a hyper cloud application backing it. Since this\nstack has a `staging` and `production` environment, you will need a hyper cloud\napplication for `staging` and then another for `production` (you get 3 hyper\ncloud applications for **free**, and you can always upgrade them later). Learn\nmore [here](https://docs.hyper.io/subscriptions).\n\nOnce the hyper applications have been created, set the `HYPER` environment\nvariable in `production` and `staging` environments using Arc:\n\n```sh\nnpx arc env --add --env staging HYPER cloud://....\nnpx arc env --add --env production HYPER cloud://....\n```\n\n\u003e Alternatively, you can set `HYPER` for `staging` and `production` via\n\u003e [your GitHub repo's secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)\n\u003e as part of CI.\n\u003e [See the `deploy` step in your `deploy` workflow](./.github/workflows/deploy.yml)\n\n### Architect Setup\n\nPrior to your first deployment, you'll need to do a few things:\n\n- [Sign up](https://portal.aws.amazon.com/billing/signup#/start) and login to\n  your AWS account\n\n- Add `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` and `AWS_REGION` to\n  [your GitHub repo's secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets).\n  Go to your AWS\n  [security credentials](https://console.aws.amazon.com/iam/home?region=us-west-2#/security_credentials)\n  and click on the \"Access keys\" tab, and then click \"Create New Access Key\",\n  then you can copy those and add them to your repo's secrets.\n\n- Along with your AWS credentials, you'll also need to give your CloudFormation\n  a `SESSION_SECRET` variable of its own for both staging and production\n  environments, as well as an `ARC_APP_SECRET` for Arc itself.\n\n  ```sh\n  npx arc env --add --env staging ARC_APP_SECRET $(openssl rand -hex 32)\n  npx arc env --add --env staging SESSION_SECRET $(openssl rand -hex 32)\n  npx arc env --add --env production ARC_APP_SECRET $(openssl rand -hex 32)\n  npx arc env --add --env production SESSION_SECRET $(openssl rand -hex 32)\n  ```\n\n  \u003e Alternatively, you can generate and set `ARC_APP_SECRET` and\n  \u003e `SESSION_SECRET` via\n  \u003e [your GitHub repo's secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)\n  \u003e as part of CI.\n  \u003e [See the `deploy` step in your `deploy` workflow](./.github/workflows/deploy.yml)\n\n  If you don't have openssl installed, you can also use\n  [1password](https://1password.com/password-generator) to generate a random\n  secret, just replace `$(openssl rand -hex 32)` with the generated secret.\n\n### Where do I find my CloudFormation?\n\nYou can find the CloudFormation template that Architect generated for you in the\nsam.yaml file.\n\nTo find it on AWS, you can search for\n[CloudFormation](https://console.aws.amazon.com/cloudformation/home) (make sure\nyou're looking at the correct region!) and find the name of your stack (the name\nis a PascalCased version of what you have in `app.arc`, so by default it's\nAlternativeStackStaging and AlternativeStackProduction) that matches what's in\n`app.arc`, you can find all of your app's resources under the \"Resources\" tab.\n\n## GitHub Actions\n\nWe use GitHub Actions for continuous integration and deployment. Anything that\ngets into the `main` branch will be deployed to production after running\ntests/build/etc. Anything in the `dev` branch will be deployed to staging.\n\n## Testing\n\n### Cypress\n\nWe use Cypress for our End-to-End tests in this project. You'll find those in\nthe `cypress` directory. As you make changes, add to an existing file or create\na new file in the `cypress/e2e` directory to test your changes.\n\nWe use [`@testing-library/cypress`](https://testing-library.com/cypress) for\nselecting elements on the page semantically.\n\nTo run these tests in development, run `npm run test:e2e:dev` which will start\nthe dev server for the app as well as the Cypress client. Make sure the database\nis running in docker as described above.\n\nWe have a utility for testing authenticated features without having to go\nthrough the login flow:\n\n```ts\ncy.login();\n// you are now logged in as a new user\n```\n\nWe also have a utility to auto-delete the user at the end of your test. Just\nmake sure to add this in each test file:\n\n```ts\nafterEach(() =\u003e {\n  cy.cleanupUser();\n});\n```\n\nThat way, we can keep your local db clean and keep your tests isolated from one\nanother.\n\n### Vitest\n\nFor lower level tests of utilities and individual components, we use `vitest`.\nWe have DOM-specific assertion helpers via\n[`@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\neditor to get a really great in-editor experience with type checking and\nauto-complete. To run type checking across the whole project, run\n`npm run 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.\nIt's recommended to install an editor plugin (like the\n[VSCode Prettier plugin](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode))\nto get auto-formatting on save. There's also a `npm run format` script you can\nrun to format all files in the project.\n\n## Thank You\n\nWe at hyper are very excited about Remix and Remix stacks. A huge shout out to\nthe [Remix team](https://remix.run/) and to\n[Kent C. Dodds](https://kentcdodds.com/) for showing us this cool new feature.\n\nAlso thank you to the all the maintainers of open source projects that we use.\nIn particular:\n\n- [Architect](https://arc.codes)\n- [Zod](https://github.com/colinhacks/zod)\n- [Ramda](https://ramdajs.com/)\n- [Vitest](https://vitest.dev/)\n- [Tailwind](https://tailwindcss.com/)\n\nand many many more!\n","funding_links":[],"categories":["Starter"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyper63%2Falternative-stack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyper63%2Falternative-stack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyper63%2Falternative-stack/lists"}