Что такое Flutter и чем он лучше Kivy?
Проведу небольшое исследование по сравнению Flutter и Kivy. Я не знаком с Flutter, поэтому для меня это буквально как изучать новое по ходу написания этой статьи. С этим мне тоже отлично помогают нейросети, которым можно доверить как исправление орфографических ошибок, так и поиск или написание некоторого текста.
Когда сравниваешь Kivy и Flutter, довольно быстро становится заметно, что эти инструменты стоят на совершенно разных основаниях, хотя внешне оба предлагают кросс-платформенную разработку. Kivy вырос из Python-экосистемы и представляет собой в первую очередь UI-фреймворк, которому приходится работать поверх интерпретируемого языка и множества слоёв абстракции. Flutter же был изначально спроектирован Google как полноценный SDK для создания нативных интерфейсов, и именно поэтому он существенно выигрывает в производительности, стабильности и управляемости сборки.
Kivy опирается на Python — мощный и гибкий язык, но изначально не предназначенный для высокопроизводительной отрисовки интерфейсов и уж тем более для нативной компиляции. Приложения на Kivy работают внутри виртуальной машины Python, а сам UI отрисовывается через OpenGL слоями, которые фреймворку приходится собирать вручную. Это приводит к заметным накладным расходам: приложения оказываются тяжелее, отклик медленнее, а поведение на разных ОС непредсказуемее. Попытки собрать приложение под Linux, macOS или мобильные платформы часто превращаются в борьбу с зависимостями, нестыкующимися версиями библиотек и обилием сторонних инструментов вроде buildozer или python-for-android. Именно из-за этого каждая новая сборка становится похожа на мини-исследование, где заранее невозможно знать, появится ли следующий сюрприз.
Flutter устроен совсем иначе. Он использует Dart — язык, созданный с учётом особенностей UI-разработки. Dart умеет работать в двух режимах: в JIT-режиме с быстрым hot-reload для разработки и в AOT-режиме, при котором код компилируется в полноценный нативный машинный код для целевой платформы. Это значит, что Flutter-приложение не интерпретируется, не работает внутри виртуальной машины и не зависит от особенностей окружения. Вместо этого оно запускается так же, как и любое нативное приложение, что сразу поднимает производительность и снижает задержки рендера.
В то время как в Kivy-приложении возникают заметные задержки даже при простом раскрытии вложенных элементов. Иногда у меня появлялось ощущение, что такая тормознутость интерфейса может отпугнуть пользователей, и они просто не захотят им пользоваться.
Важной частью архитектуры Flutter является собственный рендер-движок Skia. Этот движок используется и в Chrome, и в Android, и в ряде других крупных проектов, поэтому он отлично оптимизирован под высокие FPS, плавность анимаций и одинаковое поведение на всех платформах. Flutter не доверяет отрисовку системным элементам ОС: он рисует весь интерфейс сам, что гарантирует одинаковый внешний вид и одинаковую производительность независимо от того, собираете ли вы приложение под Linux, Windows, Android, iOS или macOS.
С точки зрения сборки разница ещё заметнее. Когда работаешь с Kivy, любое добавление зависимостей может превратиться в многодневную охоту за решениями, особенно если речь идёт о Linux или мобильных системах. Python-библиотеки часто требуют нативных расширений, которые должны компилироваться под конкретную архитектуру, а инструменты для сборки не всегда умеют делать это корректно. Иногда приходится вручную искать версии библиотек, собирать колёса, подстраивать окружение — и всё это только ради того, чтобы приложение наконец запустилось на целевой платформе.
Flutter в этом смысле почти противоположен. Его система сборки тщательно организована и использует официальные инструменты платформ: Xcode для iOS, toolchain Apple для macOS, стандартные инструменты Linux, Windows и Android. Разработчик пишет код на Dart, а Flutter уже знает, как его собрать, упаковать, связать и оптимизировать. В итоге типичная сборка сводится к одной-двум командам в терминале и занимает предсказуемое время. Ошибки возникают редко, а если и появляются, то, как правило, воспроизводимы и документированы — в отличие от многих сюрпризов, которые встречаются при сборке проектов на Kivy.
Из-за этой комбинации факторов Flutter нередко воспринимается как инструмент на голову превосходящий Kivy. Он предлагает заранее продуманную архитектуру рендера, современный язык с нативной компиляцией, единый подход к сборке приложений и большую экосистему пакетов. Kivy хорош для экспериментов, но когда речь заходит о стабильной кросс-платформенной разработке, особенно с упором на производительность и предсказуемость, Flutter становится более очевидным выбором.
Быстро и стабильно работать с Kivy у меня, увы, не получается, потому что приходится постоянно искать информацию и разбираться с нюансами, тогда как во Flutter те же задачи решаются буквально двумя командами — быстро и без лишнего мозгового штурма.
Hello world на flutter
Сама идея Flutter мне очень понравилась, он, как мне кажется, на голову превосходит Kivy. Теперь мне нужно написать код на Flutter, с которым я как Python3-разработчик пока совершенно не знаком. Обычного «Hello, World» будет достаточно для текущего этапа исследования гипотезы, поэтому я попрошу нейросеть написать приложение, которое я затем соберу под Linux.
Ответ GigaChat:

