Обновить
128K+

TypeScript *

Cтрого типизированная надстройка для JavaScript

62,68
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Outbox‑паттерн для мобильного мессенджера: как Telegram не теряет сообщения и почему ваш код их теряет

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели4.6K

Это седьмая статья про инженерные решения в ONEMIX. Тема узкая, но болезненная для каждого кто делал мобильное приложение с отправкой сообщений или файлов.

Сценарий с которого всё началось у меня. Пользователь в чате выбирает большое видео, нажимает отправить. Видео начинает грузиться. Пользователь нетерпеливый, прокручивает вверх посмотреть переписку, потом переходит в другой чат, потом возвращается. Что должен он увидеть?

В Telegram он увидит свой видео‑бабл с прогрессбаром, как и оставил. В большинстве самописных мессенджеров он увидит пустой чат без своего сообщения, потому что upload жил в state экрана, а экран размонтировался. XHR продолжал работать в фоне, файл загрузился на сервер, но результат пришёл в null, потому что setter уже не существует. Сообщение фактически отправлено, но пользователь об этом не знает.

Это боль которая лечится не «правильным useState», а отдельным архитектурным слоем. Этот слой называется outbox. В этой статье разберу свою реализацию из ONEMIX, это 820 строк TypeScript которые делают то что в Telegram кажется естественным.

Читать далее

Новости

Как я сделал групповые звонки в React Native мессенджере: WebRTC, CallKit и грабли production'а

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели13K

Это третья статья из серии про инженерные решения в ONEMIX — моём мессенджере на React Native. В первой я разбирал трёхуровневый кэш сообщений, во второй — реализацию Double Ratchet E2E. Сегодня — про звонки.

Звонки в мессенджере — это та функция, которая работает либо отлично, либо никак. Пользователь привык что WhatsApp/Telegram звонят мгновенно, показывают входящие на заблокированном экране, переживают переключения Wi-Fi/LTE, и работают из фона. Если твоя реализация делает хоть что-то из этого хуже — пользователь это сразу заметит и переключится на "нормальный" мессенджер.

Я потратил несколько месяцев на то чтобы довести звонки в ONEMIX до production-уровня. В процессе пришлось изучить WebRTC изнутри, разобраться с iOS CallKit и VoIP push notifications, и собрать десяток граблей которые в туториалах не упоминают. В этой статье — как это устроено, какие решения оказались критичными, и что бы я сделал по-другому.

Сразу оговорка. Я не использую готовые SDK типа Agora, Twilio, 100ms. У них отличное качество и поддержка, но они не дают полного контроля над процессом — а для мессенджера контроль критичен. Когда звонок не проходит, пользователь винит приложение, а не "SDK от третьей стороны". Плюс готовые SDK стоят денег, которые на раннем этапе продукта лучше направить в другие места.

Читать далее

Я реализовал Double Ratchet в React Native мессенджере. Разбор протокола и кода

Уровень сложностиСложный
Время на прочтение16 мин
Охват и читатели8.6K

В прошлой статье про трёхуровневый кэш сообщений я уже упоминал, что делаю мессенджер ONEMIX на React Native. Базовое E2E у меня было простое: ECDH P-256 для обмена ключами при первом контакте, AES‑GCM для шифрования каждого сообщения общим секретом. Это работает, но имеет одну проблему: общий секрет один на всю переписку. Если у одной из сторон скомпрометируют приватный ключ — все сообщения за всё время превращаются в открытый текст.

Это называется отсутствием Perfect Forward Secrecy (PFS). И это значит, что человек, к которому в руки попадёт твой телефон через год, может прочитать переписку из прошлого года. WhatsApp, Signal, и серьёзные части Telegram давно используют другую схему — Double Ratchet — которая ключи переизбретает заново на каждом сообщении. Так делают потому, что любой ключ компрометируется в один момент времени, и компрометация не должна давать доступа ни к прошлому, ни к будущему.

Я реализовал Double Ratchet с нуля для ONEMIX. В этой статье разберу:

Читать далее

Агрегатор LLM, как выбирать живые free-модели и переживать сбои провайдера

Время на прочтение7 мин
Охват и читатели9.9K

Если в проекте появляется выбор LLM, почти сразу возникает соблазн сделать это как можно проще. Взять один большой список моделей, показать его в интерфейсе, выбрать первую free-модель по умолчанию и считать задачу закрытой. На короткой дистанции это выглядит рабочим вариантом. На длинной начинает ломаться сразу в нескольких местах.

Часть моделей числится бесплатными, но отвечает нестабильно. Часть внезапно исчезает из выдачи провайдера. Часть формально жива, но по качеству ответа годится только для демо. Иногда пользователь выбрал одну модель, а провайдер вернул ошибку. Иногда ответ пришел, но уже от другой модели. Иногда список моделей на фронте устарел, а backend уже живет в другой реальности.

