Як я створив StemJSON — мову, якою ШІ пише нативні мобільні застосунки

💡 Усі статті, обговорення, новини про Mobile — в одному місці. Приєднуйтесь до Mobile спільноти!

Привіт! Мене звати Василь Кричун, я Senior Engineering Manager із понад 20-річним досвідом в IT, переважно в мобільній розробці. Починав ще із Symbian та J2ME, згодом працював з iOS і Android, а останні кілька років займаюся інтеграцією ШІ в мобільні продукти.

Ця стаття про те, чому я вирішив написати власну декларативну мову програмування для мобільних застосунків, що, на перший погляд, виглядає дуже амбітно і викликає питання — навіщо, особливо в період буму ШІ, коли будь-хто з мінімальним досвідом може створити потрібний додаток. Звучить просто, але власне тут і криється проблема.

Шлях від прототипу, згенерованого ШІ, до повноцінного додатку в App Store

Зараз ШІ достатньо добре створює вебдодатки, які одразу можна побачити в браузері, внести правки і навіть опублікувати на якомусь доступному хостингу. Все це може зробити людина з мінімальним ІТ-досвідом або навіть без. З мобільними застосунками все трохи складніше. За рік ШІ-інструменти дуже сильно еволюціонували, і зараз повноцінний мобільний проєкт може бути створений дуже швидко, але далі починаються проблеми, які людині без технічного бекграунду вирішити складно.

Рік тому, під час роботи з ШІ, мене муляла ця «несправедливість» 😜 щодо мобільної розробки. Я подумав, що було б добре мати можливість створювати повноцінні мобільні застосунки з ШІ, які одразу можна було б бачити і використовувати (запускати) на своїх смартфонах, без усіх технічних складнощів, пов’язаних з розробкою.


Потребу такого підходу підтвердив допис на Reddit — крик душі новоспеченого вайбкодера, який спочатку хвалився, що за 2 години навайбкодив iOS-додаток, а потім — сюрприз! Виявляється, потрібно заплатити $99 за можливість опублікувати цей додаток або навіть встановити на свій телефон на постійній основі.

Далі виникли питання: що таке mobile provisioning profile, для чого сертифікат, що то за налаштування вимагає Xcode, чому в результаті додаток був відхилений Apple тощо. В результаті висновок: я не розробник, я просто хотів додаток, а вайбкодинг обіцяв, що я це можу зробити без технічних знань 😭

Я почав досліджувати цей напрямок. Два класичні підходи, які пропонувала індустрія, це гібридний додаток з нативною оболонкою та динамічним вебконтентом і добре відомий SDUI/BDUI підхід, коли бекенд надсилає JSON з інструкціями, а мобільний клієнт вже рендерить користувацький інтерфейс на основі нього.

На перший погляд вебконтент у нативній оболонці міг би вирішити цю проблему, якби існував нативний застосунок-контейнер (host), у який користувач міг би завантажувати згенерований ШІ вебдодаток. Але без доступу до нативних функцій це по факту той самий мобільний браузер.

А доступ до функцій на кшталт камери чи GPS потребує додаткових фреймворків (JavaScript-bridge), яких багато і серед яких немає універсального. Тобто ШІ довелося б щоразу підказувати, який саме фреймворк використати, а це робить підхід надто складним для генерації додатків самими користувачами. Та й відверто кажучи, я ніколи не був прихильником гібридної розробки 🙃

Інший варіант — це server-driven UI з добре відомим JSON. Десятки великих компаній мають розроблені внутрішні рішення, є деякі публічні, які дозволяють використовувати JSON для опису UI та частково логіки. Але майже всі ці системи проєктувалися до ери LLM, під людей і бекенд-команди, а не під генерацію штучним інтелектом. Крім того, вони мають обмежені можливості для створення повноцінної логіки.