Ответ Perplexity:

Мне нравится, что Perplexity начал с установки Flutter и зависимостей для сборки. Хотя я не просил об этом, это кажется более профессиональным подходом, так как мне как пользователю не пришлось дополнительно искать информацию о том, как его установить.
git clone https://github.com/flutter/flutter.git -b stableexport PATH="$PATH:`pwd`/flutter/bin"Далее, после установки Flutter и зависимостей, я создаю новый проект. С этим справились обе нейросети.
flutter create hello_worldВывод в terminal:
Your application code is in hello_world/lib/main.dart.Вот такая богатая структура создаётся после инициализации проекта. Сразу видно, под какие операционные системы можно собрать проект. Выбор впечатляет! В данный момент я не буду разбирать каждый элемент системы, так как сам пока не знаю, как устроен проект на Flutter.

Далее мне нужно выбрать код, который я вставлю в приложение.
Ответ GigaChat:

Тут мне больше понравился код, который написал GigaChat, так как, помимо текста, он ещё указал стиль (видимо, для текста «Привет, мир!»). Читаю код как английский текст, а сам синтаксис языка Dart для меня частично загадка, но отчасти интуитивно понятно что в нём.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Hello World',
home: Scaffold(
appBar: AppBar(title: Text('Hello World')),
body: Center(
child: Text(
'Привет, мир!',
style: Theme.of(context).textTheme.headlineMedium,
),
),
),
);
}
}Ответ Perplexity:

