Yes and no.
Actually what you've done does bind the variable across the various instance of the component. The object is the same, ===, with the same reference... Until this happens:
selection = value;
This is from the compiled code in your REPL. What happens when you click on a checkbox is that Svelte creates a new array containing the checked values, and assign it to the bind:group variable. At this point, the variable is still the same... But it's content has been replaced with a new array reference. That's why when you change group, you lose the value of the previous one.
You can prove this to yourself by updating your REPL to make selection an object instead of an array, and add some logic to store the value by key.
For example, in App.svelte, change selection to an object:
let selection = {};
And in Selector.svelte, bind to an intermediary variable and write only to props of the object (not the object itself):
<script>
export let options;
export let selection;
let group = []
$: for (const option of options) {
selection[option] = group.includes(option)
}
</script>
<div class="selector">
{#each options as option}
<label>
<input type="checkbox" value={option} bind:group />
{option}
</label>
{/each}
</div>
Updated REPL
Print the value of selection somehow, and you'll see that it doesn't reset, and contains the value from all the selectors.
So, back to your issue, the problem is really the assignment. And there's not a lot you can do about it directly. There's nothing in Svelte to merge bound values... However, now that we have understood the problem, we can work around it.
The solution is to avoid binding directly the public prop (i.e. selection) but instead bind to an intermediary variable, like in our previous example, and do the merge ourselves somehow (lot of hows available here).
Here's one way you can rewrite your Selector component to accept variable sharing:
<script>
export let options;
export let selection;
let group = []
const update = () => {
selection = selection
.filter(x => !options.includes(x))
.concat(group)
}
// when group changes, update
$: group, update()
</script>
<div class="selector">
{#each options as option}
<label>
<input type="checkbox" value={option} bind:group />
{option}
</label>
{/each}
</div>
REPL
Note: I didn't put the selection = selection.filter(x => !options.includes(x)).concat(group) expression directly into the reactive block, because our update would then trigger when selection changes. And since it's shared, it will change from the outside. Actually, this would be an infinite loop condition, but Svelte has a protection against this specifically (for reactive blocks). But it's best not to rely on that, and also avoid wasting. Here it will trigger only when our local group changes, which is just what we need.