Є ще третій, дуже амбіційний підхід — створити власну мову програмування з нуля. Але перемогла більш прагматична ідея — використати JSON. Це добре відомий формат для передачі структурованих даних. Парсер для JSON є фактично в кожній мові й на кожній платформі, часто прямо в стандартній бібліотеці, а навколо формату давно склалась зріла екосистема інструментів.

Більше того, у типізованих мовах декодування JSON у нативні структури (Swift Codable, Kotlin kotlinx.serialization) саме собою валідує структуру. А оскільки я задумував інтерпретовану runtime-систему, цей крок ставав своєрідним аналогом compile-time-валідації. У звичайній мові структуру перевіряє компілятор перед запуском, а тут ту саму роль бере на себе декодер, і структурні помилки відсіюються ще до того, як опис почне працювати на пристрої.

LLM теж бачили за час тренування терабайти JSON, активно його використовують і добре розуміють. Основним блокером було — як описати повноцінну логіку. Я почав експериментувати в цьому напрямку, і крок за кроком вималювалось рішення, яке дозволяє описати повноцінну логіку мобільного додатку і не лише. Я назвав його StemJSON.

Що таке StemJSON

StemJSON — це декларативна domain-specific language (DSL) на базі JSON. Мова описує дерево компонентів, реактивні стани, події, дії, навігацію і доступ до даних. Один JSON-документ може містити опис цілого екрану, окремої фічі або навіть повноцінного додатку.

Найпростіший спосіб пояснити — показати. Ось повноцінний робочий лічильник:

{
  "id": "hello_module",
  "type": "module",
  "state": { "count": 0 },
  "children": [
    {
      "id": "counter_value",
      "type": "text",
      "context": { "_text": "${count}" },
      "style": { "common": { "font": { "kind": "system", "size": 48, "weight": "bold" } } }
    },
    {
      "id": "btn_plus",
      "type": "button",
      "context": { "_label": "+" },
      "events": {
        "onTap": [
          { "state": { "id": "increment", "input": { "count": "{{ ${count} + 1 }}" } } }
        ]
      }
    }
  ]
}

Лічильник — це «hello world», щоб показати синтаксис. Але щоб зрозуміти, наскільки далеко це заходить, гляньте на інший приклад — шашки. Це повноцінна гра: дошка, правила ходів, взяття шашок, дамки. І найцікавіше тут — суперник.

Гра в шашки, згенерована як StemJSON-модуль

Спрацьовує одна з ключових можливостей StemJSON: модуль може описати звернення до зовнішнього сервісу. У випадку шашок цей сервіс — сама ж мовна модель. Тобто ШІ згенерував додаток, який під час гри сам звертається до ШІ, щоб зробити хід суперника. Виходить така собі рекурсія: ШІ створив гру, в якій граєш проти ШІ 🤖 І все це один JSON-документ, який рендериться нативно на телефоні, без жодного рядка Swift чи Kotlin.

Що важливо: це не «ШІ написав код гри, запусти й молись». Гра — це опис. І цей опис можна перевірити ще до запуску.

Ключові дизайн-рішення

Розкажу про кілька рішень, на яких тримається вся ідея.

Найголовніше — це стан замість коду. У звичайному додатку логіка це код, який виконується. У StemJSON усе інакше: є стан (дані модуля) і є дії, які цей стан змінюють. Кнопка не «виконує функцію», вона описує, який стан треба змінити і як. Ніяких прихованих сайд-ефектів. Через це поведінка модуля передбачувана: одні й ті самі дані завжди дають однаковий екран.

Звідси випливає ще одна важлива річ — усе можна перевірити до запуску. Оскільки модуль це опис, а не програма, його можна проаналізувати статично, тобто зрозуміти, що він робить, які дані читає, до чого звертається, ще до того, як він хоч раз запуститься на телефоні. Для мене це виявилось критичним. Коли додаток генерує ШІ, просто довіритись не можна, потрібен спосіб зловити помилку до того, як вона потрапить на пристрій користувача. Тут це вбудовано в саму природу формату.