То есть проблема тут не в том, как красиво показать список LLM. Проблема в том, как построить агрегатор, который умеет выбирать живые free-модели, переживать сбои провайдера и не врать интерфейсу о том, какая модель реально ответила.

В одном из своих проектов эта задача решалась не через бесконечный каталог моделей, а через более жесткий инженерный контур. Backend получает сырой список моделей от провайдера, очищает его, отбирает только подходящие free-варианты, оставляет по одной модели на бренд, отдает этот набор на фронт, а во время реального запроса умеет сделать fallback на модель другого бренда. При этом в ответе возвращается не только текст, но и actual_model, чтобы интерфейс знал, кто реально сгенерировал результат.

Читать далее

Вопросы на собеседование: Рефакторинг TypeScript

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели7.8K

Собеседования по TypeScript всё чаще проверяют не только знание синтаксиса, но и умение видеть «узкие места» в уже работающем коде. Задача кандидата - не просто сказать «тут ошибка», а предложить более безопасное, читаемое и поддерживаемое решение.

В этой статье собраны практические вопросы, основанные на реальных принципах рефакторинга TypeScript. Каждый пример показывает типичный код, который можно улучшить, и задаёт направление для размышлений.

Читать далее

Разбираем Bulletproof React: как не утонуть в хаосе собственного кода

Время на прочтение11 мин
Охват и читатели8.6K

Помните тот момент, ĸогда вы отĸрываете свой собственный проеĸт, ĸоторый не трогали пару месяцев, и не понимаете, где что лежит? А если ĸ проеĸту подĸлючается новый разработчиĸ, первые две недели он просто бродит по папĸам в попытĸах понять логиĸу автора.

React дал нам невероятную свободу: фунĸциональные ĸомпоненты с хуĸами, состояние в Redux, Context, MobX, Zustand или useState, запросы где угодно и ĸаĸ угодно. Но эта свобода имеет обратную сторону — отсутствие стандартов.

Каждый разработчиĸ пишет «по‑своему». В одном проеĸте мирно сосуществуют устаревшие подходы с современными, запросы ĸ API разбросаны по всему ĸоду, а состояние приложения напоминает спагетти. Проходит полгода, и даже автор ĸода с трудом объясняет, почему все устроено именно таĸ.

Знакомо?

Существует архитеĸтура, ĸоторая решает эти проблемы. Она называется Bulletproof React. Это не очередной шаблон или стартовый boilerplate. Это философия и набор лучших праĸтиĸ для создания production‑ready приложений, ĸоторые не превращаются в хаос через месяц разработĸи. В этой статье я постараюсь разобрать эту архитеĸтуру детально: от струĸтуры директорий до тестирования и безопасности. Данный материал будет полезен и новичĸам, ĸоторые тольĸо начинают задумываться об архитеĸтуре, и опытным разработчиĸам, ищущим проверенные решения.

Читать далее

Как я сделал трёхуровневый кэш сообщений в мессенджере на React Native — и что узнал по дороге

Уровень сложностиСложный
Время на прочтение14 мин
Охват и читатели8.7K

Я делаю мессенджер ONEMIX на React Native. К моменту, когда я начал писать этот пост, в нём уже больше десятка экранов, групповые WebRTC-звонки через LiveKit, E2E на Double Ratchet + Sealed Sender, push-нотификации с cold-start навигацией и десктоп-версия на Electron. Но самым важным куском, который определяет ощущение от приложения, оказался не звук и не видео. А то, насколько быстро открывается чат.

Если вы хоть раз делали список сообщений на React Native, вы знаете эту боль: открыл чат — пустой экран на 200–800 мс, потом подгрузка, потом скачок при докрутке наверх. В Telegram такого не бывает: открыл — мгновенно увидел последние сообщения, прокрутил наверх — никаких пустот, история идёт сплошной лентой.

Я разбирался с этим несколько месяцев. В итоге пришёл к трёхуровневой архитектуре кэша, которую и хочу разобрать. Это не теория — это код, который сейчас работает в продакшне. Покажу как реализовано, какие были тупики и какие решения оказались критичными.

Читать далее

30 дней: блочный конструктор README — один DOM, два хозяина

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели7.2K

Мы живём в эпоху когда можно написать в чат «сделай мне CRUD» и получить рабочий код через десять секунд что в принципе удобно. И это, если честно, главная причина почему я периодически намеренно лезу в что-то сложное руками — чтобы не разучиться думать о том что происходит внутри.

ИИ я использую. Но в этом проекте он был исключительно быстрой документацией — особенно когда добрался до selection/range API, про которые до этого знал чуть меньше чем ничего. Реализация все равно была за мной.

