Thanks for your interest in contributing. Modbux was born from real-world frustration with Modbus tooling, and your help makes it better for the entire industry.
Before you start, please read this document carefully. These guidelines exist to keep the codebase consistent and the review process smooth. They are not suggestions.
- Open an issue first. Before writing code, open an issue describing the bug or feature. This avoids wasted effort if the change doesn't align with the project direction.
- One PR, one concern. Don't mix a bug fix with a refactor. Don't sneak in "while I was here" changes. Keep your diff focused.
- Don't break the build. Run
yarn checkupbefore pushing. If it doesn't pass, your PR won't be reviewed. - Match the existing style. Don't introduce new patterns, conventions, or abstractions without discussing them first.
git clone https://github.com/ploxc/modbux.git
cd modbux
yarn
yarn devPrerequisites: Node.js (LTS) and Yarn.
src/
main/ Electron main process (server, IPC, state)
renderer/src/ React UI (components, hooks, containers, theme)
preload/ Electron preload script
shared/ Types, utilities, migrations (used by both processes)
e2e/
specs/01-main/ Core feature tests
specs/02-standalone/ Persistence & restart tests
specs/03-presentation/ Screenshot & demo generation
specs/99-hardware/ Hardware integration tests (Arduino)
fixtures/ Test data and helpers
Path aliases: @main, @renderer/*, @preload, @shared, @backend. Use them instead of deep relative imports.
Formatting and linting are enforced by ESLint, Prettier, and TypeScript strict mode. Run yarn lint to auto-fix issues. Don't fight the tooling, don't disable rules inline, and don't modify .eslintrc, .prettierrc, .editorconfig, or tsconfig files without prior discussion.
Beyond what the linter catches:
- No
any, no@ts-ignore. If the types are fighting you, your approach is wrong. - Zod for validation. External data (configs, IPC payloads) is validated with Zod schemas. Don't trust unvalidated input.
- Zustand + Mutative for state. Follow the existing store patterns. Don't introduce new state management approaches.
- MUI only. Don't add other UI libraries.
- Every interactive element needs a
data-testidfor e2e tests. - Spell out variable names.
resetButton, notrstBtn.registerAddress, notregAddr. Abbreviations make code harder to read. The only exceptions are well-known conventions likeiin loops,elin DOM callbacks,zfor Zod schemas and Zustand state accessors, and established project abbreviations likee2e. - Match existing patterns. Look at how the codebase does it, do it the same way.
Follow Conventional Commits. Lowercase, no period at the end.
feat: add RTU support for serial connections
fix: prevent grid clear on address base switch
test: add bitmap schema tests and e2e spec
refactor: move readConfiguration to standalone state
docs: update changelog for v2.0.0
chore: bump version to 2.0.0
Rules:
feat= entirely new functionalityfix= something was broken, now it's notrefactor= same behavior, different codetest= test-only changesdocs= documentation-only changeschore= tooling, deps, version bumps
Don't use feat for a bug fix. Don't use fix for a refactor. Mean what you say.
| Command | What it does |
|---|---|
yarn test |
Unit tests (Vitest) |
yarn test:watch |
Unit tests in watch mode |
yarn test:e2e |
Build + full e2e suite (Playwright) |
yarn presentation |
Screenshot & demo generation |
yarn checkup |
Everything. Lint + typecheck + unit + e2e. Run this before pushing. |
- New features need tests. Unit tests for logic, e2e tests for UI behavior.
- Bug fixes need a regression test. Prove it was broken, prove it's fixed.
- Tests must be deterministic. No flaky tests. No "works on my machine". Use
waitForTimeout()for UI settling and animations, but usetoPass()when asserting on data that needs time to arrive. - e2e tests run serially with
maxFailures: 1. One failure stops the entire suite. This is intentional.
- Use the helpers from
e2e/fixtures/helpers.ts. Don't reinvent them. - Use
data-testidattributes for selectors. Never select by CSS class or DOM structure. - Spec files are numbered and ordered. New specs go at the end of their directory.
- Presentation tests (
03-presentation/) generate screenshots for the documentation site. If you change UI, update the relevant scenes.
- Branch from
main. Usefeature/descriptionorfix/description. - Keep commits clean. Squash fixups before requesting review.
- Write a clear PR description: what changed, why, and how to test it.
yarn checkupmust pass. No exceptions.- Screenshots for UI changes. Before and after.
- Don't bump the version number. That's done at release time.
- Failing
yarn checkup anytypes or disabled lint rules- Missing tests for new functionality
- Unrelated changes mixed into the diff
- New dependencies without prior discussion
- Changes to
.editorconfig,.prettierrc, or.eslintrcwithout prior discussion - Commit messages that don't follow the convention
Use the bug report template. Include:
- Modbux version
- OS and version
- Steps to reproduce (exact, not approximate)
- Expected vs. actual behavior
- Screenshots if it's a UI issue
Use the feature request template. Explain the problem you're solving, not just the solution you want.
By contributing, you agree that your contributions will be licensed under the MIT License.