Skip Navigation

How do you balance rapid iteration and merging/upgrading?

More specifically, I'm thinking about two different modes of development for a library (private to the company) that's already relied upon by other libraries and applications:

  1. Rapidly develop the library "in isolation" without being slowed down by keeping all of the users in sync. This causes more divergence and merge effort the longer you wait to upgrade users.
  2. Make all changes in lock-step with users, keeping everyone in sync for every change that is made. This will be slower and might result in wasted work if experimental changes are not successful.

As a side note: I believe these approaches are similar in spirit to the continuum of microservices vs monoliths.

Speaking from recent experience, I feel like I'm repeatedly finding that users of my library have built towers upon obsolete APIs, because there have been multiple phases of experimentation that necessitated large changes. So with each change, large amounts of code need to be rewritten.

I still think that approach #1 was justified during the early stages of the project, since I wanted to identify all of the design problems as quickly as possible through iteration. But as the API is getting closer to stabilization, I think I need to switch to mode #2.

How do you know when is the right time to switch? Are there any good strategies for avoiding painful upgrades?

24

You're viewing a single thread.

24 comments
  • Context:

    I'm a dev that consumes company wide libraries, not an author of such libraries. So the following comes from that perspective.

    A couple questions:

    1. Is development and consumption of your library happening in parallel? It sounds like you use the users to vet new features or major changes... is that correct? (They are iterating with you and reporting back on issues or desired changes)
    2. Is your library made up of a group of isolated components? Or is it a library that does one or two major things and so a breaking change literally changes the whole of what the library does?
    3. How are the consumers of your library when it comes to adopting changes? Do they readily do it? Is there a good bit of inertia?

    My thoughts:

    First off, SemVer is definitely going to be important. Also, it sounds like you're working toward API stabilization which is going help iterating in the future.

    My idea 1:

    If your library is made up of several isolated components, what about doing major releases (ex 2.x.x -> 3.x.x) more frequently? Only include a small subset of breaking changes for one or two components rather than jamming a whole bunch in there just because it's a "major version release". The result is you could move quickly and iterate while also minimizing the impact on ALL of your users every release. Some of your users may be able to upgrade to the latest without having to touch much or any of their code.

    My idea 2:

    Do frequent major release (ex 2.x.x - 3.x.x) but always start with an "alpha" release that early adopters could implement and provide feedback on. This would shield the majority of your consumer's code from having to iterate frequently but would also require you to enlist a group of committed early adopters that are diligent about iterating their code as often as you release.

    Feedback on the original option 1 and 2

    Option 1

    This could work if your users are excited about your releases. But, it could result in people NEVER upgrading because it's too much work to do so. (I've seen this happen. No one upgrades until they absolutely have to.)

    Option 2

    Depending on the size of your company, this will be a lot of work for you and will slow you down. If you're using your users to vet out new features, then everyone is going to have to iterate frequently (like you said) if experimental changes don't work out.

    • Thanks for your thoughtful reply.

      1. Yes. Yes.
      2. One or two major things. Breaking changes will usually result in a data structure format changing so algorithms that traverse the data structure need to be rewritten.
      3. One consumer is diligent about upgrading. The rest are much slower or rely on me to do it, but they continue building on top of an old version even after a new version is released.

      I like your idea of doing more frequent major releases and limiting the size of breaking changes within each release. It seems like a good compromise.

You've viewed 24 comments.