All Remix development happens here on GitHub. There are two main branches in this repository that you should be aware of:
main
- This is the stable line. Code in this branch should always pass all the tests. Hot fixes may be pushed directly to this branch without appearing indev
. Docs on the website reflect this branch.dev
- This is where most development happens. When hot fix commits land inmain
they are merged into this branch. Feature branches are based on this branch and are merged in as they are completed.
We currently use yarn
(version 1) to
develop Remix. But don't get too attached to it. We'll be migrating to npm 7
soon.
# install everything
yarn install
# run the build
yarn build
# run the tests
yarn test
# run the tests for a specific package
yarn test react
# run the tests in watch mode
yarn test react --watch
New releases should be created from release branches originating from the dev
branch. To simplify this process, use the release.js
Node script.
# Ensure you are on the dev branch
git checkout dev
# This command will create a new release branch, merge all changes from main, and
# create a prerelease tag.
yarn release start patch|minor|major
# At this point you can push to GitHub...
git push origin/release-<version> --follow-tags
# ...then publish the pre-release by creating a release in the GitHub UI. Don't
# forget to check the pre-release checkbox!
# If there are any issues with the pre-release, fix the bugs and commit directly
# to the release branch. You can iterate with a new pre-release with the following # command, then publish via GitHub the same as before.
yarn release bump
# Once all tests have passed and the release is ready to be made stable, the following
# command will create a new stable release tag, merge changes back into the dev branch,
# and prompt you to push the changes and tags to GitHub
yarn release finish
git push origin/release-<version> --follow-tags
Once the release is finished, you should see tests run in GitHub actions. Assuming there are no issues (you should also run tests locally before pushing) you can trigger publishing by creating a new release in the GitHub UI, this time using the stable release tag.
After the release process is complete, be sure to merge the release branch back into dev
and main
and push both branches to GitHub.
All packages are published together except for create-remix
, which is
versioned and published separately. To publish create-remix
, run the build and
publish it manually.
yarn build
npm publish build/node_modules/create-remix
Experimental releases and hot-fixes do not need to be branched off of dev
.
Experimental releases can be branched from anywhere as they are not intended for
general use. Hot-fixes are typically applied directly to main. In either case,
the release process here is a bit simpler:
# for experimental releases:
git checkout -b release/experimental
yarn run version experimental
yarn run publish
## clean up
git checkout <previous-branch>
git branch -d release/experimental
git push origin --delete release/experimental
# for hot-fix:
git checkout main
## fix changes and commit
git add .
git commit -m "fix: squashed a super gnarly bug"
## version + publish
yarn run version patch
yarn run publish
This repository supports handful of environment variables to streamline the local development/testing process.
REMIX_DEBUG
By default, the Remix rollup
build will strip any console.debug
calls to avoid cluttering up the console during application usage. These console.debug
statements can be preserved by setting REMIX_DEBUG=true
during your local build.
REMIX_DEBUG=true yarn watch
REMIX_LOCAL_DEV_OUTPUT_DIRECTORY
When developing Remix locally, you often need to go beyond unit/integration tests and test your changes in a local Remix application. The easiest way to do this is to run your local Remix build and use this environment variable to direct rollup
to write the output files directly into the local Remix application's node_modules
folder. Then you just need to restart your local Remix application server to pick up the changes.
# Tab 1 - create an run a local remix application
npx create-remix
cd my-remix-app
npm run dev
# Tab 2 - remix repository
REMIX_LOCAL_DEV_OUTPUT_DIRECTORY=../my-remix-app yarn watch
Now - any time you make changes in the Remix repository, they will be written out to the appropriate locations in ../my-remix-app/node_modules
and you can restart the npm run dev
command to pick them up 🎉.
The transition manager is a complex and heavily async bit of logic that is foundational to Remix's ability to manage data loading, submission, error handling, and interruptions. Due to the user-driven nature of interruptions we don't quite believe it can be modeled as a finite state machine, however we have modeled some of the happy path flows below for clarity.
Note: This does not depict error or interruption flows
graph LR
%% <Link> transition
idle -->|link clicked| loading/normalLoad
idle -->|form method=get| submitting/loaderSubmission
idle -->|form method=post| submitting/actionSubmission
idle -->|fetcher action redirects| loading/fetchActionRedirect
subgraph "<Link> transition"
loading/normalLoad -->|loader redirected| loading/normalRedirect
loading/normalRedirect --> loading/normalRedirect
end
loading/normalLoad -->|loaders completed| idle
loading/normalRedirect -->|loaders completed| idle
subgraph "<Form method=get>"
submitting/loaderSubmission -->|loader redirected| loading/loaderSubmissionRedirect
loading/loaderSubmissionRedirect --> loading/loaderSubmissionRedirect
end
submitting/loaderSubmission -->|loaders completed| idle
loading/loaderSubmissionRedirect -->|loaders completed| idle
subgraph "<Form method=post>"
submitting/actionSubmission -->|action returned| loading/actionReload
submitting/actionSubmission -->|action redirected| loading/actionRedirect
loading/actionReload -->|loader redirected| loading/actionRedirect
loading/actionRedirect --> loading/actionRedirect
end
loading/actionReload -->|loaders completed| idle
loading/actionRedirect -->|loaders completed| idle
subgraph "Fetcher action redirect"
loading/fetchActionRedirect --> loading/fetchActionRedirect
end
loading/fetchActionRedirect -->|loaders completed| idle
Note: This does not depict error or interruption flows, nor the ability to re-use fetchers once they've reached idle/done
.
graph LR
idle/init -->|"load"| loading/normalLoad
idle/init -->|"submit (get)"| submitting/loaderSubmission
idle/init -->|"submit (post)"| submitting/actionSubmission
subgraph "Normal Fetch"
loading/normalLoad -.->|loader redirected| T1{{transition}}
end
loading/normalLoad -->|loader completed| idle/done
T1{{transition}} -.-> idle/done
subgraph "Loader Submission"
submitting/loaderSubmission -.->|"loader redirected"| T2{{transition}}
end
submitting/loaderSubmission -->|loader completed| idle/done
T2{{transition}} -.-> idle/done
subgraph "Action Submission"
submitting/actionSubmission -->|action completed| loading/actionReload
submitting/actionSubmission -->|action redirected| loading/actionRedirect
loading/actionRedirect -.-> T3{{transition}}
loading/actionReload -.-> |loaders redirected| T3{{transition}}
end
T3{{transition}} -.-> idle/done
loading/actionReload --> |loaders completed| idle/done
classDef transition fill:lightgreen;
class T1,T2,T3 transition;