Skip to main content

Overview

Proton WebClients applications are built using webpack via the @proton/pack build system. Each application can be run in development mode or built for production.

Development Mode

Starting an Application

Run an application in development mode with hot reload:
yarn workspace proton-mail start
Development servers run in standalone mode by default. The application will be available at http://localhost:<port>.

Development Server Options

The proton-pack dev-server command supports various options:
--appMode
string
default:"standalone"
Application mode: standalone or sso
--no-error-logs
boolean
Suppress error logs in console
--noLogicalScss
boolean
Disable logical CSS properties transformation

Example: Custom Development Configuration

cross-env TS_NODE_PROJECT="../../tsconfig.webpack.json" \
  proton-pack dev-server \
  --appMode=standalone \
  --handleSupportAndErrors \
  --optimizeAssets

Production Builds

Building for Production

Build an application for production deployment:
yarn workspace proton-mail build:web
This runs:
cross-env NODE_ENV=production \
  TS_NODE_PROJECT="../../tsconfig.webpack.json" \
  proton-pack build --appMode=sso

Build Output

Production builds output to the dist/ directory within each application workspace.
Turbo configuration specifies build outputs:
turbo.json
{
  "tasks": {
    "build:web": {
      "outputs": ["dist/**", "webapp-bundle.tar.gz"]
    }
  }
}

Build Analysis

Analyzing Bundle Size

Generate a webpack bundle analyzer report:
yarn workspace proton-mail analyze
This runs the build with the --analyze flag:
yarn build:web --analyze
The analyzer will open a visual representation of bundle contents in your browser.

Type Checking

Check TypeScript Types

Run TypeScript compiler in check mode (no output):
yarn workspace proton-mail check-types
Type checking runs the tsc command defined in each workspace’s scripts.

Application Scripts Reference

Common Scripts

All applications share these common scripts:
ScriptDescriptionCommand
startStart development serverproton-pack dev-server
build:webProduction buildproton-pack build
check-typesTypeScript type checkingtsc
lintRun ESLinteslint --quiet
testRun testsjest
test:ciCI test runjest --ci --coverage

Application-Specific Examples

package.json
{
  "scripts": {
    "start": "cross-env TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack dev-server --appMode=standalone",
    "build:web": "cross-env NODE_ENV=production TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack build --appMode=sso",
    "analyze": "yarn build:web --analyze",
    "check-types": "tsc",
    "test": "jest --logHeapUsage --forceExit",
    "test:ci": "jest --coverage --runInBand --ci --forceExit",
    "test:watch": "jest --watch --coverage=false"
  }
}
package.json
{
  "scripts": {
    "start": "cross-env TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack dev-server --appMode=standalone --handleSupportAndErrors --optimizeAssets --noLogicalScss",
    "build:web": "cross-env NODE_ENV=production TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack build --appMode=sso --handleSupportAndErrors --optimizeAssets --noLogicalScss",
    "analyze": "yarn build:web --analyze",
    "check-types": "tsc",
    "test": "jest",
    "test:ci": "jest --coverage=false --runInBand --ci",
    "test:watch": "jest --watch --coverage=false"
  }
}
package.json
{
  "scripts": {
    "start": "cross-env TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack dev-server --appMode=standalone",
    "build:web": "cross-env NODE_ENV=production TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack build --appMode=sso",
    "check-types": "tsc",
    "test": "cross-env TZ=UTC jest",
    "test:ci": "yarn run test --ci --coverage --runInBand",
    "test:watch": "yarn run test --coverage=false --watch"
  }
}
package.json
{
  "scripts": {
    "start": "cross-env TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack dev-server --appMode=standalone --no-error-logs --noLogicalScss",
    "build:web": "cross-env NODE_ENV=production TS_NODE_PROJECT=\"../../tsconfig.webpack.json\" proton-pack build --appMode=sso --noLogicalScss",
    "check-types": "tsc",
    "test": "jest",
    "test:ci": "jest --coverage --runInBand --ci",
    "test:watch": "jest --watch"
  }
}

Build System (@proton/pack)

The @proton/pack package provides the build tooling for all applications.

Key Features

Webpack Configuration

Pre-configured webpack setup with optimized loaders and plugins

TypeScript Support

Built-in TypeScript compilation with Babel

Hot Reload

React Fast Refresh for instant feedback

Asset Optimization

Automatic image and asset optimization

Proton Pack CLI

The proton-pack command provides:
  • dev-server - Development server with hot reload
  • build - Production build with optimizations

Environment Variables

Common Environment Variables

NODE_ENV
string
default:"development"
Node environment: development or production
TS_NODE_PROJECT
string
Path to TypeScript configuration for webpack
WEBPACK_PARALLELISM
number
Number of parallel webpack processes

Troubleshooting

Increase Node.js memory limit:
export NODE_OPTIONS="--max-old-space-size=4096"
yarn workspace proton-mail build:web
The dev server uses portfinder to automatically find an available port. Check console output for the actual port.
Run type checking separately to see detailed errors:
yarn workspace proton-mail check-types
Clear webpack cache:
rm -rf applications/mail/node_modules/.cache

Performance Tips

1

Use Turbo Caching

Turbo caches build outputs. Unchanged applications won’t rebuild.
2

Parallel Builds

Use yarn workspaces foreach with -p for parallel execution:
yarn workspaces foreach -p run build:web
3

Incremental Type Checking

Enable TypeScript incremental compilation in tsconfig.json:
{
  "compilerOptions": {
    "incremental": true
  }
}
Always run builds from the monorepo root directory to ensure proper workspace resolution.

Build docs developers (and LLMs) love