БлогСообщество

Fuma Nama: философия опенсорсника

Почему Fuma Nama верит в меньшую абстракцию, меньше навязанных решений и удобство для читателя.

Taylor Fang

О грантах General Translation для проектов с открытым исходным кодом

Дух открытого исходного кода лежит в основе всего, что мы делаем в General Translation. Наши ключевые библиотеки для интернационализации (i18n) распространяются с открытым исходным кодом по лицензии MIT.

Теперь мы поддерживаем и других разработчиков, которые создают и сопровождают программное обеспечение с открытым исходным кодом на общее благо: для начала — 15 000 долларов безвозмездной помощи и 75 000 долларов в кредитах платформы GT на пятнадцать разработчиков. Номинации принимаются постоянно и по-прежнему открыты! Подробнее — здесь.

Fumadocs

Главная страница Fumadocs

Мы рады представить первый проект — получателя нашего гранта: Fumadocs, созданный Fuma Nama.

Fumadocs — красивый и гибкий фреймворк документации на React. Он состоит из четырёх модульных слоёв: Ядро, Content, UI и CLI. И архитектура, и визуальный дизайн вырастают из ключевых принципов проекта — компонуемости и простоты. Каждая библиотека представляет собой набор «строительных блоков», которые не скрывают своё устройство и позволяют разработчикам менять и создавать документацию ровно так, как им хочется. Визуальный дизайн сочетает элегантные и производительные компоненты с вниманием к мельчайшим деталям. Получается молниеносно быстрое чтение — как для людей, так и для LLMs.

Fumadocs используют Vercel Turborepo, shadcn/ui, BetterAuth, Unkey и многие другие. То, что все эти сайты выглядят совершенно по-разному, — лучшее свидетельство компонуемости Fumadocs. И, конечно же, General Translation использует Fumadocs для собственной документации!

Fuma Nama

Fuma Nama

Open-source developer and creator of Fumadocs.

Fuma Nama, создатель Fumadocs, глубоко продумал опыт разработчика. Каждому слою и каждой детали фреймворка уделено невероятное внимание: от организации контента ради читаемости до сокращения абстракций и баланса между простотой поддержки и возможностями настройки.

Мы поговорили с Fuma Nama — это его первое в жизни интервью — о более чем трёх годах разработки Fumadocs и ещё большем числе лет работы над проектами с открытым исходным кодом. (Знали ли вы, что школу он окончил только в прошлом году?)

Ниже — рассказ о том, как Fuma Nama научился программировать, изучая файлы с кодом, что он думает об «опинионированном» программном обеспечении, почему его библиотеки следуют подходу «меньше магии», почему открытый исходный код по своей природе глобален, и о его философии читательского опыта в документации. А по пути вас ждут пасхалки: например, откуда взялся его псевдоним и как луна вдохновила логотип Fumadocs.

Яркий мир компьютера

Fuma Nama вырос в Гонконге. Его семья купила компьютер, когда ему было 6 лет. Он пишет, как ребёнком бродил по Всемирной паутине и впервые ощутил «яркий мир компьютера». Его восприятие программ пронизано волшебством и игрой. В начальной школе он на скорую руку собрал песочницу на Unity, в которой игрок мог пересаживаться из машины в самолёт и обратно среди разных пейзажей: пустыни, Луны, разрушенного города, гор и леса.

Понятие «программное обеспечение как концепция» пришло к Fuma позже. Кодить он научился, делая моды к видеоиграм и занимаясь обратной разработкой. Он рассказывает, что осваивал C#, разглядывая код, меняя его и наблюдая, что изменилось в игре.

«Это довольно безумно. Я учился программировать по файлам. Видел огромную гору JavaScript и просто читал её, — говорит он. — Я вообще не заглядывал ни в какую документацию, только в сам код».

Обращаясь напрямую к «первоисточнику» (пусть и случайно), Fuma на глубоком уровне усвоил самые базовые принципы мышления. Он схватывал идеи, стоящие за фреймворком, а не ярлыки, навешанные на поведение. На вопрос о любимой стороне архитектуры программ Fuma до сих пор указывает на старое доброе ООП (объектно-ориентированное программирование) в Java — выбор почти радикально простой.

«Идея объекта очень изящна. Я мыслю категориями расширения классов, — говорит он. — Это универсальная модель, которая одинаково работает и в Java, и в JavaScript, и во многих других языках, с которыми ты сталкиваешься».

