
Я очень люблю всякие курсы программирования для детей, где маленьких мальчиков и девочек учат программировать. Им обычно говорят слова типа: «Ты всё сможешь, только попробуй. У тебя обязательно получится. Ты станешь программистом. Ну или, на худой конец, майором-программистом, зато Дубай увидишь».
Как правило, на таких курсах детям не объясняют самое главное. Ты пожизненно будешь рабом каких-то тупых соглашений, на которые, к сожалению, ты повлиять вряд-ли сможешь.
И если один бык из этих соглашений ещё под силу, то тащить несколько таких быков — не то чтобы сложно… а нелогичность всего этого, отсутствие единых соглашений и вообще вся эта лапша в мире взрослых, даже в психологии маленьких девочек стоит далеко от прекрасного, гармоничного, логичного, идеального мира программирования.
И тут я, вся такая маленькая девочка, прихожу на курсы программирования. И тут передо мной вся такая умная тётенька начинает меня учить: «Сначала делай так, нажимай вот на эту кнопочку — у тебя выйдет вот так. А если нажмёшь на эту кнопочку — у тебя получится вот так. Потому что…»
И рассказ плавно перетекает в историю, откуда это всё, какие умные дяденьки это создавали, как логично и красиво они всё это сделали.
И я такая восторженная решаю: всё. Сегодня я точно прихожу домой и создаю программу girla.com. Я соберу всех своих подружек со своего дома, и с соседнего дома, и вообще со всей улицы, и вообще со всей планеты, всех девочек. И мы все будем делать всё в программе girla.com. Сначала я создам сайт! А потом приложение в Плэй Стор, а потом в Апп Стор, потом для компьютера, а потом для моих часов, а потом для всех!
Однако не все родители могут позволить купить своей доченьке домен по цене средней квартиры в Средней Азии. Хотя… нет худа без добра, правда? Такой домен вызовет очень доверительное отношение к его владельцу.
Скорее всего, реальность внесёт свои коррективы, и вместо короткого премиального girla нашей героине придётся придумывать что-то более уникальное и житейское. Большинство современных брендов и стартапов состоят из двух слов — это хороший вариант для бизнеса, остаться уникальным дешево. «Girla» - это звучит мило для мальчика, а вот «Piper Perri» - для настоящего мужика! Это и классическая структура из двух слов, которая и вызывает основную головную боль (чем их разделять?). И известный мем «Девушка и пять парней» как нельзя лучше иллюстрирует положение кроссплатформенного приложения: одна хрупкая кодовая база в окружении пяти суровых платформ — Web, Android, iOS, Windows и Linux, самое то.
Предприниматели, горящие идеей своего продукта, обычно не думают о технических ограничениях. Они придумывают «Уникальное Название», проверяют, свободен ли домен, и требуют, чтобы их детище выглядело идентично на всех устройствах. Им невдомёк, что то, что идеально смотрится на визитке или в адресной строке браузера, может стать причиной отказа в публикации в App Store или ошибки сборки в Android.
Основной удар принимает на себя разработчик. И если «нативщики» живут в своих уютных экосистемах, волнуясь только за правила одной ОС, то в мире кроссплатформенной разработки всё иначе. Сегодня безусловным лидером здесь является Flutter, позволяющий запускать один код почти везде. Но именно Flutter-разработчик оказывается в той самой ситуации «один против всех», вынужденный искать компромисс, который удовлетворит взаимоисключающие требования IT-гигантов.
Как же назвать наш условный проект «Piper Perri» так, чтобы и везде одинаковое брендовое название, и веб-сайт работал, и магазины приложений пропустили, и линуксоиды не засмеяли? Давайте разберем, какие требования выдвигает каждый из «пяти парней» к нашему единственному идентификатору.
WEB

