# Ship Your First Project

This guide walks you through setting up your development environment, building a branded Hello World UI using Claude Code, and submitting it for review inside the Mailworks-AI GitHub organization.

**Who this is for:** Anyone at The Mailworks building their first repo. No prior development experience required -- just follow each step in order.

***

## Prerequisites

Before you start, make sure you have:

* A GitHub account (if you don't have one, create one at [github.com](https://github.com))
* Claude Code desktop app installed (download from [claude.ai/download](https://claude.ai/download))
* An invitation to the `Mailworks-AI` GitHub organization -- contact Tim (<tim@themailworks.com>) if you haven't received one yet. Accept the invite before continuing.

***

## Part 1: Install Required Tools

Open Claude Code and give it the following instructions one at a time. Claude will handle the installation for you -- just approve any commands it wants to run.

### 1. Install Node.js

> "Install Node.js on this machine and verify it's working."

### 2. Install pnpm

> "Install pnpm globally and verify it's working."

### 3. Install Git

> "Install Git on this machine and verify it's working."

### 4. Connect Git to Your GitHub Account

> "Help me configure Git with my GitHub credentials. My GitHub username is \[YOUR\_USERNAME] and my email is \[YOUR\_EMAIL]."

Replace `[YOUR_USERNAME]` and `[YOUR_EMAIL]` with your actual info. Claude will walk you through authentication setup.

> **Important:** You authenticate with your personal GitHub account, but that account must have already accepted the Mailworks-AI org invite before you reach Part 4. If you haven't accepted it yet, do that now at [github.com/Mailworks-AI](https://github.com/Mailworks-AI) or contact Tim (<tim@themailworks.com>).

***

## Part 2: Create the Hello World Repo

### 1. Create a New Project Folder and Connect It

Before giving Claude Code any instructions, you need to create your project folder and connect it as the working directory for the session.

1. Create a new folder on your computer called `hello-world`
2. Open Claude Code
3. Connect the folder as your working directory -- look for the folder/directory picker icon above the chat box and select your `hello-world` folder

> **Important:** Do not move this folder after connecting it. If you move it, Claude Code will lose the path and you will need to start a new session and reconnect the folder from its new location.

Claude Code cannot change its working directory after the session starts, so this step must happen first.

### 2. Initialize the Project

Tell Claude Code:

> "Initialize a new Node.js TypeScript project with the following configuration:
>
> * Use pnpm as the package manager
> * Add TypeScript as a dev dependency with strict mode enabled in tsconfig.json
> * Create an .nvmrc file set to v22.22.2
> * Install lodash version 4.17.4 as a dependency
> * Add a src/index.ts file that logs 'Hello from The Mailworks!'
> * Add these scripts to package.json: build, start, and lint
> * The lint script should run eslint"

Claude will scaffold the entire project for you. If Claude proposes alternative solutions,  do not accept the suggestions and move forward with the approved Mailworks method.

### 3. Add The Mailworks Config Files

Every Mailworks repo requires three configuration files. Tell Claude Code:

> "I need to add the standard Mailworks config files to this repo. Create these files at the exact paths I specify:"

Then paste the following three file contents one at a time:

**File 1: `./eslint.config.mjs`** (project root)

```javascript
// @ts-check
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  {
    files: ['**/*.js', '**/*.mjs'],
    ...tseslint.configs.disableTypeChecked,
  },
  {
    ignores: ["**/vitest.config.ts", "**/tests/*.ts"]
  },
);
```

**File 2: `./.github/workflows/pr.yml`** (create the folders if they don't exist)

```yaml
name: Lint and Test PR

on:
  pull_request:

jobs:
  lint-test:
    name: Lint and Test
    runs-on: self-hosted
    permissions:
      id-token: write
      contents: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'
      - uses: pnpm/action-setup@v4
        with:
          version: 9.15.3
          run_install: false
      - name: Get pnpm Store Directory
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
      - uses: actions/cache@v3
        name: Setup pnpm Cache
        with:
          path: ${{ env.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-
      - name: Install Dependencies
        run: pnpm i --frozen-lockfile
      - name: Lint
        run: pnpm run lint
```

**File 3: `./.github/pull_request_template.md`**

```markdown
# Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

## Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Chore (changes that do not relate to a fix or feature and don't modify src or test files)
- [ ] Infrastructure work
- [ ] This change requires a documentation update

# Checklist:

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have made corresponding changes to the documentation(Confluence, API Docs, Google Drive, LucidChart, etc..)
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] I have added alt text to any images that I have added
```

### 4. Add the Mailworks Design System and Stack Reference

Every Mailworks repo requires two reference files that tell Claude Code how to build and style everything correctly.

**DESIGN.md** defines the visual design system -- colors, typography, spacing, and components. **STACK.md** defines the tech stack Claude should use for all builds.

Download both files:

* [DESIGN.md](https://github.com/themailworks-ai/design-system/blob/main/DESIGN.md)
* [STACK.md](https://github.com/themailworks-ai/design-system/blob/main/STACK.md)

Then tell Claude Code:

> "Add these two files to the root of the project."

Attach both DESIGN.md and STACK.md to the chat.

**Why this matters:** Every time you ask Claude Code to build something, it will reference these files and produce branded, stack-compliant output instead of generic defaults.

### 5. Install ESLint Dependencies

Tell Claude Code:

> "Install the ESLint dependencies we need for our eslint.config.mjs: @eslint/js and typescript-eslint. Install them as dev dependencies with pnpm."

### 6. Build the Hello World UI

Now ask Claude Code to build a branded UI using the design system:

> "Using DESIGN.md and STACK.md as your reference, build a Hello World UI for The Mailworks. Use placeholder content throughout. The UI should include: a page header with eyebrow text and a title, a KPI card row with at least three metrics, a hero callout block with a large headline number, a data table with sortable columns and hover states, and a filter pill row above the table. Everything should follow the Mailworks design system exactly."

Claude will generate the full UI. This is what all Mailworks-branded interfaces look like.

### 7. Preview the UI Locally

Before pushing anything, run the project locally to see it in your browser.

Tell Claude Code:

> "Spin up a local development server for this project and open it in my browser."

Claude will start the server and give you a localhost URL (typically `http://localhost:3000` or similar). Open it in your browser to preview the UI. If anything looks off, describe it to Claude Code and it will fix it:

> "The hero callout background isn't showing correctly. Fix it."

Keep iterating until the UI looks right, then move on.

### 8. Initialize Git

Tell Claude Code:

> "Initialize a Git repo in this folder, create a .gitignore for Node.js projects, and make the initial commit with the message 'Initial commit: Hello World project with Mailworks config'."

***

## Part 3: Pass the Lint Check

Before pushing your repo, it must pass linting with zero errors.

Tell Claude Code:

> "Run pnpm lint and fix any errors that come up."

Claude will run the linter, identify any issues, fix them, and re-run until the check passes clean.

***

## Part 4: Push to the Mailworks-AI GitHub Org

Tell Claude Code:

> "Create a new private repository called hello-world under the Mailworks-AI GitHub organization. Do not initialize it with a README. Then add it as the remote origin and push the main branch."

Claude will handle authentication and push your code. If it needs your GitHub credentials or org permissions, follow the prompts.

***

## Part 5: Enable Dependabot and Fix Security Alerts

### 1. Enable Dependabot

1. Go to your repo at `github.com/Mailworks-AI/hello-world`
2. Click **Settings** > **Code security and analysis**
3. Enable **Dependabot alerts** and **Dependabot security updates**

### 2. Resolve Alerts

After enabling Dependabot, check the **Security** tab on your repo. You should see a Dependabot alert for the `lodash` dependency -- this is intentional, and fixing it is part of the exercise.

Tell Claude Code:

> "There are Dependabot alerts to clean up on the repo. Review them and fix everything."

Then push the fixes:

> "Commit the dependency updates and push to GitHub."

Confirm the Security tab shows zero open alerts before moving on.

***

## Part 6: Create a Branch, Fix DeepSource, and Open a PR

DeepSource is configured at the org level and runs automatically on all `Mailworks-AI` repos.

### 1. Create a New Branch

Tell Claude Code:

> "Create a new branch for my initial cleanup work and switch to it."

### 2. Fix DeepSource Errors

1. Go to `github.com/Mailworks-AI/hello-world`
2. Find the **DeepSource** section under the repo's checks or integrations
3. Review any flagged errors or warnings

If there are issues, tell Claude Code:

> "There are DeepSource errors on this repo. Here's what it's flagging: \[describe or paste the errors]. Fix them."

### 3. Run Lint One More Time

> "Run pnpm lint and fix any errors."

Both DeepSource and lint must pass clean before submitting your PR.

### 4. Push and Open a PR

Tell Claude Code:

> "Commit the fixes, push this branch to GitHub, and open a pull request. Tag Ray-MW as a reviewer."

Claude will create the PR using the pull request template already in the repo.

***

## Quick Reference

| Tool        | Version    | Purpose                  |
| ----------- | ---------- | ------------------------ |
| Node.js     | Latest LTS | JavaScript runtime       |
| pnpm        | Latest     | Package manager          |
| Git         | Latest     | Version control          |
| Claude Code | Latest     | AI development assistant |

| Mailworks Config File      | Location             | Purpose                               |
| -------------------------- | -------------------- | ------------------------------------- |
| `eslint.config.mjs`        | Project root         | Code style and quality rules          |
| `pr.yml`                   | `.github/workflows/` | Automated lint check on pull requests |
| `pull_request_template.md` | `.github/`           | Standardized PR description format    |
| `.nvmrc`                   | Project root         | Locks Node.js version                 |
| `DESIGN.md`                | Project root         | Mailworks brand design system         |
| `STACK.md`                 | Project root         | Mailworks tech stack reference        |

***

## Troubleshooting

If you get stuck at any point, just describe the problem to Claude Code in plain language. For example:

* "I'm getting a permission denied error when trying to push to GitHub"
* "The lint check is failing and I don't understand the errors"
* "The local preview isn't loading"
* "pnpm install is throwing an error"

Claude Code can diagnose and fix most issues directly.


---

# Agent Instructions: 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:

```
GET https://knowledge.themailworks.com/how-we-work/ship-your-first-project.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
