General Principles
- MVP focus: Least code change, happy-path only
- No unnecessary defensive programming: Ship the happy path first; add guards/fallbacks only when production proves them necessary
- Prefer minimal, readable code: Clarity beats cleverness
- Break down complex tasks: Create small, testable units
- Remove dead code: Delete unreachable, unused, or obsolete code
- Don’t write multiple versions: Pick the best approach and implement it once
- Iterate after confirmation: Don’t over-engineer; iterate based on feedback
Ruby Code Style
RuboCop
Chatwoot uses RuboCop for Ruby linting and formatting. Run linting:Ruby Style Rules
- Line length: Maximum 150 characters
- Module/Class definitions: Use compact format
- Always use
bundle exec: Prefix Ruby CLI tasks withbundle exec
Error Handling
Use custom exceptions fromlib/custom_exceptions/:
Models
- Add proper validations (presence, uniqueness)
- Add database indexes for frequently queried fields
- Use strong parameters in controllers
JavaScript/Vue Code Style
ESLint
Chatwoot uses ESLint with Airbnb base configuration and Vue 3 recommended rules. Run linting:Vue Style Rules
Component API
Always use Composition API with<script setup>:
Naming Conventions
- Component names: Use PascalCase
- Event names: Use camelCase
- Props: Use camelCase in JavaScript, kebab-case in templates
Type Safety
Use PropTypes for Vue components:Internationalization (i18n)
No bare strings in templates. Always use i18n:Frontend Components
For message bubbles, usecomponents-next/ (the rest is being deprecated):
CSS/Styling
Tailwind CSS Only
Chatwoot uses Tailwind CSS exclusively for styling:- Do NOT write custom CSS
- Do NOT use scoped CSS
- Do NOT use inline styles
- Always use Tailwind utility classes
Color Definitions
Refer totailwind.config.js for available color definitions:
Translation Files
Backend Translations (Rails)
Update onlyen.yml for English translations:
Location: config/locales/en.yml
Frontend Translations (Vue)
Update onlyen.json for English translations:
Location: app/javascript/dashboard/i18n/locale/en/en.json
Branding and White-labeling
For user-facing strings containing “Chatwoot” that should adapt to branded/self-hosted installs:Testing Code
Spec Best Practices
- Don’t write specs unless explicitly asked: Focus on shipping features
- Use
with_modified_env: Prefer this over stubbingENVdirectly - Error class comparison: In parallel/reloading environments, compare
error.class.nameinstead of constant equality
Linting Commands Reference
Ruby Linting
JavaScript/Vue Linting
Editor Configuration
VS Code
Recommended extensions:- Ruby:
rebornix.ruby - RuboCop:
misogi.ruby-rubocop - ESLint:
dbaeumer.vscode-eslint - Vetur or Volar: For Vue support
- Tailwind CSS IntelliSense:
bradlc.vscode-tailwindcss
EditorConfig
Chatwoot includes an.editorconfig file. Ensure your editor respects it:
Pre-commit Hooks
Chatwoot uses Husky for Git hooks: Configured hooks:- Lint staged files before commit
- Run validation before push
Summary Checklist
Before submitting your code:- Ruby code passes
bundle exec rubocop - JavaScript/Vue code passes
pnpm eslint - No custom CSS; only Tailwind utility classes used
- No bare strings in templates; i18n used throughout
- Only
en.ymlanden.jsonupdated for translations - PropTypes added for Vue components
- Strong params used in Rails controllers
- Composition API with
<script setup>used for Vue - Code is minimal, readable, and focused on the happy path
- Dead/unreachable code removed