Доменное имя для веб-сайта — это не произвольный набор символов, а строгая иерархическая структура, регулируемая на уровне протоколов Интернета. Базовым стандартом является RFC 1035, который определяет, что домен состоит из меток (labels), разделённых точками. Жесткие технические лимиты здесь продиктованы структурой пакетов DNS: длина одной метки не может превышать 63 октета, а полная длина имени (FQDN) ограничена 255 октетами. На практике, учитывая кодирование длины, максимальная длина домена в текстовой записи составляет 253 символа.
Однако для веб-разработчика важнее понятие Hostname. Не любая запись в DNS может быть именем сайта. Чтобы домен корректно работал в адресной строке браузера (URL), проходил валидацию SSL-сертификатов и понимался всеми сетевыми библиотеками, он должен соответствовать LDH-синтаксису (Letters, Digits, Hyphen), описанному в RFC 952 и уточненному в RFC 1123. Это означает, что разрешены только латинские буквы (a-z), цифры (0-9) и дефис (-). Регистр символов в DNS игнорируется (example.com и ExAmPlE.CoM эквивалентны), поэтому стандартом де-факто является использование только нижнего регистра во избежание путаницы.
С символом дефиса (-) связано несколько критических ограничений. Во-первых, он не может стоять в начале или в конце метки (например, -my-site.com — невалиден). Во-вторых, последовательность из двух дефисов на 3-й и 4-й позициях (xn--) зарезервирована для кодирования международных доменов (IDN) через алгоритм Punycode, описанный в RFC 3492. Это позволяет браузерам преобразовывать Unicode-имена (вроде россия.рф) в ASCII-совместимый вид для DNS-запросов, но также накладывает ограничения на использование двойного дефиса в обычных именах.
Самая частая ошибка при выборе домена для веба — использование нижнего подчеркивания (_). Хотя DNS технически позволяет создавать записи с этим символом (например, они активно используются для SRV-записей или верификации доменов acme-challenge), в качестве Hostname (имени хоста, к которому вы обращаетесь по HTTP/HTTPS) подчеркивание недопустимо. Если вы зарегистрируете домен mysite.com, он может разрешаться в IP-адрес, но браузеры, curl или HTTP-клиенты на Java/Python могут отказать в соединении или выдать ошибку «Invalid URI», ��ак как подчеркивание нарушает спецификацию Hostname.
Таким образом, единственно верная формула для универсального домена сайта: используйте только латинские буквы и цифры, при необходимости разделяя слова одиночными дефисами (но не по краям), и укладывайтесь в лимит 63 символа на сегмент. Любые отклонения от этого правила (спецсимволы, подчеркивания, пробелы) выведут ваш домен из зоны совместимости веб-стандартов.
Короче: для Web
Нижнее подчеркивание (_): Запрещено
Дефис (-): Разрешено
Точка (.): Разрешено
Заглавные буквы (A-Z): Допустимо, но не рекомендуется (DNS нечувствителен к регистру, лучше использовать только строчные во избежание путаницы).
Начинается с цифры (1app): Разрешено
Одно слово (нет точек): Допустимо с ограничениями (возможно в локальных сетях, но для публичного сайта обязательна доменная зона).
Очень длинный ID (>50 симв): Разрешено
Flutter разработчику
В Flutter-проекте для Web ситуация уникальна: сам домен (тот самый идентификатор piper-perri.com) не прописывается ни в одном конфигурационном файле внутри кода; он привязывается исключительно на стороне вашего хостинг-провайдера или DNS-регистратора при деплое. Однако, так как Flutter по умолчанию собирает проект как PWA (Progressive Web App), у приложения есть внутренние параметры, определяющие, как оно будет называться при установке на рабочий стол или экран смартфона. Эти настройки задаются в файле web/manifest.json (поля "name" и "short_name"), а отображаемое имя во вкладке браузера регулируется в файле web/index.html внутри тега <title>.
Вывод
Таким образом, мы можем сделать классное название нашему сайту или веб-приложению, например: piper-perri.com.
iOS

