Mailpilot

Development

Resources for developers working on Mailpilot or building integrations.

Development Guides

Getting Started

Prerequisites

  • Node.js: v22+ required
  • pnpm: v10.28.0+
  • TypeScript: v5.4+
  • Git: Version control

Clone and Install

git clone https://github.com/metal0/mailpilot.git
cd mailpilot
pnpm install

Project Structure

mailpilot/
├── src/                  # Backend source code
│   ├── server/          # HTTP server and API
│   ├── services/        # Core email processing logic
│   ├── lib/             # Shared utilities
│   └── types/           # TypeScript type definitions
├── dashboard/           # Svelte frontend
├── docs-site/           # Documentation site (fumadocs)
├── docs/                # Developer documentation
├── scripts/             # Utility scripts
└── tests/               # E2E tests

Development Commands

# Backend development
pnpm dev                 # Start with hot reload

# Frontend dashboard
cd dashboard
pnpm dev                 # Runs on port 8085

# Documentation site
cd docs-site
pnpm dev                 # Runs on port 3001

# Testing
pnpm test                # Run E2E tests
pnpm test:unit           # Run unit tests

# Build
pnpm build               # Build backend and dashboard
pnpm build:docker        # Build Docker image

Code Style

TypeScript

  • Strict mode enabled: No implicit any, strict null checks
  • ESLint: Configured with recommended rules
  • Prettier: Code formatting enforced

Conventions

  • Naming: camelCase for variables/functions, PascalCase for classes/types
  • Async/await: Preferred over .then() chains
  • Error handling: Always use try/catch for async operations
  • Comments: JSDoc for public APIs, inline for complex logic

Example

/**
 * Process an email using the configured LLM provider
 * @param email - The email to process
 * @param config - Account configuration
 * @returns Classified actions
 */
async function processEmail(
  email: IMAPEmail,
  config: AccountConfig
): Promise<ClassifiedActions> {
  try {
    // Build prompt from email content
    const prompt = buildPrompt(email, config);

    // Call LLM
    const response = await llm.classify(prompt);

    // Parse and validate actions
    return validateActions(response);
  } catch (error) {
    logger.error('Email processing failed', { error });
    throw new ProcessingError('Classification failed', { cause: error });
  }
}

Testing Philosophy

  • E2E tests: Test against real IMAP servers and LLM providers
  • Integration tests: Test service interactions
  • Unit tests: Test individual functions and utilities
  • AI-assisted testing: Use LLMs to generate test cases

See E2E Testing and AI Testing for details.

Contributing

We welcome contributions! See the Contributing Guide for:

  • Code contribution workflow
  • Pull request guidelines
  • Documentation standards
  • Issue reporting

Community

Next Steps