A private, multi-account desktop mail client for Linux and macOS, with a Laravel-powered product website.
brew install --cask nick-friedrich/tap/emzeroApple Silicon and Intel are both supported on macOS 12 (Monterey) or newer. Homebrew selects the matching build. Releases are signed with a Developer ID certificate and notarized by Apple, so they launch without a Gatekeeper prompt.
Upgrade later with brew upgrade --cask emzero.
Download the package for your distribution from the latest release and install it:
sudo apt install ./emzero_*_amd64.debsudo dnf install ./emzero-*.x86_64.rpmLinux packages are currently built for x86_64 only.
macOS builds are also published as .zip archives on the releases page for anyone not using Homebrew. Direct downloads do not update themselves.
There is no Arch Linux package yet, and building yourself is also the way to run only code you have inspected. See docs/BUILDING.md for the build steps, the system tools each package format needs, and how to verify a published build against its recorded checksum.
Requirements: Node.js and pnpm 11.22. pnpm runs the project's scripts with Node.js 24 whatever your system version is, downloading it if needed (devEngines in package.json); packaging fails silently on newer Node releases.
corepack enable
pnpm install
pnpm devThe initial application lives in apps/desktop. Electron main and preload own desktop capabilities; the sandboxed React renderer contains the shadcn-based UI.
pnpm dev— start the desktop app with hot reloadpnpm check— run linting, type checks, unit tests, and packaged Electron smoke testspnpm build— create an unpacked application inapps/desktop/outpnpm --filter @emzero/desktop make— create platform installersEMZERO_DEMO=1 pnpm dev— start in demo mode
Demo mode runs Emzero on a sample mailbox, for presentations and screenshots. It uses a separate Demo profile inside the app's data directory. Your accounts and mail are never loaded, and nothing is sent over the network. Reading, replying, sending, drafts, starring, moving, deleting, folders, search, and smart inboxes all work on the sample mail. Mail sent to one of the demo addresses arrives in that account's Inbox. AI drafting keeps using the provider configured in your own profile.
You can start demo mode in three ways: launch with --demo (or EMZERO_DEMO=1), click Restart in demo mode in Settings → General, or click the logo five times. The sample mailbox resets every time demo mode starts. Exit it from the sidebar or from Settings.
See plan.md for the current product scope.
The Laravel 13 website lives in apps/web and uses Inertia, React, and SQLite locally. It includes the public landing page, waitlist, blog, and a private admin area.
cd apps/web
composer run setup
php artisan app:create-admin you@example.com --name="Your Name"
composer run devOpen http://localhost:8000. The development command runs PHP, the queue listener, logs, and Vite together.
Production does not need a Node.js server. Run npm ci && npm run build during deployment, deploy the resulting application and public/build assets, point the web server document root at apps/web/public, and send PHP requests to the shared PHP-FPM container. Then run php artisan migrate --force and the usual Laravel cache commands. Configure a persistent production database; SQLite is only the local default.
Public registration is disabled. Create or promote the owner account on the production host with php artisan app:create-admin you@example.com; the command prompts securely for the password.
Emzero currently connects to Gmail over IMAP and SMTP with a Google app password:
- Turn on 2-Step Verification for your Google account.
- Create a 16-character Google app password.
- Add the account in Emzero, select Gmail / Google Workspace, and enter the app password instead of your normal Google password.
This transitional flow requires no Emzero Google OAuth project. Native Google OAuth and a Gmail API backend can replace it later without changing password-based accounts.
Emzero uses its registered Microsoft public-client application and device-code OAuth:
- Add an account and select Outlook / Microsoft 365.
- Select Connect with Microsoft.
- Copy the displayed device code, select Open Microsoft, and approve mail access in the browser.
The public Microsoft application ID is stored with the account. The Microsoft refresh token is encrypted with Electron's operating-system credential storage; access tokens are kept in memory and refreshed as needed.
Emzero is licensed under the MIT License. Third-party dependencies retain their own licenses and notices.
The root GitHub Actions workflow runs on pushes to main, version tags (v*), pull requests, and manual dispatch. It scans the full Git history with Gitleaks, runs desktop checks and creates packages on Linux and macOS, and builds and checks the website. The nested website workflow is a starter-template file; GitHub uses the root workflow for this monorepo.
To scan locally with Gitleaks 8.30.1:
gitleaks git . --log-opts="--all" --config=.gitleaks.toml --redact=100These checks validate unsigned packages. Pushing a v* tag runs the release workflow, which packages Linux and macOS builds and publishes them as GitHub Release assets; the macOS build is signed and notarized only when the APPLE_SIGNING_IDENTITY, APPLE_CERTIFICATE_P12, APPLE_CERTIFICATE_PASSWORD, KEYCHAIN_PASSWORD, APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, and APPLE_TEAM_ID repository secrets are configured. Passing CI alone does not publish a release or change repository visibility.