Складна логіка будується як ланцюг дій, де кожен наступний крок спирається на результат попереднього. Умови, розгалуження, обробка відповідей описуються декларативно, без «справжнього» коду. Крім того, модуль може описати звернення до стороннього сервісу за заданим сценарієм, і саме це дозволило шашкам «ходити розумом» мовної моделі. Так само можна дістати погоду, курс валют чи будь-що інше.

І окремо про саму специфікацію. Спочатку я писав її для розробників, але коли головним «читачем» став ШІ, виявилось, що йому потрібна інша подача: коротша, без пояснень «для людей», зате щільніша. Тож я тримаю дві редакції специфікації, повну читабельну для розробників і стислу для мовних моделей, утричі меншу. Менше тексту для ШІ означає менше витрачених токенів на кожну генерацію, а отже дешевше і швидше.

А чи безпечно запускати те, що згенерував ШІ?

Питання, яке виникає одразу — якщо ШІ генерує додаток, а він потім працює на моєму телефоні, що завадить згенерувати щось шкідливе?

Тут знову рятує те, що модуль — це опис, а не виконуваний код. Йому не вдасться «непомітно» щось зробити: усе, до чого модуль звертається, хай то камера, мережа чи сховище, задекларовано в самому документі. Тому ще до запуску можна побудувати повний перелік того, на що модуль здатен, і показати або перевірити його. Це принципово інша модель довіри, ніж «завантажив бінарник і сподіваєшся».

Додатково модулі ізольовані один від одного: один згенерований інструмент не має доступу до даних іншого. Тобто навіть у межах одного застосунку трекер води нічого не знає про список покупок.

Перевірка боєм. Pluri

Реалізація моєї ідеї просувалась добре: я допилював специфікацію і необхідні iOS- та Android-рантайм-бібліотеки, усував виявлені проблеми. Намагався генерувати додатки різної складності та покриття, щоб перевірити ліміти і можливості. При цьому я навчився за декілька ітерацій генерувати досить складні додатки (можна глянути приклади на GitHub — для iOS та Android), але це все ще були інструменти для розробників, а не для кінцевих користувачів, фантазія яких може бути нестримна 🤪

StemJSON-модулі, що рендеряться нативно на iOS

Тож мені потрібен був реальний продукт — мобільний додаток, в якому людина без технічних навичок, зокрема роботи з ШІ, могла б згенерувати собі необхідний інструмент, утиліту чи навіть гру. Те, що власне і було початковою ідеєю.

Тут я стикнувся з труднощами. ШІ-моделі через API працюють не так, як через стандартні чати. Більша частина магії залежить від системних промптів, налаштувань та додаткових інструментів. Виявилось, що мало мати специфікацію. Різні LLM-моделі інтерпретують її по-різному через своє навчання, як би дивно це не звучало.

Наприклад, я помітив, що мовні моделі від OpenAI краще слідують специфікації. Claude-моделі, заточені в основному на програмування, більше галюцинують у сторону класичних мов програмування. Довелось методом проб і помилок створювати ще відповідну обгортку із системних промптів та інструкцій, щоб досягти прийнятної якості генерації через API. Це і стало основою для мобільного додатку Pluri.

Pluri — це мобільний застосунок, який дозволяє користувачу звичайними словами описати, що він хоче і який функціонал, і ШІ створить додаток, який можна одразу відкривати і використовувати. Тобто кожен користувач може створити щось унікальне виключно для себе та своїх потреб, а також може поділитись з іншими.

Зверніть увагу на підписи в списку, це і є ті самі описи звичайними словами, з яких народились інструменти: «create a 2048 game», «a daily water tracker built around a circular progress ring». Гра, трекер, словник — це геть різні речі, але всі вони описані однією й тією ж мовою й запускаються нативно на телефоні.

Зараз цей застосунок ще на рев’ю в Apple. І тут сталося майже символічне: один раз Apple відхилив додаток за пунктом 2.5.2, тим самим, що забороняє завантажувати й виконувати код, який змінює функціональність застосунку. Тож зараз я, по суті, доводжу рев’юерам те, з чого починалась уся ця історія: StemJSON це не код, а декларативний опис, який рантайм рендерить нативно. Іронія в тому, що це саме та властивість, яка робить підхід передбачуваним і безпечним, і саме її доводиться пояснювати.