В экосистеме Apple фундаментальным идентификатором приложения является Bundle Identifier (Bundle ID). Это уникальная строка, которая определяет приложение в системе, используется для связывания с сервисами iCloud, Push Notifications и Game Center, а также служит ключом для проверки обновлений в App Store.
Согласно официальной документации по ключу CFBundleIdentifier, строка идентификатора должна соответствовать строгим правилам форматирования Uniform Type Identifier (UTI). Официальное определение гласит:
«Строка должна содержать только буквенно-цифровые символы (A-Z, a-z, 0-9), точку (.) и дефис (-).»
Это определение автоматически накладывает запрет на использование нижнего подчеркивания (_), пробелов и любых других специальных символов.
Apple также устанавливает стандарт структуры идентификатора. В документации About Bundle IDs указано:
«Рекомендуется использовать стиль обратного DNS (reverse-DNS style). Например, если домен вашей компании — Acme.com, а приложение называется Hello, вы можете использовать com.Acme.Hello в качестве Bundle ID.»
Эта структура не просто рекомендация «для красоты», она необходима для глобальной уникальности. App Store Connect не позволит создать запись приложения, если указанный Bundle ID уже зарегистрирован другим разработчиком. Использование подтвержденного домена компании в обратном порядке — единственный надежный способ гарантировать эту уникальность. Также важно отметить, что Bundle ID чувствителен к регистру (Case Sensitive), однако общепринятым стандартом является использование строчных букв (lowercase) для избежания путаницы при вводе.
Flutter разработчику
В отличие от веб-версии, для iOS идентификатор пакета жестко фиксируется в нативных файлах конфигурации проекта. Чтобы изменить его, необходимо открыть файл проекта ios/Runner.xcodeproj в программе Xcode. В навигаторе проекта выберите корневой элемент Runner, затем перейдите во вкладку General (или Signing & Capabilities) и в разделе Identity измените поле Bundle Identifier.
В самом коде Flutter этот параметр часто дублируется в файле ios/Runner/Info.plist через переменную $(PRODUCT_BUNDLE_IDENTIFIER), которая подтягивается из настроек сборки (Build Settings). Простого изменения текста в Info.plist может быть недостаточно, поэтому использование Xcode является наиболее надежным методом.
Короче: для iOS
Нижнее подчеркивание (_): ❌ Запрещено (официальная спецификация разрешает только буквы, цифры, точки и дефис).
Дефис (-): ✅ Разрешено (входит в спецификацию).
Точка (.): ✅ Разрешено (разделитель сегментов).
Reverse DNS (com.example.app): ✅ Обязательно (стандарт де-факто для уникальности).
Заглавные буквы (A-Z): ⚠️ Разрешено (система чувствительна к регистру, но рекомендуется использовать только строчные буквы).
Начинается с цифры (1app): ✅ Разрешено (технически сегмент может начинаться с цифры).
Одно слово (нет точек): ❌ Запрещено (требуется структура обратного DNS для публикации в App Store).
Очень длинный ID (>50 симв): ✅ Разрешено (жесткого лимита в 50 символов нет, но злоупотреблять не стоит).
Вывод
Айос: Имя piper-perri.com — не подойдет. Главное отличие от веб-домена здесь — это порядок записи: Apple настоятельно рекомендует (а для корректной работы сервисов требует) использовать стиль Reverse DNS. Это означает, что наше доменное имя piper-perri.com необходимо инвертировать, превратив его в com.piper-perri. Такой идентификатор будет валидным (так как дефис разрешен), уникальным и позволит корректно настроить страницу приложения в App Store. Ссылка на приложение в магазине будет формироваться на основе числового ID (например, apps.apple.com/app/id123456789), но com.piper-perri станет основой для работы Universal Links, позволяя открывать приложение при переходе по ссылкам с вашего сайта.
Windows

