Best practise/standard practise for semantic versioning in development I have a project that looks like this: 

SOME_MONOREPO, managed by lerna                           

- package-a
- package-b - depends on package-a, package-c
- package-c - is currently private, so not published as npm package. 
When package-b builds, it accesses package-c directly via symlink. 
As we move forward, we'll transition this to published packages like package-a. 

ANOTHER_PROJECT

- package-foo- depends on SOME_MONOREPO.package-a



Now, say I'm doing some work on package-a, this could be a major, minor or patch change. 

There are a few possible development flows: 


The simplest: the work just occurs on package-a, I write tests for it, and then when ready version bump and push to master. 
I'm doing work on package-a, but also updating package-b to adapt to the breaking changes/use the new functionality. In this scenario version bump isn't strictly necessary to do the code, because lerna's symlinks will still let package-b access the package-a code. 
I'm also doing work on package-foo. In this case I need to be publishing to npm in order to access the code. 


So, I'm thinking that nightly/unstable/prerelease builds are warranted here. That is - I build some functionality on package-a, build an unstable artefact, and then package-foo can use it, see if it's fit for purpose. 

At some point though - a decision needs to be made whether this is a major, minor or patch update. 

The question is - when should this happen? Does the developer, when making changes, decide on their first PR to develop each time what the version bump is? (And it not being a release PR, the CI automatically publishes it with the 'unstable' appendix, when it is release the unstable appendix is removed). What about if another developer is simultaneously working on the same package?

Is there a way to not think about version bumps until formal release?
Version bumps should happen every single build.  Waiting until a formal release and releasing everything as 1.0.0 is an option, but you should still know what build you are using in your alpha/beta.

Ultimately, the developer will have to determine if a major release increment is needed. 
You should only do a major release bump if you introduced a breaking change.

For your regular builds, a common practice is to let your CI tool increment the "patch release" number or the X.X.Patch portion of the version.  This way your versioning is tied to your builds which will help the development and testing process.  If you choose to only do a nightly build, you can have your CI tool increment this number then so that you and other developers know what version of the package they are using.

NPM has published a good guide on how to handle semantic versioning.