После написания запущу проект и посмотрю как оно отработает.
cd hello_world && flutter runВывод в terminal:
Downloading Web SDK... 4,0s
Downloading linux-x64-debug/linux-x64-flutter-gtk tools... 4,6s
Downloading linux-x64-profile/linux-x64-flutter-gtk tools... 2 822ms
Downloading linux-x64-release/linux-x64-flutter-gtk tools... 2 208ms
Connected devices:
Linux (desktop) • linux • linux-x64 • Debian GNU/Linux 12 (bookworm) 6.1.0-41-amd64
Chrome (web) • chrome • web-javascript • Google Chrome 143.0.7499.40
[1]: Linux (linux)
[2]: Chrome (chrome)
Please choose one (or "q" to quit): 1
Launching lib/main.dart on Linux in debug mode...
Building Linux application...
✓ Built build/linux/x64/debug/bundle/hello_world
Syncing files to device Linux... 117ms
Flutter run key commands.
r Hot reload.
R Hot restart.
h List all available interactive commands.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
A Dart VM Service on Linux is available at: http://127.0.0.1:43129/yIwmXl6KQrU=/
The Flutter DevTools debugger and profiler on Linux is available at: http://127.0.0.1:43129/yIwmXl6KQrU=/devtools/?uri=ws://127.0.0.1:43129/yIwmXl6KQrU=/wsКажется оно запустилось =) Прочитаю немного что там за VM Service и VM Service запустились.
Dart VM Service — это интерфейс для отладки и профилирования приложения:
Dart VM Service (http://127.0.0.1:43129/…) — внутренний сервер, через который можно получать информацию о работе приложения: состояние памяти, потоков, производительность и т.д;
Flutter DevTools (http://127.0.0.1:43129/…/devtools) — веб-интерфейс для удобной работы с Dart VM Service. Через него можно:
- отлаживать код (debugger);
- смотреть логи;
- профилировать производительность (CPU, память);
- визуализировать виджеты и их состояние.
VM Service:

Очень приятно, что из коробки Flutter представляет такой богатый функционал отладки и профилирования.
Окно программы:

В окне видны две надписи: «Hello World» и «Привет, мир!». Также в углу указано, что приложение запущено в режиме отладки (Debug).
Сборка приложения под Linux
Далее перехожу к самому главному исследованию — сборке приложения под Linux. Мне нужно понять, насколько этот процесс удобен во Flutter. Для эксперимента я решил выбрать формат AppImage.
AppImage — это формат упаковки приложений для Linux, который позволяет запускать программу как единый самодостаточный файл, без установки и зависимости от системных библиотек. Он удобен тем, что даёт почти портативный опыт: скачал, дал права на запуск — и вперёд, никакого «танца с пакетами» и конфликтов версий. Поддерживается AppImage на большинстве дистрибутивов Linux, от Debian, Ubuntu и Fedora до Arch и openSUSE, и именно универсальность делает его любимцем разработчиков, которые хотят распространять софт без лишних хлопот.
На втором шаге нейросети расскажут, как собрать приложение. Что ж, посмотрим, насколько хорошо у них это получится на практике.
Ответ GigaChat:

В начале я решил проверить пример от GigaChat. По его совету я решил поставить appimagetool через apt.
sudo apt install appimagetoolВывод в terminal:

Этого пакета нет в apt для Debian 12. Посмотрим каким способом предлагает Perplexity установить пакет для сборки приложения.
Ответ Perplexity:

Perplexity предлагает скачать два инструмента linuxdeploy и appimagetool с помощью wget.
Чем они отличаются?
- appimagetool — это инструмент упаковки: он берёт уже подготовленную файловую структуру AppDir и превращает её в AppImage;
- linuxdeploy — это инструмент сборки: он сам собирает AppDir из вашего бинарника, подтягивает зависимости, раскладывает всё по правильным каталогам и только потом уже может упаковать это в AppImage.
В итоге:
- appimagetool = упаковщик
- linuxdeploy = сборщик + упаковщик
Flutter приносит с собой почти всё необходимое для запуска приложения:
движок, рендерер, ICU-данные, бинарники — всё включается в билд. Поэтому основные зависимости Flutter уже внутри.
Из-за этого в теории можно просто взять готовый build/linux/x64/release/bundle, оформленный как AppDir, и упаковать его через appimagetool — и оно должно запустится на большинстве дистрибутивов.
Appimagetool не подтягивает зависимости. Он просто упаковывает то, что уже положили в AppDir. Если какой-то системной библиотеки не хватает на старой версии Ubuntu/Debian/Fedora, AppImage может не запуститься.
Для начала выберу самый простой вариант собрать с помощью appimagetool.
Скачивание инструмента:
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImageВывод в terminal:
2025-12-08 23:24:34 (5,15 MB/s) - «appimagetool-x86_64.AppImage» сохранён [8811712/8811712]Делаем файл исполняемым:
chmod +x appimagetool-x86_64.AppImageСоздание нужной структуры каталогов для сборки:
mkdir -p AppDir/usr/bincp build/linux/x64/debug/bundle/hello_world AppDir/usr/bin/cp build/linux/x64/debug/bundle/hello_world.png AppDir/cp build/linux/x64/debug/bundle/hello_world.desktop AppDir/Вывод в terminal:
cp: не удалось выполнить stat для 'build/linux/x64/debug/bundle/hello_world.desktop': Нет такого файла или каталогаСудя по всему, отсутствует важный файл, и если сейчас запустить сборку, она ожидаемо упадёт.
./appimagetool-x86_64.AppImage hello_world/AppDir Вывод в terminal:
appimagetool, continuous build (commit 5735cc5), build <local dev build> built on 2023-03-08 22:52:04 UTC
Desktop file not found, abortingТеперь мне нужно узнать у нейросетей, что это за файл .desktop и как его создать.
Ответ GigaChat:

Ответ Perplexity:

Мне больше понравился .desktop файл от Perplexity, который выглядит более простым.
Создание пустого .desktop
touch ./AppDir/hello_world.desktopЗаполнение файла:
[Desktop Entry]
Name=Hello World
Exec=hello_world
Icon=hello_world
Type=Application
Categories=Utility;
Comment=Hello World Flutter AppТеперь запускаю процесс сборки приложения.
./appimagetool-x86_64.AppImage hello_world/AppDirВывод в terminal:
Creating 4.0 filesystem on Hello_World-x86_64.AppImage, block size 131072.
[=|] 4/4 100%
Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 131072
compressed data, compressed metadata, compressed fragments,
compressed xattrs, compressed ids
duplicates are removed
Filesystem size 229.65 Kbytes (0.22 Mbytes)
89.06% of uncompressed filesystem size (257.87 Kbytes)
Inode table size 138 bytes (0.13 Kbytes)
57.26% of uncompressed inode table size (241 bytes)
Directory table size 98 bytes (0.10 Kbytes)
67.59% of uncompressed directory table size (145 bytes)
Number of duplicate files found 0
Number of inodes 7
Number of files 3
Number of fragments 1
Number of symbolic links 1
Number of device nodes 0
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 3
Number of ids (unique uids + gids) 1
Number of uids 1
root (0)
Number of gids 1
root (0)
Embedding ELF...
Marking the AppImage as executable...
Embedding MD5 digest
SuccessРезультатом процесса сборки стал файл Hello_World-x86_64.AppImage, который мне не терпелось запустить.
Однако, когда я нажал на файл, увидел ошибку: «The command not be found», что означает, что команда не была найдена. Я предположил, что что-то не так со структурой или приложение не может понять, как запустить себя. Я спросил у нейросетей совета по решению и прикрепил изображение с ошибкой.
Ответ Perplexity:


Ответ GigaChat:


Тут я опять выбрал ответ от Perplexity так как он подсказал создать файл AppRun, который необходим для запуска приложения.
Создание AppRun:
touch ./AppDir/AppRun#!/bin/sh
HERE="$(dirname "$(readlink -f "$0")")"
export LD_LIBRARY_PATH="$HERE/lib:$LD_LIBRARY_PATH"
exec "$HERE/hello_world" "$@"chmod +x ./AppDir/AppRunДалее последовала череда ошибок и запросов к нейросетям, которые я не буду перечислять, чтобы не затягивать статью. Однако я кратко расскажу о некоторых моментах.
Тут он не мог инициализировать движок:
embedder.cc (2090): 'FlutterEngineInitialize' returned 'kInvalidArguments'. Not running in AOT mode but could not resolve the kernel binary.
** (com.example.hello_world:315658): WARNING **: 00:57:09.388: Failed to start Flutter engine: Failed to initialize Flutter engineОказалось, что я не заметил: собирал debug-версию, а не release. Поэтому я пересобрал релизную версию под Linux.
flutter build linux --release -vТак же можно запускать сам файл hello_world чтоб видеть ошибки ещё до сборки. Это экономит массу времени.
./bin/hello_world Вывод в terminal:
./bin/hello_world: error while loading shared libraries: libflutter_linux_gtk.so: cannot open shared object file: No such file or directoryОшибка указывает на отсутствие библиотеки, содержащей код, необходимый для работы Flutter-приложения на Linux: отображение окон, обработка событий, взаимодействие с системой и рендеринг графики. Также возможно нарушение структуры проекта, из-за чего библиотека не находится.
В итоге помог запрос к Perplexity, который помог понять, что проблема была именно со структурой. Это действительно логично, так как из папки build приложение запускается нормально.

Далее нужно было пересоздать каталог, скопировать в него правильно файлы и структуру и добавить остальные файлы, которые были созданы выше.
mkdir -p AppDir cp -r build/linux/x64/release/bundle/* AppDir/Проверка запуска:
cd AppDirexport LD_LIBRARY_PATH="$PWD/lib:$LD_LIBRARY_PATH"Команда export LD_LIBRARY_PATH="$PWD/lib:$LD_LIBRARY_PATH" добавляет путь к папке lib в текущей директории в список путей, где система ищет динамические библиотеки при запуске программ.
./hello_worldПосле того как окно приложения запустилось осталось только собрать его и проверить в собранном виде.
cd .. ./appimagetool-x86_64.AppImage AppDir chmod +x Hello_World-x86_64.AppImage./Hello_World-x86_64.AppImageЗапуск из terminal:
./Hello_World-x86_64.AppImage
В результате запуска появилось окно приложения. Обе нейросети показали себя достаточно хорошо и помогли разобраться с возникающими проблемами. В итоге за один вечер мне удалось успешно собрать и запустить Flutter-приложение под Linux.
Поздравления с днём рождения

Так получилось, что день публикации статьи совпал с днём рождения Ивана — создателя и автора канала «Код на салфетке». Хочу поздравить его с праздником и пожелать всего самого наилучшего, а также дальнейших успехов в карьере и в развитии канала!
Планы на будущее
В следующей статье я продолжу проверять гипотезу, написав на Flutter и собрав что-то более сложное, чем Hello World. Мне предстоит разобраться в структуре проекта, синтаксисе языка Dart и в том, как создаётся внешний вид приложения. Также я хочу взять часть своего приложения Kivy и попробовать повторить похожий результат на Flutter.
Если кому-то интересен проект на Kivy, который я упоминал в начале статьи, то вы можете узнать о нём, перейдя по этой ссылке.
Если у вас есть мысли о том, как можно улучшить проект, пишите в комментариях — с удовольствием ознакомлюсь с вашими предложениями!
Читайте продолжение — не пропустите!
Комментарии
Оставить комментарийВойдите, чтобы оставить комментарий.
Комментариев пока нет.