Для публикации приложений в Microsoft Store используется формат упаковки MSIX (или устаревший APPX). Сердцем пакета является файл манифеста Package.appxmanifest, где в элементе <Identity> задается атрибут Name. Это и есть уникальный идентификатор пакета в экосистеме Windows.
Правила валидации здесь одни из самых строгих и жестко прописаны в схеме манифеста пакета UWP. Официальная документация гласит:
«Строка длиной от 3 до 50 символов, состоящая из буквенно-цифровых символов (alpha-numeric), точки (.) и тире (-).»
Кроме того, существует список зарезервированных имен, пришедших еще из эпохи MS-DOS, которые запрещено использовать в качестве значения Identity Name: CON, PRN, AUX, NUL, COM1...COM9, LPT1...LPT9.
Ключевая особенность Windows-идентификатора, о которую спотыкаются многие мобильные разработчики — это полный запрет на нижнее подчеркивание (_). Если в Android вы привыкли писать com.example.my_app, то в Windows такой манифест просто не соберется. Вам придется либо удалять подчеркивание, либо заменять его на дефис.
Второе критическое ограничение — длина. В отличие от Android и iOS, где лимит составляет 255 символов, Windows ограничивает атрибут Name ровно 50 символами. Это заставляет быть лаконичным при использовании длинных Reverse DNS конструкций.
Flutter разработчику
В нативной части Windows-проекта Flutter этот параметр находится в файле windows/runner/Runner.rc (информация о версии) и, что более важно для сборки MSIX, конфигурируется через инструменты упаковки. Если вы используете популярный пакет msix для создания установщика, идентификатор задается в файле pubspec.yaml в секции msix_config: полем identity_name. Если вы настраиваете сборку вручную через Visual Studio, то редактировать нужно файл windows/runner/Package.appxmanifest, изменяя атрибут Name в теге <Identity>.
Короче: для Windows
Нижнее подчеркивание (_): ❌ Запрещено (вызывает ошибку валидации манифеста).
Дефис (-): ✅ Разрешено (официально поддерживается).
Точка (.): ✅ Разрешено.
Reverse DNS (com.example.app): ✅ Разрешено (и часто используется).
Заглавные буквы (A-Z): ✅ Разрешено (файловая система Windows нечувствительна к регистру, но в манифесте регистр сохраняется).
Начинается с цифры (1app): ✅ Разрешено.
Одно слово (нет точек): ✅ Разрешено (в отличие от мобильных платформ, Windows допускает идентификаторы вроде MyApp, если они уникальны в Store).
Очень длинный ID (>50 симв): ❌ Запрещено (строгий лимит — 50 символов, сборка упадет с ошибкой).
Вывод
Виндовс: Имя piper-perri.com — технически подойдет, так как Windows позволяет использовать точки, дефисы и структуру домена. Однако, учитывая ограничение iOS, где мы уже приняли решение использовать com.piper-perri, для Windows разумнее всего использовать тот же вариант: com.piper-perri. Это имя полностью валидно (дефис разрешен, подчеркивания нет, длина укладывается в 50 символов) и обеспечивает единообразие идентификаторов между платформами. Единственное, за чем нужно следить в Windows — чтобы длина вашего "Reverse DNS" имени никогда не превысила 50 знаков.
Android

В экосистеме Android ключевым идентификатором является Application ID (часто называемый Package Name). Это уникальная строка, которая идентифицирует приложение на устройстве и в магазинах приложений. Несмотря на то, что инструменты сборки Gradle позволяют отделить идентификатор приложения (applicationId) от структуры папок с исходным кодом (package), правила его именования остаются жестко привязанными к спецификации языка Java.
Согласно официальной документации Android Developers, идентификатор должен состоять как минимум из двух сегментов (разделенных точкой) и каждый сегмент должен начинаться с буквы. Допустимыми символами являются только латинские буквы (a-z), цифры (0-9) и нижнее подчеркивание (_).
Здесь мы сталкиваемся с главным архитектурным ограничением платформы: использование дефиса (-) строго запрещено. В отличие от iOS или Windows, где дефис является легальным разделителем, в Android (из-за наследия Java) этот символ интерпретируется как математический оператор вычитания. Попытка собрать проект с идентификатором com.piper-perri приведет к ошибке компиляции, так как система воспримет это как «пакет com.piper минус переменная perri».
Это ограничение является фундаментальным. Кроме того, важно помнить о неизменности ID. В Huawei AppGallery и RuStore имя пакета фиксируется при первой загрузке. Если вы ошиблись с неймингом, исправить его обновлением не получится — придется создавать новое приложение с нуля и терять набранную аудиторию, отзывы и рейтинги.
Flutter разработчику
В Android-части Flutter-проекта идентификатор настраивается в файле сборки android/app/build.gradle. Вам нужно найти блок defaultConfig и изменить значение поля applicationId (по умолчанию там стоит com.example.your_project_name).
Важно: хотя современный Android позволяет иметь applicationId, отличный от структуры папок Java/Kotlin, для избежания путаницы и проблем с некоторыми плагинами (например, Firebase или Activity Embedding) настоятельно рекомендуется, чтобы applicationId совпадал с путем к главному файлу MainActivity. Это значит, что если вы меняете ID на com.piper.perri, вам также следует переименовать структуру папок по пути android/app/src/main/kotlin/com/piper/perri/.
Короче: для Android
Нижнее подчеркивание (_): ✅ Разрешено (широко используется в Android как разделитель слов).
Дефис (-): ❌ Запрещено (критическое отличие от iOS/Windows/Web — вызывает ошибку сборки, так как это знак "минус").
Точка (.): ✅ Разрешено (обязательный разделитель сегментов).
Reverse DNS (com.example.app): ✅ Обязательно (стандарт платформы).
Заглавные буквы (A-Z): ❌ Запрещено (инструменты сборки и сторы требуют использовать только нижний регистр).
Начинается с цифры (1app): ❌ Запрещено (сегмент пакета Java не может начинаться с цифры).
Одно слово (нет точек): ❌ Запрещено (требуется минимум два сегмента, например com.app).
Очень длинный ID (>50 симв): ✅ Разрешено (лимит 255 символов).
Вывод
Андроид: Имя com.piper-perri, которое мы предварительно выбрали для iOS и Windows, здесь не подойдет из-за наличия дефиса, который Android считает математическим знаком вычитания.
Кажется, что можно заменить дефис на нижнее подчеркивание (com.piper_perri), но тогда мы потеряем совместимость с iOS и Windows, где подчеркивание запрещено.
Чтобы разорвать этот замкнутый круг и найти имя, которое будет валидно абсолютно везде (валидно для Web, iOS, Windows и Android одновременно), мы должны использовать универсальный разделитель — точку.
Поэтому мы отказываемся от дефисов и подчеркиваний в пользу сегментации точками. Наш итоговый, железобетонный выбор: com.piper.perri.
Это имя идеально:
Android: Любит точки (com.piper.perri — стандартный вид пакета).
iOS: Разрешает точки (валидный Bundle ID).
Windows: Разрешает точки (валидный Identity Name).
Web: Соответствует Reverse DNS логике.
Linux (Snap)