На своём сайте Fuma Nama называет себя «open sourcerer». После того как он с нуля освоил C#, неудивительно, что современные веб-фреймворки вроде React.js и Vite он описывает как «сияющие и волшебные». В его отношении к программированию есть что-то от колдовства — ощущение безграничных творческих возможностей.

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

«То, что кто-то другой чувствует, когда рисует, я чувствую, когда пишу код», — говорит Fuma.

Экосистема открытого исходного кода

Fuma прекрасно понимает, что библиотеки с открытым исходным кодом — это накопленное видение и труд множества разработчиков.

«Интересно, что ты можешь прикоснуться ко всем этим идеям, над которыми работало множество людей и в которые вложено столько сил, — говорит Fuma Nama. — Это как чувствовать природу и весь земной шар. Ты буквально ощущаешь людей со всего мира».

«Например, над [React] Server Component трудилось множество блестящих умов. Процесс RFC означал, что в него было вовлечено много разработчиков наряду с основной командой React», — сказал он, имея в виду процесс Request For Comments.

Когда Fuma начал работу над тем, что впоследствии стало Fumadocs, он изначально назвал проект «Next-docs».

«Мне казалось забавным сделать официальный фреймворк документации для Next.js — амбиция довольно безумная, — говорит он. — Но это был эксперимент: Server Component только-только появился, шла эпоха App Router, и это был интересный паттерн, который я ещё не пробовал. Для меня сам код — как игрушка, которую хочется опробовать».

Позже он переименовал свой фреймворк в Fumadocs, чтобы не пересекаться с официальной документацией. (Псевдоним Fuma Nama родился из шутливой игры слов с японским ふわふわ, «фува-фува», которым описывают что-то лёгкое и воздушное. Идеальный опыт разработчика, можно сказать.)

Fumadocs вырос при мощной поддержке сообщества открытого исходного кода. Больше всего Fuma радует конструктивная обратная связь.

«Мне нравятся ответы с вопросом или что угодно, что помогает мне улучшать фреймворк», — говорит он. Fuma до сих пор ссылается на issue, созданный разработчиком Anthony Shew два года назад. В своём запросе на новую возможность Shew подмечает, что замысел Fumadocs сильно тяготеет к принципу «меньше магии, больше компонуемости».

«Он был одним из первых, кто внедрил [Fumadocs] в крупном проекте, — говорит Fuma. — Он дал мне ценную и по-настоящему конкретную обратную связь. Он действительно понимал цели проекта, и ему было не всё равно, — это меня удивило».

С тех пор Fumadocs набрал более 13 000 звёзд на GitHub и используется такими компаниями, как Vercel, Unkey, Orama, — и нами в том числе. За последние три года Fuma Nama продолжал развивать и поддерживать фреймворк, вложив в него сотни часов помимо учёбы и других обязанностей.

За стремлением Fuma Nama к мастерству стоят более глубокие взгляды на фреймворки веб-разработки и проектирование программного обеспечения.

Меньше абстракции, меньше навязанных решений

В разделе Philosophy документации Fumadocs Fuma формулирует основной тезис: Fumadocs задуман как фреймворк для документации, который можно сломать.

Под «ломаемостью» он понимает возможность разработчика разобрать на части и перекроить любой элемент фреймворка. Дух Fumadocs — служить тем, кому нужна не просто работающая документация, а «идеальная документация»: подогнанная под их уникальные потребности, предпочтения и чувство прекрасного.

«Нам нужна по-настоящему компонуемая система, — говорит он. — Фреймворк, который достаточно полон и при этом предельно компонуем». Fumadocs стремится дать разработчикам модульные и понятные кубики Lego, из которых можно самыми разными способами собирать совершенно разные сайты с документацией.

Подход Fuma вырастает из более общего диагноза: современные веб-фреймворки слишком абстрактны. Ими «волшебно» легко пользоваться, потому что сложность спрятана; но за этим же скрываются внутренняя логика, механика и неизбежные компромиссы. Например, начинающий разработчик может использовать Metadata API в Next.js, не понимая, как работает мета-тег, или поместить логику в Server Component, не представляя, во что обойдутся вычисления.

Избыток абстракции мешает разработчикам по-настоящему видеть, понимать и изменять код. Поэтому его цель для Fumadocs — быть «менее волшебным». Фреймворк кладёт файлы маршрутов в ваш repository, предлагает вам самим создать обработчик поиска, позволяет вызывать загрузчик контента из вашего собственного кода и умеет копировать UI-компоненты прямо в вашу кодовую базу через CLI.

