> For the complete documentation index, see [llms.txt](https://docs.ipcheck.ing/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipcheck.ing/developer/contributing/how-to-contribute.md).

# How to Contribute

MyIP is open source and welcomes outside contributions. This page describes the flow the project actually uses, from the first issue to a merged pull request.

Everything here mirrors [`CONTRIBUTING.md`](https://github.com/jason5ng32/MyIP/blob/main/CONTRIBUTING.md) and `AGENTS.md` in the repository. The project also has a [Code of Conduct](https://github.com/jason5ng32/MyIP/blob/main/CODE_OF_CONDUCT.md) (Contributor Covenant). By participating, you agree to uphold it.

## Before you write code

Open an issue first for anything non-trivial. A short discussion up front is cheaper than a rejected pull request. New features, behavior changes, new dependencies, and refactors all qualify.

Small, obvious fixes — a typo, a broken link, a one-line bug — can go straight to a pull request.

If you are new to the project, look for issues labelled `good first issue`.

## The flow

{% stepper %}
{% step %}

### Open an issue

Describe the change and why it is needed. Wait for a maintainer to confirm the direction before you invest time. See [Reporting Issues](/developer/contributing/reporting-issues.md).
{% endstep %}

{% step %}

### Fork and branch from `dev`

Fork the repository, then create your branch from **`dev`** — not `main`.

```bash
git clone https://github.com/<you>/MyIP.git
cd MyIP
git checkout dev
git checkout -b fix/mac-input-validation
```

{% endstep %}

{% step %}

### Set up and build

Install with pnpm and get the app running. See [Dev Environment](/developer/development/dev-environment.md).

```bash
pnpm install
pnpm dev
```

{% endstep %}

{% step %}

### Make the change

One concern per branch. Follow the [Coding Conventions](/developer/development/coding-conventions.md), and add or update tests in `tests/` for any non-visual logic you touch.
{% endstep %}

{% step %}

### Run `pnpm check`

`pnpm check` runs the test suite and a production build. It must be green before you push.

```bash
pnpm check
```

{% endstep %}

{% step %}

### Rebase onto the latest `dev`

Rebase — don't merge `dev` into your branch. It keeps the history readable.

```bash
git fetch upstream
git rebase upstream/dev
```

{% endstep %}

{% step %}

### Open the pull request against `dev`

Fill in the pull request template: a summary, the type of change, and the checklist. Link the issue it fixes.
{% endstep %}
{% endstepper %}

## Why pull requests target `dev`

{% hint style="warning" %}
**Never open a pull request against `main`.** `main` only receives release merges from `dev` branch. A pull request targeting `main` will be asked to retarget.
{% endhint %}

The repository is `dev` in, `dev` out. All work lands on `dev` first; `main` moves only through a `dev` → `main` release merge. This keeps `main` aligned with what is released, and it means every change gets exercised on `dev` first.

## Pull request rules

* **Target `dev`.** See above.
* **One concern per pull request.** Don't bundle a feature with an unrelated dev-environment tweak. Split them.
* **Rebase before submitting**, so your branch sits on top of current `dev`.
* **Describe what changed and why.** Reviewers should not have to reverse engineer the intent from the diff.
* **`pnpm check` green.** CI runs `pnpm test` and `pnpm run build` on Node 24 for every pull request to `dev` or `main`; a red run blocks the merge.

## Commit message style

Commits use a `Type(scope):` prefix, taken from the project's own history. The scope is optional and names the area touched (`ui`, `api`, a feature name, a module name).

| Prefix          | Used for                          | Real example from the repo                                                     |
| --------------- | --------------------------------- | ------------------------------------------------------------------------------ |
| `Feat(...)`     | New capability                    | `Feat(ui): shared Globalping country picker for MTR / latency / censorship`    |
| `Fix(...)`      | Bug fix                           | `Fix(ui): align MAC input validation with backend (exactly 12 hex digits)`     |
| `Refactor(...)` | Restructuring, no behavior change | `Refactor(country-name): replace hand-maintained table with Intl.DisplayNames` |
| `Perf(...)`     | Performance work                  | `Perf(frontend): lazy-load the active UI locale only`                          |
| `Style(...)`    | Visual or copy polish             | `Style(toggle): high-contrast pressed state for toggle primitives`             |
| `Chore(...)`    | Tooling, deps, housekeeping       | `Chore: simplify jsconfig path mapping`                                        |

Write messages in English, in the imperative, and keep one concern per commit.

## The i18n rule

MyIP ships in four locales: `en`, `zh`, `fr`, `ru`.

{% hint style="danger" %}
Any change that surfaces user-visible copy must update **all four locale files in the same commit** — including the `frontend/data/changelog.json` entries. `tests/changelog.test.js` enforces this, so a partial translation fails `pnpm check`.
{% endhint %}

If you cannot write a locale confidently, still add the key to every file with your best attempt, and say so in the pull request. Details: [i18n](/developer/development/i18n.md).

## Tests

Non-visual logic that can run without a network call — pure functions, validators, transforms, composables with mockable inputs — ships with a spec in `tests/` in the same change. UI rendering, real network behavior, and browser APIs are out of scope. See [Testing](/developer/development/testing.md).

## Code review

A maintainer reviews every pull request. Expect questions, requested changes, or a discussion about approach before a merge. That is normal, not a rejection.

Push follow-up commits to the same branch — the pull request updates automatically. If your change is visual and cannot be verified headlessly, say so and attach a screenshot or a short recording.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ipcheck.ing/developer/contributing/how-to-contribute.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