Snap — это универсальная система управления пакетами, разработанная Canonical (создателями Ubuntu), которая позволяет доставлять приложения на большинство дистрибутивов Linux. Центральным репозиторием является Snap Store. Здесь правила именования радикально отличаются от мобильных платформ и Windows, так как Snap наследует философию традиционных утилит командной строки Linux.
Согласно официальной документации Snapcraft, имя пакета (snap name) должно быть простым, запоминающимся и легко набираемым в терминале.
Имя должно состоять только из строчных латинских букв (a-z), цифр (0-9) и дефисов (-). Оно обязано начинаться с буквы.
Главное техническое ограничение, которое ломает привычную картину мира мобильного разработчика: точки (.) и нижние подчеркивания (_) строго запрещены. Регулярное выражение для валидации имени выглядит так: ^[a-z][a-z0-9-]*$. Максимальная длина имени ограничена 40 символами.
Запрет на точки означает, что формат Reverse DNS (например, com.piper.perri), являющийся стандартом в Android, iOS и современной Windows, в Snap Store технически невозможен. Это сделано намеренно: в Linux приложения запускаются из терминала по их имени. Пользователь ожидает, что для запуска Firefox он наберет команду firefox, а не org.mozilla.firefox. Поэтому Snap требует «плоских» (flat) имен.
Конфликты имен здесь решаются по принципу «кто первый встал, того и тапки». Если имя piper-perri занято, вам придется придумывать другое (например, piper-perri-app), так как пространств имен вроде com. или org. здесь не существует.
Flutter разработчику
Настройки упаковки Snap приложения находятся в файле snap/snapcraft.yaml в корне вашего проекта. Этот файл генерируется автоматически при инициализации поддержки Snap, но требует ручной правки перед публикацией. Имя пакета задается в самом верху файла в поле name:.
Важно понимать: это имя будет использоваться пользователем для установки (snap install myapp) и, по умолчанию, для запуска приложения из консоли. Внутри Flutter-кода (в pubspec.yaml) вы можете оставить любой name, но для успешной сборки snap-пакета поле name в snapcraft.yaml обязано соответствовать жестким правилам Snapcraft (без точек и подчеркиваний).
Короче: для Snap
Нижнее подчеркивание (_): ❌ Запрещено (наследие Linux-команд, где _ неудобен).
Дефис (-): ✅ Разрешено (единственный легальный разделитель слов).
Точка (.): ❌ Запрещено (главный «убийца» кроссплатформенных Reverse DNS имен).
Reverse DNS (com.example.app): ❌ Запрещено (из-за наличия точек).
Заглавные буквы (A-Z): ❌ Запрещено (Linux чувствителен к регистру, стандарт — только lowercase).
Начинается с цифры (1app): ❌ Запрещено (имя должно начинаться с буквы).
Одно слово (нет точек): ✅ Идеально (это рекомендуемый формат, например telegram или spotify).
Очень длинный ID (>40 симв): ❌ Запрещено (лимит жестче, чем в Windows — всего 40 знаков).
Вывод
Линукс Снап: Наш универсальный фаворит com.piper.perri, который идеально подошел для Web, iOS, Android и Windows, здесь не подойдет.
Snap Store категорически запрещает использование точек. Мы физически не сможем зарегистрировать пакет с таким именем.
Здесь нам придется пойти на вынужденный компромисс и нарушить единообразие идентификаторов. Для Snap Store мы должны трансформировать наше имя, убрав доменную структуру.
Логичным и валидным вариантом, максимально близким к оригиналу, будет замена точек на дефисы или удаление зоны .com.
Наиболее красивый и «Linux-way» вариант для нас: piper-perri.
Это имя валидно (только буквы и дефис), удобно для набора в терминале и однозначно ассоциируется с брендом. Да, оно отличается от Android/iOS ID, но это неизбежная плата за присутствие в Snap Store.
Linux (Native)

