Привет! Меня зовут Родион, я стажер фронтенд-разработчик. Когда-то в 2022 году писал свои первые сайты на нативном HTML, CSS и JavaScript. С тех пор успел поработать в стартапах и на фрилансе, и вот опыт завел меня в мой первый бигтех — MTS Web Services.
Проект, с которым работает моя команда управления производством, пишется уже не первый год. Когда я только устроился в компанию и впервые увидел его структуру, то подумал, что разбираться в ней займет примерно весь стажерский срок. Нужно было понять логику всех вложенностей, правил, «исторических особенностей», но в реальности хотелось поскорее приступить к работе.
В первые дни мне дали задачу по созданию нового виджета. На проекте их уже было много, так что где-то должны были храниться файлы, в которые я планировал дописать строчки, а еще папки, чтобы добавить новые компоненты. Звучит элементарно, на поиск нужных мест я потратил около часа. Просто на то, чтобы понять, где все это лежит.
Такой расклад меня, конечно, не устроил, и я пошел смотреть, что с этим можно сделать, — так и познакомился с Cursor. В этом посте расскажу, как настроил его под проект, какие промпты использовал, благодаря чему реально сэкономил время, и как боролся с багами. Надеюсь, будет полезно таким же как и я начинающим специалистам.

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

То есть каждую строку видно до того, как она попадет в файл. Можно принять все правки сразу или пройтись по каждой. Для меня как стажера это показалось важным. Конечно, опытные разработчики часто включают автоприменение, потому что вручную принимать правки в десяти местах это потеря времени, а не безопасность. Чем лучше ты понимаешь проект и чем точнее твои промпты, тем меньше нужен ручной контроль каждой строки. Я пока на том этапе, когда лучше перепроверить, чем потом разбираться с последствиями.
Еще Cursor не загружает в модель все файлы разом, а индексирует кодовую базу при открытии проекта — разбивает файлы на смысловые куски (функции, классы, экспорты) и превращает их в векторные представления. По этим индексам он ищет релевантные куски и отправляет их в модель вместе с промптом. Единственный момент: если файл слишком большой или проект представляет собой монорепозиторий, он начинает сильно тормозить и дает неточные изменения (о чем я узнал чуть позже).
Под капотом Cursor использует ChatGPT, Claude, Deepseek и Grok. Поэтому он может анализировать весь проект целиком, а не только дописывать функции или создавать переменные. Это мне как раз и было нужно.
Как я подружился с Cursor
Первым делом попробовал написать промпт: «Я стажер фронтенд-разработчик на данном проекте. Работаю два дня и не могу разобраться с архитектурой. Помоги мне понять, где находятся файлы и папки, связанные с созданием новых виджетов».
В ответ Cursor не написал ни строчки кода, но четко объяснил структуру: какой файл за что отвечает, куда добавляются компоненты, где лежат типы. Именно то, что до этого я пытался найти целый час:

Дальше я задавал вопросы, просил исправить проблемные места, уточнял поведение незнакомых модулей. По ходу диалога Cursor все меньше нуждался в дополнительных объяснениях, быстро улавливал контекст и предлагал правки, которые вписывались в правила проекта.
Например, в проекте был модуль с непонятным названием, внутри которого была функция на 80 строк без комментариев. Я спросил: «Что делает эта функция и зачем она здесь вызывается?» Из ответного сообщения узнал, почему именно такая трансформация и что трогать эту логику опасно, ведь она используется еще в трех местах. И на это ушло 30 секунд.
Но это сработало, потому что функция была относительно простой. Когда я попробовал тот же прием на модуле с нетривиальной асинхронной логикой, ответ был уверенный и связный, но часть деталей оказалась все-таки неточной. А узнал я об этом только потому, что мои изменения просмотрел сеньор. Cursor хорошо справляется с читаемым кодом, но чем больше сложностей, тем выше шанс галлюцинации, — это стоит учитывать.
После реализации нового виджета приступил к следующей задаче — созданию формы. Ну и так шаг за шагом познакомился со всем проектом. И вот что я делал и понял в процессе.
Четко формулировал промпты
Отдельно стоит поговорить о запросах. Расскажу, по какой логике их писал.
Во-первых, сразу давал контекст. Не просто указывал, что нужно сделать или что хочу увидеть, а объяснял, зачем я это делаю. Например, вместо «Исправь эту функцию», использовал «Эта функция отвечает за авторизацию, сейчас она падает при пустом токене — нужно добавить проверку и вернуть понятную ошибку». Благодаря этому увидел рабочее решение. Без контекста он, скорее всего, добавил бы просто if (!token) return, и это было бы технически верно, но не соответствовало тому, как обрабатываются ошибки в остальных частях проекта.
Во-вторых, указывал конкретные границы. Как бы пытаясь помочь, Cursor может затрагивать смежные модули. Что бы этого не происходило, я писал напрямую: «Меняй только этот компонент и не трогай остальные».
В-третьих, описывал стек и соглашения. Когда я сам разобрался в правилах проекта, то стал передавать их в явном виде. К промпту стал добавлять: «Проект на React + TypeScript, стейт через Zustand, стили CSS Modules, линтер ESLint с правилами airbnb. Напиши компонент в этом стиле». Без таких дополнений он иногда выдает решения, которые не вписываются в кодовую базу, хоть сами по себе и являются корректными.
В-четвертых, просил все объяснять. Да, Cursor не только предлагает код, но и может аргументировать, почему выбрал именно такое решение. Для этого в конец промпта я добавлял: «Объясни свое решение в двух предложениях». Ответы помогали мне оценивать и принимать изменения.
Вот еще примеры для сравнения:
Неудачный промпт | Удачный промпт |
«Исправь эту функцию» | «Эта функция отвечает за авторизацию и падает при пустом токене. Добавь проверку и верни понятную ошибку. Меняй только этот файл» |
«Создай компонент» | «Создай компонент карточки товара. Проект на React + TypeScript, стили — CSS Modules, именование — PascalCase. Объясни решение в двух предложениях» |
«Объясни архитектуру» | «Я стажер, работаю два дня. Помоги понять, где файлы и папки, связанные с созданием виджетов» |
Использовал отдельные чаты под каждую задачу
Cursor отлично держит контекст, поэтому нет смысла заводить новые диалоги в рамках одной задачи. Если ответ не устроил, можно переспросить и попросить переделать, чтобы получить более точный результат.
Но не стоит вести в одном чате вообще всю работу. Чем длиннее диалог, тем больше в нем шума. Старые вопросы, уже неактуальные правки, промежуточные решения, от которых ты отказался. Cursor начинает на них опираться, и ответы становятся менее точными. Он может предложить подход, который ты уже отверг час назад, просто потому что этот вариант мелькал где-то в переписке.
Так что я завел за правило: одна задача — один чат. Переключая ветку с таской, сразу открываю диалог, связанный именно с этой задачей. Особенно удобно, когда задачи возвращаются в работу — легче вспомнить, на чем остановился. Возможно, звучит банально, но это сильно помогло.
Так что важно понимать, что контекст помогает, но только пока он актуален и чат не перегружен.
Добавил правила в Rules и .cursorrules
Чтобы не объяснять стек, соглашения и правила проекта в каждом новом чате, можно положить их в папку .cursor/rules/ в корне проекта. В ней есть файлы с расширением .mdc, которые работают как системный промпт — они читаются автоматически при каждом запросе и в каждом новом диалоге.
Чтобы создать правило, наберите «Cmd+Shift+P → New Cursor Rule» и файл появится в нужном месте. Например:

alwaysApply: true как раз означает, что правила применяются в каждом чате и каждом автодополнении без каких-либо дополнительных действий. Менять файл можно в любой момент и изменения применяются без перезапуска.
После того как я прописал стек и соглашения, Cursor перестал предлагать решения с inline-стилями или useState там, где должен быть Zustand. Это очень выручило меня в момент онбординга. А еще так я структурировал собственные знания о проекте, собрал все в одном месте, чтобы не держать в голове.
Работал с галлюцинациям
Как и все другие помощники, Cursor может галлюцинировать, причем тогда, когда ты меньше всего этого ждешь.
Например, я попытался делегировать ему верстку по макету — казалось бы, простая и понятная задача. Но в итоге он использовал прямые hex-значения вместо переменных из дизайн-системы, визуал отличался от макета, а логика поведения компонента была реализована неправильно. Я применил патч, проверил в браузере и понял, что нужно все переделывать. В итоге это заняло больше времени, чем если бы я написал все сам с нуля.
Я бы разделил галлюцинации в Cursor на четыре категории:
Распространенные решения — когда ответ формируется с опорой на лучшие практики, но без учета кодовой базы, которую он просто еще не знает. Он может предложить inline-стили вместо CSS Modules или any вместо нормального типа. Поэтому я добавил .cursorrules, а еще в промптах подробно описывал весь стек.
Неполный контекст — видит только то, что ему показали. Если попросить написать компонент, не объяснив, как устроены соседние модули, он сам будет додумывать связи и почти наверняка ошибется. Так что важно передавать переменные, токены и зависимости в явном виде.
Чрезмерная уверенность — предлагает синтаксически правильный код, но со сломанной логикой. Все компилируется, линтер молчит, но в рантайме падает или ведет себя неожиданно. Именно поэтому я старался отслеживать изменения и принимал только те, в которых был уверен. Был момент, что Cursor переписал обработчик формы и забыл передать одно из полей дальше. Форма сабмитилась, запрос уходил, ошибок не было, но одно поле молча терялось. Удалось поймать уже только на ревью.
«Шум» в чате — чем длиннее диалог, тем больше вероятность, что Cursor будет опираться на устаревший контекст. Именно поэтому я разделял чаты по задачам.
Отслеживал баги
Галлюцинации — не единственная проблема. За время онбординга я поймал несколько багов, которые связаны не с качеством ответов, а с поведением Cursor.
Зависание на больших файлах. Когда я работал с файлами на несколько сотен строк, Cursor иногда долго думал. В итоге либо ничего не менял, либо делал что-то минимальное вроде переименования функций. Не падал, не выдавал ошибку, но делал не то. Я заметил закономерность: если ответ приходил подозрительно быстро после долгого ожидания и патч выглядел слишком коротким, обычно это значило, что он не справился.
Удаление кода, который не просили трогать. В патче несколько раз исчезал код, который я не просил менять. Cursor не предупредил, а просто убрал строки, которые, видимо, посчитал лишними. Именно поэтому я читал весь diff целиком, даже если просил поменять одну строку. И особое внимание уделял красным строкам.
.cursor/rules применялся не всегда. Правила из файла работают, но скорее как подсказки, а не жесткие ограничения. Например, он предлагал useState там, где правило явно говорило использовать Zustand, особенно в Agent-режиме. Помогало просто продублировать правило в промпте.
Итог
Прошел месяц. Онбординг, который я боялся растянуть на весь стажерский срок, прошел комфортно, и я быстро освоился. Сейчас хорошо ориентируюсь в проекте, берусь за задачи с совершенно разным функционалом, не трачу время на поиски нужной папки и редко отвлекаю старших коллег.
Я доволен совместной работой, но не могу закончить фразой «всем советую». Cursor хорошо работает в конкретных сценариях, когда есть большая кодовая база, живые соглашения и более-менее читаемый код. В этом случае он может стать навигатором. Когда проект маленький и все хранится в одном файле, быстрее будет разобраться самому. А если кодовая база написана без правил, соглашений и с «историческими особенностями» на каждом шагу, он только добавит уверенных галлюцинаций к уже существующему беспорядку.
Ну и как с любыми нейросетями — главное, не отдавать им всю работу полностью. Важно самому разбираться в коде и использовать Cursor или любой другой ИИ-редактор в роли помощника. Если у вас остались вопросы или просто хотите что-то обсудить — пишите в комментариях.
