In our approach to software development, we aim to achieve the following goals for major releases:
We introduce new features into the current release with a future flag in remix.config that looks something like unstable_someFeature
.
/** @type {import('@remix-run/dev').AppConfig} */
export default {
future: {
unstable_someFeature: true,
},
};
Once an unstable feature reaches a stable state, we remove the special prefix and include the feature in the next minor release. At this point, the API's structure remains consistent throughout subsequent minor releases.
This approach allows us to refine the API collaboratively with early adopters, incorporating necessary changes in the unstable phase without affecting all users. The stable releases then benefit from these improvements without disruptions.
If you're utilizing features labeled with unstable_*
flags, it's crucial to review the release notes for each minor release. This is because the behavior or structure of these features might evolve. Your feedback during this phase is invaluable in enhancing the feature before the final release!
When we introduce breaking changes, we do so within the context of the current major version, and we hide them behind future flags. For instance, if we're in v2
, a breaking change might be placed under a future flag named v3_somethingDifferent
.
/** @type {import('@remix-run/dev').AppConfig} */
export default {
future: {
v3_someFeature: true,
},
};
v2
behavior and the new v3_somethingDifferent
behavior coexist simultaneously.v3_*
future flags are enabled, transitioning to v3
should ideally not necessitate any changes to your codebase.unstable_*
flags. These might undergo modifications during minor releases. Once they become v3_*
future flags, the corresponding API is set and won't change further.Our development strategy focuses on gradual feature adoption and seamless version upgrades for major releases. This empowers developers to selectively integrate new features, avoiding the need for extensive code adjustments during version transitions. By introducing features through unstable_*
flags, we refine the API collaboratively with early adopters while ensuring stable releases benefit from enhancements. Through careful management of breaking changes using v3_*
flags, we provide the flexibility to adopt changes incrementally, facilitating a smoother transition between major versions. While this increases the complexity for developing Remix the framework, this developer-centric approach greatly simplifies application development with Remix, ultimately leading to improved software quality and (hopefully!) developer satisfaction.