Що вже працює, а що попереду

StemJSON поки що покриває не все. Наприклад, поки немає drag&drop, вбудованих графіків, готової роботи з камерою чи іншими складними бібліотеками. Частину з цього можна вже зараз під’єднати ззовні, через механізм зовнішніх сервісів, але «з коробки», однією лише мовою, це ще не описується. Я свідомо рухаюсь від простого до складного. Cпочатку щоб надійно генерувалось те, що потрібно більшості користувачів, а решту додаю в міру появи реальних запитів і сценаріїв.

Попереду ще багато роботи: розширювати саму мову (нові компоненти й можливості), покривати більше кейсів у генерації, вилизувати якість першої спроби, доводити паритет між iOS та Android. Але головне для мене вже підтвердилось — концепція робоча. ШІ справді може згенерувати повноцінний нативний інструмент за описом звичайними словами, і цей інструмент запускається на телефоні. А далі це вже питання техніки й обсягу роботи.

Де все це подивитись

StemJSON-специфікація опублікована і є у відкритому доступі. Є готові StemRuntime SDK для iOS та Android, які вміють будувати (рендерити) додатки на основі цієї специфікації, і проєкти-приклади для обох платформ, де видно, як усе працює та інтегрується. Все це на GitHub і на сайті stemjson.com.

Окремо виділю MCP-сервер, який я випустив нещодавно. По суті він перетворює ШІ-асистента (Claude, Cursor та інші) на свого роду IDE для StemJSON: дає йому інструменти пошуку по специфікації, скафолдингу й валідації, щоб той генерував коректні StemJSON-модулі чи окремі фічі прямо в робочому середовищі розробника, а далі їх можна вбудувати у власні проєкти. Коли Pluri опублікується, ці ж модулі можна буде запускати і в ньому.

Наостанок про ідею, якої в початковому задумі не було, вона з’явилась уже по ходу роботи. Я називаю її Stem AI Area. Розробник може виділити у своєму застосунку ізольований блок, підключити StemRuntime і дати кінцевому користувачу можливість кастомізувати його власними словами.

Користувач описує потрібну фічу, ШІ генерує, а рантайм одразу рендерить нативний модуль просто на місці, підлаштовуючи застосунок під кожного на льоту. Це вже не просто спосіб згенерувати додаток, а можливість зробити застосунок таким, що добудовує себе під конкретного користувача.😎

Буду радий думкам, конструктивній критиці й питанням у коментарях.

👍ПодобаєтьсяСподобалось7
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Чи підтримує цей підхід взаємодію з бекендом (REST/WebSockets)?
Я думав щодо чогось подібного для генератора різних статусів та дашбордів, які показує додаток динамічного від того, що важливо для мене.

Так, REST підтримується рантаймом з коробки. Достатньо описати remote-репозиторій як dependency, а відповідні CRUD-дії мапляться на HTTP-методи. Авторизація реалізована через interceptor (токен підтягується із захищеного сховища одразу в хедери). Готові приклади: погодний інформер і «інстаграм» з авторизацією через токен. WebSocket-транспорту з коробки поки немає, але для realtime є підписка listen та interval для періодичного рефрешу. При інтеграції рантайму можна зареєструвати власний WebSocket-репозиторій чи сервіс і модуль слухатиме його тим самим listen. Саме так, до речі, підключається Firebase. Якщо API відкрите або має документацію — AI може проаналізувати формат респонсу і згенерувати відповідний дашборд дуже швидко.

Кейс із динамічними статусами й дашбордами — це, можна сказати, рідний сценарій для такого підходу. Єдине застереження — вбудованих графіків поки немає, вони в roadmap. Але табличні дашборди, анімовані прогрес-індикатори чи навіть мапу для гео-статусів можна описати вже зараз.