Под «нативным» Linux подразумевается классическая система распространения программ через репозитории дистрибутивов (Debian, Ubuntu, Fedora, CentOS) с использованием пакетных менеджеров APT (.deb) и DNF/YUM (.rpm). Здесь действуют одни из самых старых и консервативных правил в IT-индустрии, которые формировались десятилетиями.
Наиболее строгим стандартом является «Политика Debian» (Debian Policy Manual). Согласно главе 5.6.1, имя пакета может содержать только строчные латинские буквы (a-z), цифры (0-9) и символы: плюс (+), минус (-) и точка (.).
Ключевое ограничение, которое часто упускают разработчики: нижнее подчеркивание (_) строго запрещено в именах пакетов Debian/Ubuntu. Попытка собрать .deb пакет с именем piper_perri приведет к фатальной ошибке упаковщика dpkg-deb.
В мире Red Hat (Fedora/RHEL) правила чуть мягче и допускают подчеркивание, но для кросс-дистрибутивной совместимости ориентироваться нужно на более строгий стандарт Debian.
Что касается структуры Reverse DNS (com.piper.perri): технически точки разрешены (они используются для версий, например python3.11), поэтому имя com.piper.perri пройдет валидацию. Однако в культуре нативного Linux это считается моветоном (bad practice). Пользователи привыкли устанавливать софт короткими командами (sudo apt install git), и вводить длинные доменные имена в терминале не принято. Кроме того, префиксы lib, python- и другие имеют зарезервированное семантическое значение, поэтому имя должно быть максимально простым и описывающим суть утилиты.
sudo apt install cpp - а если так?
В мире Linux (Native) это идеальный пример того, как именуются пакеты:
Коротко: cpp (всего 3 буквы).
Без мусора: Никаких com., org., net..
Без версий: (обычно) просто имя программы.
Подходит иделально, Если бы не но:
В данном случае cpp — это реальный пакет (C Preprocessor), который уже есть в репозиториях Debian, Ubuntu и других.
Flutter разработчику
В нативной Linux-части Flutter-проекта есть два уровня именования.
Первый — имя исполняемого бинарного файла. Оно задается в файле linux/CMakeLists.txt в строке set(BINARY_NAME "..."). Здесь крайне не рекомендуется использовать точки, так как это усложнит запуск программы из терминала.
Второй — имя самого пакета для дистрибуции. Flutter не создает .deb или .rpm файлы «из коробки» (команда flutter build linux делает только бинарник). Для создания установщика вам потребуется создать файл метаданных (например, debian/control для .deb), где в поле Package: вы и укажете финальное имя для пакетного менеджера. Именно это имя должно соответствовать правилам Debian Policy.
Короче: для Linux Native
Нижнее подчеркивание (_): ❌ Запрещено (в Debian/Ubuntu вызывает ошибку сборки пакета).
Дефис (-): ✅ Разрешено (основной разделитель слов, стандарт де-факто).
Точка (.): ⚠️ Разрешено (технически возможно, но культурно не принято использовать для доменных префиксов типа com.).
Reverse DNS (com.example.app): ⚠️ Технически валидно, но не рекомендуется (выглядит чужеродно в apt install, вас засмеют линуксоиды).
Заглавные буквы (A-Z): ❌ Запрещено (имена пакетов должны быть строго в нижнем регистре).
Начинается с цифры (1app): ✅ Разрешено (например, пакет 7zip).
Одно слово (нет точек): ✅ Идеально (золотой стандарт, например nginx, vim).
Очень длинный ID: ✅ Разрешено (но неудобно для набора в консоли).
Вывод
Линукс Натив: Универсальное имя com.piper.perri здесь технически возможно, но идеологически неверно.
Хотя apt install com.piper.perri сработает (так как точки разрешены), это нарушает негласные конвенции Linux. Пакеты здесь именуются просто, коротко и ясно («slug-style»).
Кроме того, если бы мы выбрали вариант с подчеркиванием для Android (com.piper_perri), здесь бы он сломался, так как Debian запрещает подчеркивания.
Чтобы наше приложение выглядело в репозиториях "как родное", мы должны (как и в случае со Snap) отбросить доменную часть com..
Наш выбор для нативных пакетов: piper-perri.
Это полностью валидное имя (строчные буквы и дефис), оно совместимо со всеми дистрибутивами (Debian, Ubuntu, Fedora, Arch) и интуитивно понятно пользователю терминала.
Linux (Flatpak)
Flatpak — это современная технология песочницы и дистрибуции приложений для Linux, которая де-факто стала стандартом для графического софта в таких системах, как Fedora, Linux Mint и SteamOS (Steam Deck). В отличие от хаоса нативных пакетов или простоты Snap, Flatpak с самого начала наводит жесткий порядок в именовании. Идентификатор приложения (Application ID) здесь является краеугольным камнем всей архитектуры: он определяет пути к файлам конфигурации, права доступа в песочнице и имя файла .desktop для запуска.
Правила формирования ID во Flatpak базируются на спецификации D-Bus, так как именно через D-Bus приложение общается с внешним миром. Согласно официальной документации Flatpak, идентификатор обязан использовать стиль Reverse DNS. Но есть важное уточнение, отличающее его от Android: идентификатор должен состоять минимум из трех сегментов. То есть имя com.app будет считаться невалидным, требуется минимум com.company.app.
В плане допустимых символов Flatpak является, пожалуй, самой лояльной платформой из всех «строгих». В именах сегментов разрешены латинские буквы (A-Z, a-z), цифры (0-9), дефис (-) и нижнее подчеркивание (_). Это делает Flatpak уникальным местом, где легальны и «Android-стиль» (_), и «iOS-стиль» (-).
Более того, Flatpak — единственная современная среда, где официально поощряется (но не требуется) использование заглавных букв в стиле CamelCase для последнего сегмента (например, org.gimp.GIMP или com.visualstudio.code). Однако для кроссплатформенной унификации разработчики чаще используют полный lowercase.
Flutter разработчику
Сборка Flatpak-приложения не встроена в стандартный тулчейн Flutter (команды flutter build flatpak нет). Упаковка происходит с помощью утилиты flatpak-builder, которая управляется файлом манифеста (обычно это YAML или JSON файл в корне репозитория). Имя этого файла традиционно совпадает с ID приложения, например com.piper.perri.yml. Внутри этого манифеста поле app-id задает идентификатор.
Критически важно: этот же ID должен быть прописан в имени файла иконки, в имени .desktop файла (метаданные для меню приложений) и в AppStream-файле (описание для магазина приложений), который должен лежать по пути data/com.piper.perri.metainfo.xml.
Короче: для Flatpak
Нижнее подчеркивание (_): ✅ Разрешено (и часто используется).
Дефис (-): ✅ Разрешено (полная свобода выбора разделителя).
Точка (.): ✅ Разрешено (обязательный разделитель, минимум 2 точки для 3 сегментов).
Reverse DNS (com.example.app): ✅ Обязательно (фундамент архитектуры).
Заглавные буквы (A-Z): ✅ Разрешено (и даже популярно, например org.libreoffice.LibreOffice).
Начинается с цифры (1app): ❌ Запрещено (сегменты не могут начинаться с цифры).
Одно слово (нет точек): ❌ Запрещено (строгое требование минимум 3-х компонентов).
Очень длинный ID: ✅ Разрешено.
Вывод
Линукс Флатпак: Наш универсальный кандидат com.piper.perri здесь подходит идеально.
Структура: Он состоит из 3-х сегментов (com, piper, perri), что удовлетворяет требованию Flatpak (минимум 3 части). Если бы мы назвали приложение короче, например com.piper, Flatpak бы его отверг, но com.piper.perri проходит.
Символы: Точки разрешены и являются разделителями.
Совместимость: Это имя полностью совпадает с тем, что мы выбрали для Android, iOS и Windows.
Таким образом, для публикации на Flathub нам не нужно ничего менять. Мы используем com.piper.perri.
Итого?

