Guidance for AI coding agents working in frontend-app-authoring, the React/Paragon
frontend for Open edX Studio (course and library authoring). Human contributors should
also read the README.rst and How To Contribute.
- Use the Node version in
.nvmrc(currently 24). Install withnpm ci. npm start/npm run dev— run the dev server (needs a running Open edX backend, e.g. Tutor; seeREADME.rst).npm test— run Jest with coverage. For a single file:npm test -- path/to/file.test.tsx.npm run types— TypeScript type-check (tsc --noEmit).npm run lint— dprint + oxlint + stylelint.npm run lint:fixauto-fixes most issues.make validate— the full CI gate: lint, types, tests, build, and i18n/lockfile checks. Run before declaring work done.
Always run npm run lint and npm run types (and relevant tests) after changing code, and fix what they report.
This codebase is actively migrating away from older patterns. Follow the new ones, and prefer improving code you touch over matching nearby legacy style.
- TypeScript first. Write new files as
.ts/.tsx. AvoidpropTypesanddefaultPropsin new or modified code. - Imports. Use the
@srcalias instead of deep relative paths, e.g.import { initializeMocks } from '@src/testUtils';(not'../../../testUtils').- Code in the
pluginsdirectory should useCourseAuthoring/as the import alias instead of@src/. TheCourseAuthoring/alias should not be used outside of thepluginsdirectory.
- Code in the
- Data fetching. Use React Query for REST APIs. Put hooks in a feature's
data/apiHooks.ts— see existing ones for the pattern. - React Router Links and navigation are handled using React Router.
- State. Do not add new fields to the Redux store; Redux is deprecated here. Share state with React Context. Use local/React Query state for server data.
- Feature-based structure. Code is organized by feature/module, not by type. Keep a feature's view components and its
data/directory together, expose a public interface, and don't import from a feature's internals or its parents. See docs/decisions/0002-feature-based-application-organization.rst. - i18n. All user-facing strings go through
react-intlin amessages.tsfile, and every message needs adescriptionfor translators. See docs/how_tos/i18n.rst. Do not hand-editsrc/i18n/messages/. - Formatting. dprint enforces single quotes in TS (double in JSX), semicolons, 2-space indent, 120-col width. Let
npm run lint:fixhandle it rather than formatting by hand. - Linting Despite some leftover references to eslint and eslint directives in the code, this repo is now using oxlint as its linter. Do not run eslint.
- Use
src/testUtils.tsx, especiallyinitializeMocks(...)and the customrender(), to set up providers, the API mock, and routing. Don't reinvent test scaffolding. - Prefer
user-eventoverfireEvent - Selectors and queries in tests should follow the React Testing Library Guiding Principles and query priority guidelines. In particular, prefer
getByRole(e.g.getByRole('button', {name: /submit/i})),getByLabelText,getByPlaceholderText,getByText, andgetByDisplayValueover non-user-visible selectors likegetByTestId. - Mock HTTP with the provided axios mock adapter; assert on user-visible behavior via Testing Library queries.
- New code is expected to be covered (see
codecov.yml).
- Document non-trivial design decisions in the repo (docstrings or an ADR under docs/decisions/), per OEP-19.
- Commit messages must follow Conventional Commits (
feat:,fix:,chore:,refactor:, …); this is enforced by commitlint in CI.