Какие фундаментальные ограничения этого подхода?

Да, и это глубже, чем перечисленные ранее практические минусы — это структурное ограничение любого DSL такого типа, известное довольно давно.

**1. Закон Гринспена в действии**
Любая достаточно навороченная попытка описать полноценную логику декларативно рано или поздно реализует внутри себя половину обычного языка программирования — просто неявно, без типов, без отладчика, без инструментов. Как только Стем начнёт покрывать сложные кейсы (циклы с условием выхода, рекурсию, конкурентные состояния), схема неизбежно раздуется до полноценного языка в JSON-обёртке. Это не временный пробел «пока не покрыли», а структурный предел — чем шире охват, тем менее декларативным и более «языко-подобным» становится формат, и грань «это не код» стирается сама по себе.

**2. Верифицируется только оболочка, а не поведение**
Его аргумент про «можно проверить до запуска, к чему модуль обращается» — верен только для *поверхности вызовов* (какие API задекларированы), но не для *фактического поведения* через них. Пример с шашками это и обнажает: ход соперника генерирует LLM на лету — то есть реальная логика игры непредсказуема и не проверяема заранее, она просто вынесена за пределы того, что верифицируется. Получается, что чем интереснее и сложнее приложение, тем больше логики убегает во внешние вызовы, и тем меньше остаётся от «безопасно проверено заранее».

**3. Классическая проблема визуального/декларативного программирования**
State+action-chain в JSON — это по сути node-based программирование (как Unreal Blueprints, Node-RED, старые BPMN-движки). У всех них одна и та же известная болезнь: отлично работает для линейной/простой логики, но с ростом вложенности условий и параллельных состояний становится нечитаемым быстрее, чем эквивалентный текстовый код — именно поэтому индустрия давно ушла от чистых flow-based языков к текстовым для чего-либо сложнее интеграционных сценариев.

**4. Нет полноценной observability/debugging модели**
Раз это дерево данных, а не код — нет стектрейсов, брейкпоинтов, привычного дебага. Когда сгенерированный ИИ JSON ведёт себя неправильно, диагностировать «где» и «почему» на уровне дерева состояний сложнее, чем в обычном коде с трассировкой стека — и это не решается тулингом за счёт зрелости, это следствие самой модели (нет call stack, есть только состояние на момент времени).

Итог: подход Стема принципиально ограничен для **всего, что не является тонким слоем оркестрации простых UI-взаимодействий поверх внешних сервисов**. Как только логика внутри самого приложения (а не снаружи, через API) становится нетривиальной, формат либо ломается по расширяемости, либо перестаёт быть «просто декларацией» и по сути становится языком программирования, зашифрованным в JSON — то есть тем самым исполняемым кодом, против которого возражал ревьюер Apple.

Бачу, що статтю «прогнали» через AI 🙂 Непоганий огляд вийшов. І звучить досить правильно і певною мірою точно описує, чим StemJSON є, хоча все розглянуто через призму повноцінної мови програмування, якою StemJSON не являється. Але деякі моменти мені навіть допомогли чіткіше визначити стратегію розвитку StemJSON.

Коли зароджувалась ця ідея — щоб AI мав змогу генерувати мобільні додатки безпосередньо на мобільному пристрої, я не думав про повноцінну мову програмування... радше ідея була у використанні готових блоків, з яких AI міг би швидко зібрати готовий додаток. Не секрет, що більшість мобільних застосунків, і не тільки мобільних — достатньо однотипні. Пригадую, я розглядав можливість використання готових, напрацьованих рішень, модулів, компонентів, які можна було б описати, і рантайм уже побудував би з них функціонал. Ідея зводилась до створення мови для AI з мінімальною свободою. Маючи трохи практики роботи з AI, я розумів, що більше можливостей і гнучкості у виборі рішення — це більше потенційних проблем і помилок генерації. Я застосував той самий принцип, який усе життя застосовую у своїй ІТ-кар’єрі: «менше коду — менше багів». Тому й не намагався проектувати класичну мову програмування чи повноцінну DSL з усіма атрибутами. Я відштовхувався від практичних чинників і задач: що саме мені потрібно для генерації того чи іншого додатку з мінімальним описом, який AI генерував би надійно.

