1# Design Principles
2
3The purpose of Cargo is to formalize a canonical Rust workflow, by automating
4the standard tasks associated with distributing software. Cargo simplifies
5structuring a new project, adding dependencies, writing and running unit
6tests, and more.
7
8Cargo is not intended to be a general-purpose build tool. Ideally, it should
9be easy to integrate it within another build tool, though admittedly that is
10not as seamless as desired.
11
12## Stability and compatibility
13
14### Backwards compatibility
15
16Cargo strives to remain backwards compatible with projects created in previous
17versions. The CLI interface also strives to remain backwards compatible, such
18that the commands and options behave the same. That being said, changes in
19behavior, and even outright breakage are sometimes done in limited situations.
20The following outlines some situations where backwards-incompatible changes are
21made:
22
23* Anything that addresses a security concern.
24* Dropping support for older platforms and tooling. Cargo follows the Rust
25  [tiered platform support].
26* Changes to resolve possibly unsafe or unreliable behavior.
27
28None of these changes should be taken lightly, and should be avoided if
29possible, or possibly with some transition period to alert the user of the
30potential change.
31
32Behavior is sometimes changed in ways that have a high confidence that it
33won't break existing workflows. Almost every change carries this risk, so it
34is often a judgment call balancing the benefit of the change with the
35perceived possibility of its negative consequences.
36
37At times, some changes fall in the gray area, where the current behavior is
38undocumented, or not working as intended. These are more difficult judgment
39calls. The general preference is to balance towards avoiding breaking existing
40workflows.
41
42Support for older registry APIs and index formats may be dropped, if there is
43high confidence that there aren't any active registries that may be affected.
44This has never (to my knowledge) happened so far, and is unlikely to happen in
45the future, but remains a possibility.
46
47In all of the above, a transition period may be employed if a change is known
48to cause breakage. A warning can be issued to alert the user that something
49will change, and provide them with an alternative to resolve the issue
50(preferably in a way that is compatible across versions if possible).
51
52Cargo is only expected to work with the version of the related Rust tools
53(`rustc`, `rustdoc`, etc.) that it is released with. As a matter of choice,
54the latest nightly works with the most recent stable release, but that is
55mostly to accommodate development of Cargo itself, and should not be expected
56by users.
57
58### Forwards compatibility
59
60Additionally, Cargo strives a limited degree of *forwards compatibility*.
61Changes should not egregiously prevent older versions from working. This is
62mostly relevant for persistent data, such as on-disk files and the registry
63interface and index. It also applies to a lesser degree to the registry API.
64
65Changes to `Cargo.lock` require a transition time, where the new format is not
66automatically written when the lock file is updated. The transition time
67should not be less than 6 months, though preferably longer. New projects may
68use the new format in a shorter time frame.
69
70Changes to `Cargo.toml` can be made in any release. This is because the user
71must manually modify the file, and opt-in to any new changes. Additionally,
72Cargo will usually only issue a warning about new fields it doesn't
73understand, but otherwise continue to function.
74
75Changes to cache files (such as artifacts in the `target` directory, or cached
76data in Cargo's home directory) should not *prevent* older versions from
77running, but they may cause older versions to recreate the cache, which may
78result in a performance impact.
79
80Changes to the registry index should not prevent older versions from working.
81Generally, older versions ignore new fields, so the format should be easily
82extensible. Changes to the format or interpretation of existing fields should
83be done very carefully to avoid preventing older versions of Cargo from
84working. In some cases, this may mean that older versions of Cargo will not be
85able to *select* a newly published crate, but it shouldn't prevent them from
86working at all. This level of compatibility may not last forever, but the
87exact time frame for such a change has not yet been decided.
88
89The registry API may be changed in such a way to prevent older versions of
90Cargo from working. Generally, compatibility should be retained for as long as
91possible, but the exact length of time is not specified.
92
93## Simplicity and layers
94
95Standard workflows should be easy and consistent. Each knob that is added has
96a high cost, regardless if it is intended for a small audience. Layering and
97defaults can help avoid the surface area that the user needs to be concerned
98with. Try to avoid small functionalities that may have complex interactions
99with one another.
100
101[tiered platform support]: https://doc.rust-lang.org/nightly/rustc/platform-support.html
102