# How to Contribute to the Macro Project: A Step‑by‑Step Guide

> Learn how to contribute to the Macro project with this step by step guide. Follow our simple process to submit your code and make an impact.

- Repository: [Macro/macro](https://github.com/macro-inc/macro)
- Tags: how-to-guide
- Published: 2026-08-14

---

**To contribute to the Macro project, open a GitHub issue first, then fork the repo, set up the local Docker Postgres stack with `just setup_macrodb`, implement your change following hexagonal architecture patterns, run `just check` to pass the CI gate, and submit a PR that references your issue.**

The **Macro** project is a large Rust-based workspace that powers an all-in-one collaborative platform. Contributing to macro-inc/macro requires understanding its three-layer architecture—apps, services, and crates—and following strict style rules enforced by the `just check` CI gate. This guide walks you through the complete contribution workflow based on the official source code and [`CONTRIBUTING.md`](https://github.com/macro-inc/macro/blob/main/CONTRIBUTING.md).

## Understanding the Macro Repository Structure

Before making changes, map your contribution to the correct layer:

- **Apps** (`apps/`): SolidJS web client in `apps/web` and documentation site in `apps/docs`
- **Services** (`services/`): 40+ deployable microservices and Lambda workers using hexagonal patterns (inbound adapters → domain core → outbound adapters)
- **Crates** (`crates/`): ~167 reusable Rust libraries; most new domain logic belongs here
- **Packages** (`packages/`): Shared TypeScript utilities for the web client

All components share a single PostgreSQL database (`macro_db_client`) and a bidirectional graph linking emails, messages, docs, tasks, and agents.

## The 7-Step Contribution Workflow

Follow this workflow exactly to ensure your contribution to Macro follows project conventions.

### 1. Open a GitHub Issue

Create an issue describing your proposed change or bug fix. This gives maintainers a chance to validate the idea before you invest development time. The project only merges PRs that reference an open issue.

### 2. Fork and Branch with Conventional Commits

Fork the repository on GitHub, then clone your fork and create a properly named branch:

```bash
git clone https://github.com/<your-username>/macro.git
cd macro
git checkout -b feat/chat-dev-observability

```

Branch names use **Conventional Commits** style (`type/scope-description`) and become your PR title automatically: `type(scope): short description`.

### 3. Set Up the Local Development Environment

Bring up the Postgres stack and prepare the database:

```bash

# Start the local Docker stack

docker compose -f docker/docker-compose.yml up -d postgres

# Create the main database and update SQLx cache

just setup_macrodb
just prepare_db

```

The `just prepare_db` command is critical—it updates the `.sqlx` cache to prevent "no cached data" compilation errors. See [`docs/RUNNING_LOCALLY.md`](https://github.com/macro-inc/macro/blob/main/docs/RUNNING_LOCALLY.md) for full setup details.

### 4. Implement Your Change

Structure your code according to the layer you're modifying:

| Layer | Location | Pattern to Follow |
|-------|----------|-------------------|
| New service | `services/<name>/` | Hexagonal (adapters → domain → outbound) |
| New crate | `crates/<name>/` | Standard Rust lib structure |
| Shared utilities | `packages/<name>/` | TypeScript module pattern |

Use these shared macros throughout your implementation:

- **`macro_env_var`** for environment variable handling
- **`rootcause`** for error handling

Enforce these style rules from [`docs/STYLE_GUIDE.md`](https://github.com/macro-inc/macro/blob/main/docs/STYLE_GUIDE.md):

- Keep files under **1000 lines** (`CS-24`)
- Declare sub-modules in **[`mod.rs`](https://github.com/macro-inc/macro/blob/main/mod.rs)** (`CS-25`)

### 5. Run Checks and Tests

Execute the CI gate and targeted tests:

```bash

# Format, clippy, and type-check (enforced in CI)

just check

# Test only the crate you modified

cargo test -p document_storage_service

```

If you changed any SQL, re-run `just prepare_db` to update the offline query cache. The `just check` command includes:

- `cargo fmt` for formatting
- `cargo clippy` for linting
- `tsc` for TypeScript type checking
- Compile-time SQL verification (`CS-08`)

### 6. Submit Your Pull Request

Push your branch and open a PR on GitHub:

```bash
git push origin feat/chat-dev-observability

```

Your PR title must mirror your branch name using Conventional Commits format. The PR body should clearly state:

- **What** changed
- **Why** it changed
- Link to the related issue number

### 7. Respond to Review

Be prepared to explain your implementation decisions, run additional tests requested by reviewers, and make iterative updates. The maintainers emphasize understanding the changes—this is especially important for AI-assisted contributions.

## Key Files for Contributors

| File | Purpose |
|------|---------|
| [`CONTRIBUTING.md`](https://github.com/macro-inc/macro/blob/main/CONTRIBUTING.md) | Full workflow, branch naming, and PR guidelines |
| [`README.md`](https://github.com/macro-inc/macro/blob/main/README.md) | High-level architecture and repository layout |
| [`docs/STYLE_GUIDE.md`](https://github.com/macro-inc/macro/blob/main/docs/STYLE_GUIDE.md) | Lint rules, naming conventions, `just check` gate |
| [`docs/RUNNING_LOCALLY.md`](https://github.com/macro-inc/macro/blob/main/docs/RUNNING_LOCALLY.md) | Local stack setup instructions |
| `crates/` | Core Rust libraries |
| `services/` | Microservices and Lambda handlers |
| `packages/` | Shared TypeScript utilities |

## Common Setup Issues and Solutions

**"No cached data" SQLx errors**: Run `just prepare_db` after any schema change or when first setting up. This populates the `.sqlx/` directory with offline query metadata.

**CI failures on `just check`**: The gate is strict. Fix clippy warnings and ensure `cargo test` passes for your modified crate before pushing.

**Database connection failures**: Verify Docker Compose started Postgres successfully with `docker ps`, and check that `just setup_macrodb` completed without errors.

## Summary

- **Always open an issue first**—Macro requires issue references for all PRs
- **Use Conventional Commits** for branch names and PR titles
- **Run `just setup_macrodb` and `just prepare_db`** to initialize your environment
- **Follow hexagonal patterns** in services and keep files under 1000 lines
- **Pass `just check`** before submitting—this is the enforced CI gate
- **Link your issue** in the PR description for faster review

## Frequently Asked Questions

### Do I need to set up the entire stack to contribute to Macro?

No. For most contributions, you only need the local PostgreSQL container and the relevant crate or service. The full stack setup in [`docs/RUNNING_LOCALLY.md`](https://github.com/macro-inc/macro/blob/main/docs/RUNNING_LOCALLY.md) is only required for end-to-end testing of the complete platform.

### What happens if `just check` fails?

Fix all reported issues before submitting your PR. `just check` runs `cargo fmt`, `cargo clippy`, and TypeScript type checking—failures here will block CI and prevent merging. The project strictly enforces this gate to maintain code quality.

### Can I use AI tools to help write code for Macro?

Yes, but be transparent about it. The maintainers value understanding of the changes, so you must be able to explain any AI-generated code during review. AI-assisted contributions are welcome when you thoroughly understand and can justify the implementation.

### Where should I put new business logic?

Prefer `crates/` for reusable domain logic that multiple services might need. Put service-specific orchestration in `services/` following the hexagonal pattern (inbound adapters → domain core → outbound adapters). Check existing services in `services/` for examples of this structure.