Всі CRUD-репозиторії, сервіси — це властивість не мови, а рантайму. Мова описує тільки мінімальний потрібний контракт для взаємодії з ними і дійсно виступає відносно тонким шаром оркестрації UI зі свідомо обмеженою логікою. Тому й закон Гринспена тут не спрацює сам собою. Без циклів, рекурсії та користувацьких функцій «половина мови програмування» непомітно не наросте — її просто неможливо написати. Чи втримається ця межа під тиском нових фіч — справедливе питання, але це вже питання дисципліни розвитку, а не структурна неминучість.

До речі, дебаг-механізм усе-таки присутній. Він був мені потрібен, коли писав рантайм і треба було відстежувати зміну станів. У JSON брейкпойнт, на жаль, не поставиш 🙂

Поки що те, що я бачу: StemJSON + рантайм потенційно покриває генерацію великої кількості додатків. Звичайно, складні обчислювальні сценарії без зовнішніх сервісів не покриються. Хоча той приклад із шашками, де AI виступає бекендом, потенційно може перекрити й такі сценарії — фактично для рендерингу UI потрібні тільки готові обчислені дані.

Читабельність, розширюваність, дебаг — властивості, які мають ціну насамперед тоді, коли софт живе довго й людина його супроводжує. А тут основний користувач мови — AI, і життєвий цикл трохи інший, ніж у класичного софту. Стосовно безпеки — формат дозволяє не перевірити поведінку повністю, а спрогнозувати її на основі описаних можливостей. Це все-таки краще, ніж закритий бінарник.

Підсумовуючи... StemJSON — не мова загального призначення, у ній за задумом немає примітивів довільного керування потоком виконання (циклів, рекурсії, користувацьких функцій, винятків ітд). Якщо порівняти з класичною мовою програмування, яка дозволяє описати складну логіку з нуля, хоча для більшості прикладних задач цього ніхто не робить, бо є готові бібліотеки — то StemJSON одразу йде шляхом спрощення (декларативності). Генеративні інтерфейси зараз приблизно там, де веб був у дев’яності. Формати й правила гри ще тільки формуються. Тож я сподіваюсь, що StemJSON займе свою нішу.

Для різних нових мов програмування/фреймворків, є чудовий бенчмарк Real World Conduit. Якщо ви напишете реалізацію цього проєкту на StemJSON, то відразу зможете порівняти свою реалізацію з десятками фронт та бек рішень, навіть екзотичними.

концептуально нагадує a2ui.org

Так, концепції дуже схожі, я б сказав — перетинаються. Але A2UI використовує трохи інший підхід. Якщо StemJSON-модуль інкапсулює логіку при генерації, то цей підхід генерує лише UI на основі запиту. Вся логіка виконується AI-бекендом. Щось на кшталт класичного Server-Side Rendering (SSR) у вебі. Я ще детально не розбирався з цим рішенням, але деякі моменти мене зацікавили. Наприклад, я колись хотів, щоб AI міг стрімити StemJSON, тобто UI би регенерувався блочно залежно від запитів користувача. Зараз модуль генерується цілісним, хоча сам модуль фактично може бути невеликим блоком UI (фічею) зі своїм стейтом. Але радує те, що в цьому напрямку працюють навіть такі ІТ-гіганти, як Google, які опублікували своє рішення порівняно недавно.

Я останні років 20 топив за DSL і до сьогодні вважаю їх не до кінця зрозумілою і недооціненою суперсилою. Хоча, може AI трохи вдихне життя в цю підзабуту концепцію.

Але в мене питання — чому на базі JSON? Я можу зрозуміти, чому не кастомний синтаксис — це довго придумувати, відлажувати і писати кастомні парсери. Але чому не щось на кшталт YAML чи більш нові альтернативи?

