Files
graylog2-server/graylog2-web-interface/CONTRIBUTING.md
Dennis Oelkers e6e6008e41 Add AGENT.md and restructure CONTRIBUTING.md for agent/human use (#25049)
* Add `AGENT.md` and restructure `CONTRIBUTING.md` for agent/human use

Split contribution guidance into two files:
  - `AGENT.md`: agent-specific instructions (commands, project structure, quick-reference decisions)
  - `CONTRIBUTING.md`: restructured from original with clearer formatting, serving both humans and agents

Both files cross-reference each other.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Formatting files.

* Replace commands table with bash block and remove maxWorkers sections

- AGENT.md: Consolidate commands into a single bash code block, remove maxWorkers entry
- CONTRIBUTING.md: Remove Test Timeouts subsection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add CLAUDE.md pointing to AGENT.md and CONTRIBUTING.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:49:00 +01:00

9.0 KiB

Contributing

Thank you for contributing to the Graylog web interface. This guide covers conventions and standards for both human contributors and AI coding agents.

For general contribution instructions, visit graylog.org/get-involved.

AI agents: Also read AGENT.md for agent-specific instructions, commands, and project structure details.

Code of Conduct

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

Please read and understand the Code of Conduct.

Code Style

  • We use ESLint to detect issues in our code, mostly following the Airbnb Javascript style guide with some exceptions.
  • Custom rules are maintained in eslint-config-graylog.
  • Enable linter hints in your IDE and consider enabling "fix on save" (IntelliJ docs).
  • A CI job checks for linter hints in changed files.
  • yarn lint:changes — lint all changed files (requires committed changes).
  • yarn lint:path <file> — lint a specific file.

Naming

  • Functions: use a verb as the name.
  • Classes: use a noun as the name.

Components

Class vs Functional

Small components should be functional. For complex components, either class or functional with hooks is acceptable — when in doubt, prefer functional.

Size and Simplicity

  • Keep components under 300 lines.
  • Components should not contain business logic. Extract transformation/computation logic into helper functions that can be reused and tested independently.

Reusing Components

  • We wrap react-bootstrap components in our own wrappers, importable from components/graylog. Always use these wrappers instead of importing react-bootstrap directly.
  • Check the frontend documentation for available common components before creating new ones.

Type Definitions

  • Use TypeScript for all new React components with static types for props.
  • No PropTypes — support was dropped with React 19.
  • Use default parameters instead of defaultProps in functional components. See the React 19 upgrade guide.
  • When touching existing components, migrate them to functional, typed components. Exception: trivial bugfixes where migration effort exceeds the fix or risks unforeseen consequences.
  • Prefix unused parameters with an underscore and a meaningful name (e.g., _eventType), not just _. See this discussion.
  • types.d.ts can hide errors like missing imports. Temporarily rename to types.ts to detect them.

Imports

  • Prefer ES6 modules (import/export) over CommonJS require.
  • Modules with one export should use default export.
  • With multiple exports, use default export only if one serves the module's main purpose.
  • index.ts barrel files in component folders can simplify imports but may introduce cyclic dependencies — use with caution.

State Management

New code should use (in order of simplicity):

  1. useState — for local component state
  2. useContext — for state shared across a component hierarchy
  3. Redux — for complex state

Existing Reflux stores (discouraged for new code):

  • Prefer replacing with react-query (API caching) or useState/useContext (state).
  • If migration isn't possible yet, access via useStore.

Testing

  • Framework: Jest + Testing Library.
  • Follow Testing Library's Guiding Principles and their guide for picking a good query.
  • Import render from wrappedTestingLibrary, not directly from @testing-library/react.
  • Write unit tests for every use case of new functionality.
  • Test from the user's perspective — do not rely on internal implementation details.
  • No snapshot tests for component state. Use Testing Library queries (getByText, etc.) instead. Snapshot tests are acceptable for verifying complex function return values.

Test File Placement

Test files go next to their source files:

ComponentA.tsx
ComponentA.test.tsx

If fixtures are needed, use a __tests__/ directory:

ComponentA.tsx
__tests__/ComponentA.test.tsx
__tests__/ComponentA.test.case1.json

Useful Tool

The Chrome extension "Testing Playground" helps find the best queries to select elements.

JavaScript Gotchas

Default Values

Use nullish coalescing (??) instead of logical OR (||) for defaults:

// ?? only replaces undefined/null
const a = undefined ?? 'default'; // 'default'
const b = false ?? 'default'; // false
const c = 0 ?? 'default'; // 0
const d = '' ?? 'default'; // ''

// || replaces all falsy values (usually not what you want)
const e = false || 'default'; // 'default'
const f = 0 || 'default'; // 'default'

Default parameters and destructuring only assign defaults when the value is undefined, not null:

const test = ({ value1 = 12, value2 = 34 }) => console.log(value1, value2);
test({ value1: undefined, value2: null }); // 12, null

Avoid Array.reduce for Object Construction

Array.reduce is slow for building objects from large arrays. Use Object.fromEntries instead. See this PR for details.

Session Timeouts

To prevent session expiry during user interaction, every API request using fetch from FetchProvider extends the session. Periodic requests must use fetchPeriodically instead to avoid extending the session when the user is idle.

Plugin System

  • Register: PluginStore.register(new PluginManifest({}, { key: [data] }));
  • Consume: usePluginEntities('key')
  • No central docs for plugin store keys — search the codebase.
  • Test without plugins: disable_plugins=true yarn start
  • Example plugin: graylog-plugin-sample

Internal Packages

  • graylog-web-plugin — shared packages for core and plugins, webpack config for plugin builds, plugin registration interfaces.
  • eslint-config-graylog — custom ESLint config based on eslint-config-airbnb.
  • stylelint-config-graylog — custom Stylelint config.

Refactoring

  • Fix visible ESLint warnings in files you touch.
  • Separate refactoring into dedicated commits.
  • If refactoring grows large, create a separate PR.
  • Near releases or for backported changes, weigh the risk of refactoring — defer if it adds too many changes.

Working on a Feature

Test thoroughly before submitting a PR:

  • Different user roles (admin, reader, minimal permissions).
  • Different screen resolutions.
  • Different browsers (especially Safari).
  • Heterogeneous data and high data volumes.

Run checks locally before creating a PR:

yarn tsc && yarn lint:changes && yarn test

Browser Compatibility

Test layout changes in Chrome, Firefox, and Safari. Larger layout changes should also be tested in older browsers. See the browser compatibility list.

UI Styling

Forms

  • Use vertically aligned labels and inputs (no horizontal forms without good reason).
  • Add helper text to inputs.
  • Show validation state only after changes or form submission.
  • Prefer our own Select component over the native one.
  • Avoid long forms in modals.
  • Mark optional fields with "(Optional)" in the label.

Responsive Styles

  • Large and medium screens: all features must work.
  • Mobile: graphs and complex layouts may have limitations.

Button Colors

Color Variant Use for
Grey default Neutral actions
Blue info Neutral actions
Red danger Destructive actions
Yellow warning Potentially dangerous actions
Green success Creative actions (creating data)

Avoid link style buttons — use actual anchors for navigation.

Page Loading

  • Use Spinner when loading data from the backend.

Modals

  • ESC key must close modals.
  • Form modals should not close on outside click (to prevent data loss).
  • Form modals should autofocus the first input.

Common Problems

Yarn Cache

The yarn cache can grow very large (200GB+). Run yarn cache clean periodically.