Code style
How Plotra's code and interface text are written.
There is no formatter configuration in the repository. Match the file you are in. ESLint is the automated check: bun run lint.
TypeScript
- Strict mode. Avoid
any; if a cast is needed, keep it narrow and say why. - Two spaces, double quotes, semicolons, trailing commas. Lines run long (up to about 140 characters) in preference to awkward wrapping.
- Prefer a plain function and a plain object over a class.
- Keep logic that needs neither React nor the database in a pure module under
lib/. The continuity checks, the spoiler horizon, the calendar and the exporters are all like this, which is why they can be tested with a ten-line script. - Import shared code from
@plotra/*packages. An app never imports from another app.
Comments
Comments say why, in plain sentences. They don't narrate what the next line does.
// Not awaited past a short timeout: a slow analytics host mustn't slow a request.Where it helps, cite the section of the plan a piece of code implements: (plan.md 2.9). A file that implements a feature usually opens with a short paragraph explaining the rules it follows.
React and the interface
- Use the components in
@plotra/ui/components/*and the icons in@plotra/icons. Don't add another component or icon library. - Tailwind CSS v4. Match the look of what is around you:
text-[13px]for interface text,text-muted-foregroundfor secondary text. - A view registers in
view-meta.tsandview-registry.tsx. See Monorepo layout.
Text in the interface
Short and direct. Written for a writer, not a developer.
| Write | Not |
|---|---|
| Give the project a title. | Error: title is required! |
| That folder is in the trash. | Invalid parent node |
| A workspace can hold 10 projects. | Upgrade to add more projects |
- No exclamation marks, no marketing voice.
- An error says what happened and, if there is one, what to do about it.
- Don't sell. A limit's message says what the limit is and what the person can do about it. On the hosted version that may include moving the workspace to Pro, said once and plainly. On an instance without billing (
CREEM_API_KEYunset) no text may mention plans or upgrading.
Dependencies
Add one only when a few lines of your own code won't do. Plotra is AGPL-3.0, so a dependency's licence has to allow distribution under it. After adding one, run:
bun scripts/check-licenses.tsIt reads the licence of every installed production dependency, all the way down the tree, and fails if one is incompatible, unrecognised or missing. --all includes development dependencies, and --list prints every package with its licence. Assets count too: an icon, a font or a dataset that asks for attribution needs a line on the site's Credits page.
Pull requests
- One thing per pull request.
- Say what you tested and what you didn't. "Not click-tested" is a useful sentence.
- If you changed what a feature does, update its page under
apps/docs/content/docs. AGENTS.mdis rewritten bynext devandturbo. If it turns up changed in your diff, commit it as it is.