mirror of
https://github.com/mattermost/mattermost.git
synced 2026-02-12 07:13:58 -05:00
- STACK.md - Technologies and dependencies - ARCHITECTURE.md - System design and patterns - STRUCTURE.md - Directory layout - CONVENTIONS.md - Code style and patterns - TESTING.md - Test structure - INTEGRATIONS.md - External services - CONCERNS.md - Technical debt and issues Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.9 KiB
6.9 KiB
Coding Conventions
Analysis Date: 2026-01-13
Naming Patterns
Files:
- Go:
snake_case.go(e.g.,channel_actions.go,post_store.go) - TypeScript components: PascalCase directories (e.g.,
about_build_modal/) - TypeScript utilities:
snake_case.ts(e.g.,post_utils.ts,burn_on_read_timer_utils.ts) - Hooks:
camelCasewith "use" prefix (e.g.,useBurnOnReadTimer.ts) - Tests:
*_test.go(Go),*.test.ts(x)(TypeScript) - co-located with source
Functions:
- Go:
PascalCasefor exported,camelCasefor unexported - TypeScript:
camelCase(e.g.,openDirectChannelToUserId,isSystemMessage) - Event handlers:
handle*prefix (e.g.,handleClick,handleSubmit)
Variables:
- camelCase for variables (Go and TypeScript)
- UPPER_SNAKE_CASE for constants (e.g.,
CHANNEL_SWITCH_IGNORE_ENTER_THRESHOLD_MS) - No underscore prefix for private members
Types:
- Go:
PascalCasefor exported types, structs - TypeScript:
PascalCasefor interfaces, types, enums (e.g.,TimerState,SocketStatus) - No
Iprefix for interfaces (e.g.,UsernotIUser)
Code Style
Formatting:
- Go:
gofmtstandard (tabs) - TypeScript: Prettier with
.prettierrc.json - Line length: 120 characters (TypeScript)
- Indentation: Tabs (Go), 4 spaces (TypeScript), 2 spaces (YAML/JSON)
EditorConfig (.editorconfig):
[*.{js,jsx,ts,tsx,html}] → 4 spaces
[*.go] → tabs
[*.{yml,yaml}] → 2 spaces
[*.scss] → 4 spaces
Quotes and Semicolons (TypeScript):
- Single quotes for strings (
singleQuote: true) - Semicolons: Required (ESLint enforced)
- No bracket spacing (
bracketSpacing: false)
Linting:
- Go:
golangci-lintwith.golangci.yml - TypeScript: ESLint with
.eslintrc.json - Run:
npm run lint(webapp),make lint(server)
Import Organization
Go:
- Standard library
- Third-party packages
- Internal packages (
github.com/mattermost/mattermost/server/...)
TypeScript:
- External packages (react, redux, etc.)
- Internal modules (@mattermost packages)
- Relative imports (./utils, ../types)
- Type imports last within groups
Grouping:
- Blank line between groups
- Alphabetical within each group
Path Aliases (TypeScript):
@mattermost/client- API client SDK@mattermost/types- Shared types@mattermost/components- Shared UI components
Error Handling
Go Patterns:
- Return
*model.AppErrorfor business errors - Return Go
errorfor system errors - Always check returned errors
- Log with context before returning
if err != nil {
return nil, model.NewAppError("GetUser", "app.user.get.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
TypeScript Patterns:
- Actions return
{data: ...}or{error: ...} - Use
try/catchfor async operations bindClientFuncfor standardized Client4 error handling
try {
const data = await Client4.getUser(userId);
return {data};
} catch (error) {
forceLogoutIfNecessary(error);
return {error};
}
Logging
Go Framework:
- Package:
github.com/mattermost/logr/v2 - Structured logging with context
- Levels: debug, info, warn, error
mlog.Error("Failed to get user", mlog.String("user_id", userId), mlog.Err(err))
TypeScript:
- Console logging in development
- No
console.login production code (ESLint enforced)
Comments
When to Comment:
- Explain "why" not "what"
- Document business rules and edge cases
- Complex algorithms or non-obvious logic
Copyright Header (all files):
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
JSDoc/GoDoc:
- Required for exported functions/types
- Use
@param,@returns,@throwstags (TypeScript) - Function documentation above declaration (Go)
TODO Comments:
- Format:
// TODO: descriptionor// TODO: MM-XXXXX description - Link to Jira issue when applicable
Function Design
Size:
- Keep functions focused, single responsibility
- Extract helpers for complex logic
- Go: Aim for <50 lines per function
Parameters:
- Go: Use context as first parameter when needed
- TypeScript: Max 3 parameters, use options object for more
- Destructure objects in parameter list
Return Values:
- Go: Return
(result, error)tuple pattern - TypeScript: Return
{data}or{error}from async actions - Return early for guard clauses
Module Design
Go Exports:
- PascalCase for exported identifiers
- Package-level functions for module API
- Internal helpers in same file or
internal/package
TypeScript Exports:
- Named exports preferred
- Default exports for React components
- Barrel files (
index.ts) for public API
React Component Patterns:
- Functional components (no class components in new code)
- Hooks:
useSelector,useDispatch,useCallback,useMemo React.memofor expensive render logicmakeAsyncComponentfor code splitting
CSS/SCSS Conventions
Co-location:
- SCSS file next to component (e.g.,
my_component.scss+my_component.tsx) - Import styles directly into component
Naming:
- Root class: PascalCase matching component (e.g.,
.MyComponent) - Child elements: BEM suffix (e.g.,
.MyComponent__title) - Modifiers: Separate class (e.g.,
&.compact)
Theming:
- Use CSS variables for colors:
var(--link-color) - RGB variants for transparency:
rgba(var(--link-color-rgb), 0.8) - Theme variables in
channels/src/sass/base/_css_variables.scss
Avoid:
!important(over 300 legacy instances need cleanup)- Hard-coded color values in themed areas
- Element selectors (prefer class selectors)
Redux Patterns
Actions:
- Async thunks return
{data}or{error} - Use
Client4only in Redux actions - Batch network requests when possible
Selectors:
- Memoize with
createSelectorfor computed values - Factory pattern (
makeGet*) for parameterized selectors - Use
useMemofor selector instances in functional components
Error Handling:
- Wrap
Client4calls in try/catch - Call
forceLogoutIfNecessaryon errors - Dispatch
logErrorfor error tracking
Accessibility
Semantic HTML:
- Use
button,input,h2,uloverdiv/span - Interactive elements must have accessible names
- Use
aria-labelledbyoraria-label
Keyboard Support:
- All interactive elements focusable
- Standard keyboard patterns (Enter, Space, Arrow keys)
- Visible focus states (
.a11y--focusedclass)
Screen Readers:
- Alt text for images (don't include "image" or "icon")
aria-expandedfor expandable elementsaria-describedbyfor additional context
Internationalization
React Intl:
- Use
FormattedMessageoveruseIntlwhen possible - Store
MessageDescriptorobjects outside React - Don't use deprecated
localizeMessage
Formatting:
- Rich text formatting for mixed styles
- Never concatenate translated strings
Convention analysis: 2026-01-13 Update when patterns change