Fuma прямо говорит, что фреймворк ничего не навязывает. Термин «opinionated software» описывает фреймворк или библиотеку, которые закрепляют набор соглашений и ведут пользователя к единственному «правильному» способу разработки. (Иногда это путают с наличием собственной позиции вообще или считают безусловно хорошим свойством.) Такое программное обеспечение — с жёсткими значениями по умолчанию и «единственно верным» путём — противоречит целям Fuma: компонуемости, ломаемости и меньшей абстракции.

Таким образом, Fumadocs — это фреймворк с меньшим количеством магии и меньшим количеством навязанных решений.

При этом Fuma всё же признаёт: разработчикам нужно помогать — здесь и сейчас, готовыми и полными решениями. Ради этого он спроектировал UI-библиотеку как более «навязчивый» слой фреймворка с выразительным визуальным оформлением по умолчанию. Так разработчики могут сразу получить элегантно выглядящую документацию, сохраняя возможность изменить каждый модульный элемент. (А значит, при желании полностью заменить UI на свой.)

«Самая трудная задача Fumadocs — балансировать между двумя крайностями пользователей, — говорит он. — С одной стороны, разработчики, которые не хотят ничего менять и хотят просто быстро и легко стартовать. С другой — те, кто хочет настроить всё так, что исходную форму едва можно узнать».

Такой баланс — вызов для большинства авторов фреймворков и библиотек, и это лишь один из множества компромиссов, о которых Fuma Nama размышлял всерьёз.

Чёрный ящик и компилятор

Поставка кода в виде package — привычный выбор по умолчанию для библиотек — стала для Fuma тщательно взвешенным решением.

«Для большинства разработчиков package — это своего рода чёрный ящик, если только они не заглядывают в исходный код, — говорит Fuma. — Конечно, код всегда можно поправить патчем. Но как только вы упаковали его в package, вы фактически перестаёте понимать, что происходит внутри».

С ростом масштаба проблема только усугубляется. «Чем больше логики вы закладываете в package, тем больше кода вы складываете в чёрный ящик», — говорит он.

Альтернативный подход — модель shadcn/ui, при которой компоненты копируются прямо в ваш codebase, — снимает проблему чёрного ящика. Но у него есть свои минусы.

«Стоимость поддержки всегда ложится на вас, — говорит он. — И каждый раз, когда фреймворк улучшается или получает новую возможность, вам приходится основательно рефакторить код. В какой-то момент это просто перестаёт иметь смысл».

В Fumadocs Fuma ищет баланс в этом компромиссе, встраивая постепенные «аварийные выходы». Package остаётся основной моделью, а CLI (вдохновлённый shadcn/ui) выручает разработчиков, которым понадобилась более тонкая настройка. CLI работает на уровне компонента и может спускаться ещё глубже, вытягивая отдельный slot макета (например, только оглавление). Copy компонента принадлежит разработчику, а prop slots встраивает её обратно в окружающую структуру, так что будущие releases могут и дальше обновляться из package Fumadocs, не перезаписывая её.

За кулисами Fuma Nama называет CLI одной из самых сложных в реализации частей. По сути это компилятор, который должен взять исходный компонент из package и превратить его в standalone files, совместимые с целевым проектом и фреймворком.

«Нужно преобразовать рабочий компонент из package обратно в нечто самостоятельное, изолированное в файле, который можно скачать в codebase, — объясняет он. — Мне пришлось изучить все фреймворки и провести массу тестов, чтобы убедиться, что AST построен верно». (Преобразование абстрактного синтаксического дерева (Abstract Syntax Tree) включает разбор исходного файла компонента в дерево, переписывание путей импорта под назначение и адаптацию синтаксиса.)

С появлением CLI четыре модульных слоя фреймворка сложились полностью: Content, Ядро, UI и CLI.

Content layer fumadocs-mdx Built-in source CMS adapters Notion, Sanity Local files Markdown, HTML API generators OpenAPI, GraphQL Core layer fumadocs-core Source loader Builds page tree Search FlexSearch, Algolia MDX plugins Headings, TOC, code UI layer fumadocs-ui Radix UI base-ui Base UI variant shadcn shadcn/ui variant React app Next.js React Router TanStack Start Waku Dev tooling create-fumadocs-app Scaffold a docs app @fumadocs/cli Add + customize UI components

Fuma описывает Fumadocs как «набор утилит и MDX-плагинов». Его любимая integration — Story, созданная для документации библиотек компонентов. Именно в Story Fumadocs раскрывается по-настоящему: интерактивные компоненты невозможно показать в чистом Markdown, и для менее гибких фреймворков документации это серьёзное ограничение.