Так вот — ReadGen. Блочный конструктор README-файлов. Месяц, 2-3 часа в день, React и TypeScript и небольшая пачка дополнительных библиотек для разумного облегчения жизни. Важно понимать что это не коммерческий продукт и не претендует на решение чьей-то боли. Просто техническая задача которую я давно хотел разобрать.

Читать далее

Структура Vue проекта

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели12K

Правильная файловая структура - скелет любого фронтенд-приложения. В Vue 3 нет строгих предписаний, как раскладывать файлы по папкам, кроме базового разделения components/views/. Но с ростом проекта хаотичное размещение кода быстро превращается в проблему. В этой статье разберём популярные подходы к организации Vue-проектов: от простейшего плоского до микрофронтендов.

Читать далее

React stack 2026: карта лучших библиотек по категориям

Уровень сложностиСредний
Время на прочтение71 мин
Охват и читатели9.9K

Открываете очередной React-проект в 2026 году и смотрите на белый экран package.json. Какой роутер? Vite или Next.js? shadcn/ui или Mantine? Zustand или всё-таки Redux Toolkit? React Hook Form или TanStack Form? И как вообще теперь делать таблицы — TanStack Table или AG Grid?

Каждая из этих категорий за последние 2-3 года прошла через смену лидера. То что было стандартом в 2022 (Redux, Material UI, Webpack, styled-components, Formik), в 2026 либо в legacy-режиме, либо проиграло свежим конкурентам. Те кто работают в одной экосистеме годами, могут не заметить как сместились веса в соседних слоях стека — пока не открывают новый проект и не сталкиваются с тем что “стандарт”, которым они пользовались, теперь редко выбирают.

Эта статья — карта актуального React-стека 2026 года, разбитая по 60+ категориям. По каждой — что выбрал бы я для нового проекта в 2026, какие есть альтернативы для специфических случаев, что считается legacy и почему. Плюс — типовые комбинации стека под разные виды проектов (SaaS dashboard, collaborative editor, real-time dashboard, streaming app, consumer landing).

Читать далее

TeachTrack: NestJS + Telegram‑бот напоминаний + РКН — как я в одиночку собрал CRM для частных репетиторов

Уровень сложностиСредний
Время на прочтение19 мин
Охват и читатели11K

Месяц назад я выложил на Хабр статью про TripTrack — GPS‑трекер для машины на iOS, который собрал будучи бэкендером без опыта в Swift. Статья неожиданно набрала 7.4К (на данный момент написания) просмотров. Но, мне посчастливилось поработать по своей специальности, не только под IOS‑приложения, а под NestJS бекенд.

Параллельно с TripTrack я писал второй проект — на этот раз ровно в зоне комфорта (NestJS + PostgreSQL), и это позволило развернуться по‑серьёзному: транзакционный outbox для идемпотентных отправок в Telegram, single‑use invite‑токены с защитой от enumeration, timezone‑aware scheduler, partial unique indexes — словом, всё то, что для бэкендера интересно само по себе.

Под катом — про то, как устроен Telegram‑бот напоминаний в TeachTrack, что я понял про pessimistic_write и FOR UPDATE SKIP LOCKED, зачем pet‑проекту с реальными пользователями из РФ нужно уведомление в РКН, и почему холодный аутрич преподавателям английского научил меня важной вещи про русский менталитет.

Читать далее

Frontend Status: свежий дайджест фронтенда и AI — 06.05.2026

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели12K

Привет!

Это 15-й выпуск Frontend Status — дайджеста по фронтенд-разработке.

В этом выпуске:

📺 MoscowJS 70 про инженерную культуру в действии: доклады и круглый стол показывают, как командам быстрее синхронизироваться и принимать сильные технические решения.

⚛️ React Server Components и кеширование страниц: разбираем partial page caching, чтобы ускорять загрузку и снижать стоимость рендеринга без потери актуальности контента.

🤖 AI из «вау-демо» переходит в дисциплину: разбираем рабочие промпт-пайплайны и практики Claude Code, которые дают предсказуемый результат, а не случайный успех.

🛡️ Безопасность больше не факультатив: кейс критической уязвимости в GitHub и массовый багхант в Firefox напоминают, как быстро один пропуск превращается в инцидент.

🎨 CSS и анимации взрослеют: от scroll-driven подходов до нативной случайности и новых API, которые делают интерфейсы богаче без тяжёлого JS.

⚡ JavaScript и React на новом витке: ES2025/ES2026, типизированные контракты, React Compiler, TanStack Form и useHotkeys как база для масштабируемой фронтенд-разработки.

🌐 Стандарты и платформа двигаются вперёд: Baseline, Long Animation Frames, CBOR-LD и апдейты WebGPU меняют практику производительности и межплатформенной разработки.

…и многое другое.

Читать далее

TokenToad: как я сделал Chrome-расширение, чтобы перестать удивляться счетам за AI

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели8.5K