Чтобы охватить все платформы одним кодом, нужно видеть всю картину ограничений. В этой таблице оставлена только "сухая выжимка" по допустимым символам для идентификаторов (ID):
Правило / Платформа | Web (Hostname) | Android | iOS | Windows | Snap | Flatpak | Linux Native |
Нижнее подчеркивание (_) | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ |
Дефис (-) | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
Точка (.) | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ⚠️ |
Заглавные буквы (A-Z) | ⚠️ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ |
Начинается с цифры (1app) | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
Одно слово (нет точек) | ⚠️ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ |
Очень длинный ID (>50) | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
Как назвать бренд, чтобы быть везде?
Исходя из нашего расследования, единого "золотого ключа" не существует. Однако мы вывели формулу "Двух сущностей", которая покрывает 100% цифрового пространства с минимальной болью.
Вот как будет выглядеть инфраструктура для бренда Piper Perri:
Web (Сайт): piper-perri.com
(Красиво, читаемо, привычно для людей).iOS / Android / Windows / Flatpak (Внутренний ID): com.piper.perri
(Универсальный Reverse DNS. Мы заменили дефис на точку, чтобы угодить Android, и не используем подчеркивания, чтобы угодить iOS и Windows. Это имя валидно везде).Snap / Linux Native (Имя пакета): piper-perri
(Slug-style. Мы убрали доменную зону и точки, так как Linux требует "плоских" имен. Это имя валидно для терминала).
А вот пример для отечественного бренда Roga Kopyta:
Web: roga-kopyta.ru
All App Stores (Universal ID): ru.roga.kopyta
Linux CLI: roga-kopyta
Заключение
Возвращаясь к той маленькой девочке с курсов, которая мечтала объединить весь мир в приложении girla.com.
Те самые «умные дяденьки», портреты которых висят в залах славы IT, создали невероятные технологии. Они подарили нам интернет, смартфоны и операционные системы. Но они забыли сделать одну вещь — договориться.
В прекрасном, логичном и идеальном мире программирования, о котором рассказывают детям, идентификатор — это просто имя. В реальности же — это шрам от битвы корпораций и идеологий. Android не переваривает дефис, потому что тридцать лет назад создатели Java решили, что это знак вычитания. Windows и iOS боятся нижнего подчеркивания, потому что их файловые системы и сертификаты живут по другим законам. А Linux, гордый и свободный, вообще отрицает саму концепцию доменов в именах, требуя простоты печатной машинки.
Разработчик в этом мире — не просто творец. Это дипломат, вынужденный лавировать между "быками" взаимоисключающих правил. Ты не можешь просто "создать". Ты должен знать, что в Редмонде ненавидят то, что обожают в Маунтин-Вью, а сообщество Линукса вообще живет в своей отдельной вселенной.
И заказчику, и той самой девочке, которая вырастет и станет "майором-программистом", придется смириться с тем, что в IT нет гармонии. Есть только бесконечный поиск компромисса, где твое красивое girla.com превращается в com.girla.app в одном месте и в girla-cli в другом. Не потому что так лучше или логичнее. А просто потому, что те, кто строил этот цифровой мир, строили его не вместе, а каждый в своей песочнице, огороженной высоким забором из несовместимых спецификаций.
P.S. Всем подписчикам плюс в карму)
P.P.S. (Piper Perri Surrounded) К слову, еще есть что сказать по этой теме: время поменялось, и черные парни теперь белые, а вот девочка — не факт, что белая, и не факт, что девочка. Так что ждите продолжения и помните о тайных желаниях единого идентификатора.