Elm has well thought out versioning rules. Because of Elm's strong type system their package manager could (can?) enforce the rules. They already have a CLI command to generate a report of what's changed between any two versions of a module.
For example, to compare changes between elm-lang/core's module 3.0.0 vs 4.0.0, run: elm-package diff elm-lang/core 3.0.0 4.0.0
which will produce:
Comparing elm-lang/core 3.0.0 to 4.0.0...
This is a MAJOR change.
------ Added modules - MINOR ------
Platform
Platform.Cmd
Platform.Sub
Process
------ Removed modules - MAJOR ------
Graphics.Collage
Graphics.Element
Graphics.Input
Graphics.Input.Field
Keyboard
Mouse
Signal
Text
Touch
Trampoline
Transform2D
Window
------ Changes to module Basics - MINOR ------
Added:
type Never
------ Changes to module Date - MINOR ------
Added:
now : Task.Task x Date.Date
------ Changes to module Debug - MAJOR ------
Removed:
trace : String -> Graphics.Collage.Form -> Graphics.Collage.Form
watch : String -> a -> a
watchSummary : String -> (a -> b) -> a -> a
------ Changes to module Dict - MINOR ------
Added:
merge : (comparable -> a -> result -> result) -> (comparable -> a -> b -> result -> result) -> (comparable -> b -> result -> result) -> Dict.Dict comparable a -> Dict.Dict comparable b -> result -> result
------ Changes to module Random - MAJOR ------
Added:
step : Random.Generator a -> Random.Seed -> (a, Random.Seed)
Changed:
- generate : Random.Generator a -> Random.Seed -> (a, Random.Seed)
+ generate : (a -> msg) -> Random.Generator a -> Platform.Cmd.Cmd msg
------ Changes to module Task - MAJOR ------
Added:
type alias Task err ok = Platform.Task err ok
perform : (x -> msg) -> (a -> msg) -> Task.Task x a -> Platform.Cmd.Cmd msg
Removed:
type Task x a
type ThreadID
sleep : Task.Time -> Task.Task x ()
spawn : Task.Task x a -> Task.Task y Task.ThreadID
------ Changes to module Time - MAJOR ------
Added:
now : Task.Task x Time.Time
Removed:
delay : Time.Time -> Signal.Signal a -> Signal.Signal a
fps : number -> Signal.Signal Time.Time
fpsWhen : number -> Signal.Signal Bool -> Signal.Signal Time.Time
since : Time.Time -> Signal.Signal a -> Signal.Signal Bool
timestamp : Signal.Signal a -> Signal.Signal (Time.Time, a)
Changed:
- every : Time.Time -> Signal.Signal Time.Time
+ every : Time.Time -> (Time.Time -> msg) -> Platform.Sub.Sub msg
That is very damn cool. Wish we had this in node.js land. See the Elm Package Manager documentation here.