Расходы на AI API копятся незаметно: сессия Claude Code тут, batch к GPT-5 там — и к концу месяца биллинг удивляет. Собрал бесплатное Chrome-расширение, которое показывает траты Anthropic, OpenAI и Gemini в реальном времени прямо в badge браузера.

Читать далее

Ближайшие события

Migration toolkit для 1С Битрикс: переносим аккаунт между инстансами через crm.*.list + идемпотентность по ORIGINATOR_ID

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели9.4K

В предыдущей статье (как отдавать лиды из Next.js в 1С Битрикс) я показывал outbound‑интеграцию: сайт пишет лид к себе в PostgreSQL, через after() отдаёт его в Битрикс, в строку лида подкладывает bitrix_id. Архитектура работает, пока Битрикс один.

Но в реальной жизни Битрикс редко остаётся один. Сценарии, в которых нужна полноценная миграция между инстансами, я ловил на проектах четыре раза за последний год:

Читать далее

CraftHub для VS Code: редактируй JSON как таблицу прямо в редакторе

Уровень сложностиПростой
Время на прочтение3 мин
Охват и читатели7.8K

Если вы хоть раз ловили себя на том, что ищете нужную строку в 300-строчном JSON — эта статья для вас. CraftHub теперь живёт прямо в VS Code: открыл файл, переключился в таблицу, поправил, переключился обратно

Читать далее

Монорепозиторий — стрем или норм?

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели10K

Наверное, у каждого разработчика был момент, когда бизнеса в жизни становится слишком много. Слишком много хотелок. Слишком короткие сроки. Слишком мало времени подумать.

И в этот момент код перестаёт быть инженерной задачей. Он превращается в бесконечное тушение пожаров.

Требования меняются быстрее, чем ты успеваешь их осмыслить. Приоритеты «на вчера». Технический долг растет не потому, что вы плохие разработчики, а потому что у вас просто нет времени быть аккуратными.

Читать далее

Откуда пришли пользователи: first-touch attribution для NestJS + React + Telegram Mini App в 100 строк кода

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели9.9K

Я делаю голосовой AI-репетитор английского. Продукт живёт в трёх местах:
веб-сайт speakwithai.pro, Telegram Mini App и Android-приложение в RuStore. У меня одна и та же база пользователей на NestJS + Postgres, и мне очень нужен ответ на вопрос: откуда вообще приходят люди?

Yandex.Metrika и Google Analytics показывают только сайт. Telegram Mini App для них — чёрный ящик. Android-приложение через WebView — тоже. Из 6000
просмотров статьи на Habr я не мог сказать, сколько оттуда пришло в продукт, и через какой канал (TG, веб, app).

Я не хотел тащить большую CDP вроде Mixpanel или Amplitude — для
соло-разработчика это overkill. Вечером сел и сделал simplest-thing-that-could-possibly-work: одна колонка в БД, парсится при первом визите, читается на регистрации. 100 строк кода. Делюсь.

Если интересно посмотреть на сам продукт — он живёт здесь:
🤖 Telegram-бот
🌐 Веб-версия
📱 Android в RuStore

Читать далее

Личный кабинет колледжа на Next.js: как я подключился к 1С: Колледж ПРОФ без «дорогой лицензии»

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели9.2K

Студенты попросили нормальный онлайн-доступ к оценкам и расписанию. В колледже уже была 1С:Колледж ПРОФ, но без удобного веб-интерфейса для студентов. Я сделал личный кабинет на Next.js, где браузер работает с моим сервером, а сервер — с 1С через HTTP-сервисы. Рассказываю, как устроил авторизацию, журнал, расписание, заказ справок и что оказалось самым сложным на стыке 1С и JSON.

Читать далее

Типобезопасный HTTP API на TypeScript без кодогенерации: @cleverbrush/server и @cleverbrush/client

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели8K

Статья о том, как единый типизированный контракт позволяет получить проверяемые на этапе компиляции сервер, клиент и React-хуки — без кодогенерации и без дублирования типов.

Дисклеймер: все описываемые библиотеки носят экспериментальный характер — они созданы в рамках эксперимента. Несмотря на это, покрытие тестами у них достаточно хорошее.

Читать далее

Безопасность приложений на Typescript от А до Я: гайд по защите от очевидных и не очень уязвимостей

Уровень сложностиПростой
Время на прочтение14 мин
Охват и читатели9.1K

Я часто замечаю, насколько некоторые разработчики халатно относятся к вопросам безопасности своих приложений. И начинают задумываться о методах защиты только тогда, когда уже приходится переписывать большую часть приложения. Сегодня мы пройдемся по классическим и не только методам атаки, посмотрим, где компилятор бессилен, и построим современную защиту, опираясь на лучшие практики и конкретные примеры кода.

Погрузиться в мир уязвимостей
1
23 ...