«Даже если бы я начал всё с нуля, думаю, Fumadocs получился бы примерно таким же, — говорит Fuma. — Это фреймворк, который действительно можно сломать, и он был скрупулёзно спроектирован именно таким».

Дизайн-кредо Fumadocs

Философия дизайна документации у Fuma тяготеет к минималистичному пользовательскому опыту с глубоким вниманием к каждой детали; его визуальный вкус созвучен вере в простоту кода.

«Меня привлекает абстракция формы в дизайн-искусстве. Я стараюсь применять это в собственных работах, чтобы изображать что-то с помощью геометрических фигур, — рассказал он. — Логотип Fumadocs — это круг, который я бы назвал луной, Luna».

«Я потратил уйму времени просто на проработку деталей. Стандартный макет менялся много раз, и в каждой версии были совсем небольшие изменения», — сказал он.

Fuma Nama считает, что «броский, притягивающий взгляд UI» больше подходит для лендинга, тогда как страницы документации должны быть сосредоточены на содержании и простоте чтения.

Оформление оглавления (TOC) — один из примеров ненавязчивой, но глубоко продуманной визуальной детали Fumadocs.

Слайдер Fumadocs

«Меня вдохновил слайдер в документации Clerk. Но мне хотелось сделать это иначе и красивее», — сказал он. Механика слайдера непроста из-за серверного рендеринга. Сервер рисует контур, но не может снять размеры в браузере, поэтому интерактивную часть приходится пересобирать на клиенте. Работает это так: форма контура повторяется SVG-путём и применяется как CSS-маска, а за ней скользит светящийся блок — благодаря чему подсветка «активного раздела» движется вдоль линии.

«Полагаю, люди могут этого и не заметить», — размышляет Fuma. Но мелкие детали всё равно стоят усилий, и очевидно, что его внимание к нюансам визуального дизайна рождается из общей заботы об опыте разработчика и читателя.

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

Идеальный софт

Следующая итерация Fumadocs Plus будет устроена проще — чтобы лучше подходить как новичкам, так и ИИ. «Чем меньше сложности, тем лучше для ИИ, — объяснил Fuma. — Потому что, как мы знаем, ИИ вполне способен галлюцинировать».

Он отмечает, что issue стало приходить меньше, чем раньше, — вероятно, из-за агентов, которые не заводят issue, а просто обходят проблему. Выстраивать обратную связь стало сложнее. «Если агенты не сообщают о багах, я не могу их исправить, — сказал он. — Но я по-прежнему активно работаю над всеми проектами и стараюсь держать количество issue минимальным».

Он приветствует вклад со стороны сообщества открытого исходного кода. «Если вы хотите добавить функцию или что-то ещё в мои репозитории, просто откройте issue и напишите, что хотите внести вклад, — сказал он. — Я с радостью это рассмотрю».

«Надеюсь, Fumadocs станет фреймворком документации для веба, — сказал он. — И я хочу и дальше делать его стандартом для UI».

Fuma также разрабатывает другое ПО с открытым исходным кодом: сейчас в активной работе tegami — инструмент для управления changelog’ами и versioning, — и fumadb, database API для библиотек.

«Думаю, открытый исходный код будет только расти по мере того, как всё больше компаний начнут признавать сообщество и отдавать ему должное», — сказал он. Он отметил, что ИИ меняет экосистему, снижая стоимость поддержки проектов и давая мейнтейнерам больше свободы.

Источником вдохновения в мире открытого исходного кода Fuma называет Daishi Kato — особенно его RSC-фреймворк Waku и библиотеку управления состоянием Jotai.

«Waku сильно недооценён. Ключевая идея в том, что он предельно минималистичный и композиционный, — именно поэтому я и построил на нём Fumadocs и многие другие проекты», — сказал он. Совпадение их философий заметно невооружённым глазом: сайт Waku описывает фреймворк как «лёгкий» и дающий «увлекательный опыт разработки».

Fuma потратил огромное количество времени на свои проекты с открытым исходным кодом, вложив в них кропотливый труд, который зачастую остаётся невидимым. Все свои проекты он считает сокровищами, работа над которыми не заканчивается.

«Я хочу создавать идеальный софт, — сказал он. — Ноль issue в моих репозиториях — вот, пожалуй, моя цель». Если идеальное ПО и существует, то создать его вполне может именно Fuma Nama.