Як на мене, з JSON є кілька фундаментальних проблем, які трохи заважають йому бути повноціннми DSL (причому більшості цих проблем нема в реальній JavaScript нотації — це все з`являється тільки в JSON spec):
* Нема коментарів
* Багато лишніх синтаксичних елементів — brackets, всі ключі повинні бути в лапках, всі елементи треба розділяти комами, неможливо залишити trailing comma, бо json parser буде сваритися...
* Обмежена кількість типів
* Відсутність посилань між елементами та схожих advanced фіч типу include

Все це можна в JSON тим чи іншим шляхом обійти чи юзати розширені альтернативи типу JSON5, але зазвичай воно виглядає тяжким і не дуже читабельним.

це довго придумувати, відлажувати і писати кастомні парсери.

А що там складного?

Усе правильно, складно було б не погодитися, якби це стосувалося повноцінної DSL, спроектованої для людей, а також класичного підходу до розробки ПЗ: створення, дебаг, реліз, підтримка.

Але початкова ідея була створити інструмент для AI. Я розглядав і YAML, й інші формати, але вибір зупинив усе-таки на JSON. Було декілька причин:

1. Поширений і добре відомий формат. Більшість сервісів, зокрема AI-сервіси, використовують його для генерації структурованих даних.
2. AI добре знає і розуміє цей формат.
3. Декодування з коробки доступне на більшості платформ, можливо, навіть на всіх. Такий собі аналог compile-time validation: якщо StemJSON не декодується, модуль просто не буде відрендерений.
4. Багато документних NoSQL-баз даних використовують JSON або JSON-подібні структури.

Для моїх цілей це виглядало найбільш прийнятним варіантом.

Більше того, у грудні 2025 року Google представив A2UI — декларативний JSON-формат із контрольованим каталогом компонентів на клієнті, принципом «UI як дані, а не код» і підходом, оптимізованим під LLM. Певною мірою в нас спільні концепції, і те, що Google теж зупинився на JSON, говорить на його користь. Хто я такий, щоб не довіряти Google. 🙂

Додам, що життєвий цикл StemJSON трохи відрізняється: запит → генерація → валідація → регенерація → рендеринг. Відповідно, класичний підхід, за якого потрібно вручну дебажити, а потім супроводжувати й розширювати StemJSON-модуль, тут не є основним сценарієм. Найбільша складність — це якість генерації та валідації.

У Pluri я, до речі, реалізував для цього проміжну ланку: людина може валідувати поведінку та UI, а не дебажити JSON, і вже на основі скоригованого промпту — AI вносить зміни.

Коли я проектував DSL і паралельно писав для неї рантайм, щоб перевірити свої ідеї, труднощі справді виникали, бо іноді доводилося самому «читати» JSON. Але основна цільова аудиторія — це LLM, тому читабельність і коментарі тут не відіграють великої ролі. Головне — структурованість, а JSON із цим добре справляється.

У реальності StemJSON можна використовувати для побудови UI та логіки й вручну — це не заборонено. Але тоді справді виникають описані проблеми. Хоча я б і цю роботу радив довірити AI.

1. може неуважно читав, але не побачив механізму як «стан» перетворюється на пікселі на екрані..
2. 50% статті просто опис як працює стейт машина, навіщо це писати, є кращі описи.

Я постійно юзаю фреймворк з декларативним фронтом і, як на мене, з АІ це імба. При такому підході і без АІ швидкість неймовірна, а з АІ взагалі. До того ж занести баги досить складно. Я думаю ідея супер.
А те що пишуть що треба вичити ще одну мову, ну як би ні, не треба. Прописати скіли і АІшка буде генерувати чітко. Думаю коментатори невірно оціннють цільову аудиторію цієї тули.

Дякую за відгук. Мусив спитатися в дочки, що таке «імба» ))))

В сенсі, а як це рев’ювити? Там же кров з очей :-) Ще й динамічна типізація.
Я розумію що влом парсери-лексери робити, як і програмісту вчити 100500ий синтаксис.
Але є ж той же lisp/clojure. Де на виході теж структуровані скобочки, але сам підхід на порядки потужніший.
І чому саме json, якщо є всякі dhall, cue чи hocon, чи amazon ion. Теж мови конфігурації але розвинутіші та читабельніші за жсон.

Схоже, почався зворотний процес в ІТ. Хтось намагається відібрати роботу в AI, а не навпаки 🙂 Основна ідея в тому, що в ланцюжку: «користувач → запит → згенерований StemJSON → робочий функціонал» людини-рев’юера немає. Всю цю роботу виконує AI, а користувач отримує готовий результат. Якщо все ж є бажання переглянути згенерований JSON — є безліч pretty-форматерів, які спростять задачу. Але особисто я б і це довірив AI. JSON він аналізує швидко і на ура.

Стосовно перелічених форматів. Здебільшого в них інше призначення — це конфігурація, а не UI/UX мобільних застосунків, хоча при потребі можна наконфігати будь-що. Але вибір був на користь формату, який LLM генерує, можна сказати, з гарантіями, а платформи декодують штатними засобами. До цього списку я б скоріше додав DivKit, Vercel json-render, Google A2UI, тощо. Вони краще лягають у загальну концепцію. Але жоден з них (поки що) не поєднує опис повноцінної логіки мобільного застосунку з нативним рендерингом. Особливість StemJSON саме в цьому, плюс статична аналізованість і прогнозованість поведінки, що критично для безпеки. Роль модератора тут виконує сам AI. У нього свої запобіжники і на шкідливий промпт він просто нічого не згенерує. Хіба що колись збунтується 🙂

Я не розумію, якщо мова дозволяє звертатись до різних апі — це вже потенційний вектор атак, хіба ні? Умовно, якщо можна і в мережу сходити, і логіку написати, і до девайсу звернутись — то це ж по суті і є виконуваний код! Претензія епл тоді валідна, як на мене

До того ж я не розумію, як тут треба покрити persistence. А ще існують питання з screen orientation, на андроіді це foldable та історія з хром буками, котрі Гугл намагається підживити — тобто адаптивний UI. Не просто розтягнути картинку, але інакше організувати простір на екрані

Мені здається, тут змішались три поняття: мова, софт і платформа. Сама по собі мова безпечна. Інструкція «Як зібрати кулемет» не нашкодить, а зібраний кулемет — може :) У цьому випадку рантайм служить платформою і виконує те, що описано в модулі StemJSON (софт). Тобто відповідь на питання стосовно доступу до локального сховища, мережі чи інших сервісів стосується конкретної реалізації рантайму. Мова — це відкритий формат, тож при бажанні можна написати свій рантайм зі своїми «фішками», обмеженнями та правилами безпеки. Якщо побоювання викликає власне завантажуваність StemJSON у рантаймі та його можливості, то такі сценарії вже давно не рідкість. Наприклад, Apple Shortcuts дозволяють звертатись до мережі і доброї половини системних API, при цьому вони вільно завантажуються за посиланням. Або добре відомий HTML+JS у WebView.

Стосовно адаптивності і persistence — якщо говорити про можливості мови та існуючого рантайму, то він дозволяє працювати через CRUD з локальними сховищами (звичайним + захищеним), а також адаптувати екран до орієнтації. Крім того, при інтеграції рантайму, host app може керувати цим процесом сам, генеруючи кастомні події, які описані в StemJSON-модулі, або навіть підвантажувати потрібний модуль (маленький текстовий файл) для рендерингу іншого UI відповідно до потреб. Імовірно, адаптивність додам в roadmap щоб детальніше розглянути.

Сама по собі мова безпечна.

За такою логікую буть який застосунок безпечний, бо виконується у середині свого адресного простору. Небезпечно лише API, яке надає OS.

уявляю ці товпи народу, які стали в чергу вчити мову василя кричуна 🙂

Підписатись на коментарі