Реализующих BLoC паттерн библиотек много. Но та, о которой я расскажу, необычная, и называется isolate_bloc.
Как можно понять из названия — это какой-то необычный блок, а особенность его в том, что он работает в отдельном Isolate (далее изолят) и не тормозит ваш UI.
Помимо бойлерплейта есть и еще одна проблема — он работает в главном потоке, поэтому тяжелые задачи, типо парсинга json могут привести к фризам в UI.
С первой проблемой могут помочь библиотеки по типу simple_bloc или cubit. Со второй — изолят, или обертка над ним — Compute. В принципе это действительно хорошая связка, которую используют многие, но даже она решает не все проблемы. Например, в изоляте нельзя работать с MethodChannel, и в принципе его использование сопряжено с неудобствами и бойлерплейтом.

Эта библиотека помогает использовать BLoC паттерн и решает ряд задач, таких как работа с изолятами и MessageChannel-ами. Кроме этого она позволяет сократить количество кода при написании самого блока.
Чтобы понять, как работать с этой библиотекой, рассмотрим простой пример.
Несмотря на то, что далее я постарался описать все подробно, что-то может остаться непонятным, поэтому предполагается, что вы уже знакомы с BLoC паттерном.
Любой flutter проект начинается со счетчика, поэтому мы тоже с него начнем. Первым делом напишем сам блок.

В 3 строке мы создаём класс CounterBloc, который наследуется от класса IsolateBloc. Здесь же мы указываем тип ивентов и состояний нашего блока.
В 4 строке мы передаём начальное состояние счетчика — 0.
С 6 по 9 строках мы переопределяем метод onEventReceived, который вызывается при получении нового ивента. State — это гетер, который возвращает последнее состояние, которое блок отправил в UI.
В 8 строке мы используем функцию emit, которая принимает состояние и отправляет его в UI.
Теперь нужно зарегистрировать блок.
Так как он работает в отдельном изоляте, мы не можем напрямую создать его. Поэтому нужно дать знать библиотеке о его существовании с помощь функции register.

В 5 строке мы инициализируем библиотеку и передаем функцию, которая будет работать в изоляте и регистрировать блоки.
В 10 строке мы регистрируем CounterBloc — теперь библиотека сможет создать его по нашему запросу.
Осталось лишь описать UI!

В 8 строке мы создаем блок и добавляем его в дерево виджетов.
В 23 строке мы слушаем состояние блока. IsolateBlocBuilder работает как и StreamBuilder, но сам способен найти блок в дереве виджетов.
С 31 по 33 строки мы с помощью extension метода isolateBloc<Bloc, State>() получаем блок из контекста и с помощью функции add() добавляем в него новый ивент.
На этом всё, теперь можно запускать!
На базовом примере я показал, как работать с этой библиотекой, а для дальнейшего изучения советую заглянуть на её страницу на гитхабе. Там описан весь функционал и есть более сложные примеры.
Как можно понять из названия — это какой-то необычный блок, а особенность его в том, что он работает в отдельном Isolate (далее изолят) и не тормозит ваш UI.
В чем проблема обычного bloc-а?
Помимо бойлерплейта есть и еще одна проблема — он работает в главном потоке, поэтому тяжелые задачи, типо парсинга json могут привести к фризам в UI.
С первой проблемой могут помочь библиотеки по типу simple_bloc или cubit. Со второй — изолят, или обертка над ним — Compute. В принципе это действительно хорошая связка, которую используют многие, но даже она решает не все проблемы. Например, в изоляте нельзя работать с MethodChannel, и в принципе его использование сопряжено с неудобствами и бойлерплейтом.
Isolate Bloc

Эта библиотека помогает использовать BLoC паттерн и решает ряд задач, таких как работа с изолятами и MessageChannel-ами. Кроме этого она позволяет сократить количество кода при написании самого блока.
А как пользоваться?
Чтобы понять, как работать с этой библиотекой, рассмотрим простой пример.
Несмотря на то, что далее я постарался описать все подробно, что-то может остаться непонятным, поэтому предполагается, что вы уже знакомы с BLoC паттерном.
Любой flutter проект начинается со счетчика, поэтому мы тоже с него начнем. Первым делом напишем сам блок.

В 3 строке мы создаём класс CounterBloc, который наследуется от класса IsolateBloc. Здесь же мы указываем тип ивентов и состояний нашего блока.
В 4 строке мы передаём начальное состояние счетчика — 0.
С 6 по 9 строках мы переопределяем метод onEventReceived, который вызывается при получении нового ивента. State — это гетер, который возвращает последнее состояние, которое блок отправил в UI.
В 8 строке мы используем функцию emit, которая принимает состояние и отправляет его в UI.
Теперь нужно зарегистрировать блок.
Так как он работает в отдельном изоляте, мы не можем напрямую создать его. Поэтому нужно дать знать библиотеке о его существовании с помощь функции register.

В 5 строке мы инициализируем библиотеку и передаем функцию, которая будет работать в изоляте и регистрировать блоки.
В 10 строке мы регистрируем CounterBloc — теперь библиотека сможет создать его по нашему запросу.
Осталось лишь описать UI!

В 8 строке мы создаем блок и добавляем его в дерево виджетов.
В 23 строке мы слушаем состояние блока. IsolateBlocBuilder работает как и StreamBuilder, но сам способен найти блок в дереве виджетов.
С 31 по 33 строки мы с помощью extension метода isolateBloc<Bloc, State>() получаем блок из контекста и с помощью функции add() добавляем в него новый ивент.
На этом всё, теперь можно запускать!
Финал
На базовом примере я показал, как работать с этой библиотекой, а для дальнейшего изучения советую заглянуть на её страницу на гитхабе. Там описан весь функционал и есть более сложные примеры.