Litebox

module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2026 License: Apache-2.0

README

Litebox

CI Security Release Container OpenSSF Scorecard Go Report Card License Contributions welcome

A brutally lightweight, self-hosted human mailbox powered by Resend.

Litebox gives custom-domain addresses real browser inboxes without asking you to run SMTP, IMAP, Redis, Postgres, Elasticsearch, a queue broker, or a JavaScript production runtime. One installation can host independent mailboxes, aliases, multiple administrators, and multiple browser sessions while retaining the one-container, one-volume default.

[!IMPORTANT] Litebox is pre-1.0 software. Back up /data, review the security model, and test with a non-critical domain before adopting it for important mail.

Why Litebox?

You own a domain and want hello@example.com. Resend already handles the hard internet-facing transport. Litebox owns the part you actually interact with:

  • Inbox, unread state, threaded conversations, Sent, Drafts, Archive, Starred, and Trash;
  • Compose, Reply, Reply all, CC/BCC, and attachments;
  • provider delivery states and retry diagnostics;
  • signed, replay-safe webhook ingestion backed by a durable SQLite job queue;
  • local raw .eml and attachment retention independent of provider retention;
  • strict inbound HTML sanitization and remote-image blocking;
  • full-text search with useful operators;
  • first-run setup, Argon2id passwords, hashed sessions, CSRF protection, and login throttling;
  • independent mailboxes, shared aliases, per-mailbox roles, mailbox switching, and revocable device sessions;
  • light, configurable alias colors shown consistently in the inbox and conversation view;
  • per-user daily or weekly private summaries with counts by mailbox and no message content;
  • database-backed installation settings with encrypted Resend credentials and a one-time setup link;
  • one signed, shell-free GHCR image tag that runs on Linux AMD64 and ARM64 VPS hosts;
  • built-in doctor, backup, restore, reindex, and password-recovery commands;
  • responsive server-rendered UI using Go, templ, vendored HTMX, and custom CSS.
  • mobile search, keyboard navigation, shortcut help, and clear progress/confirmation feedback.

Litebox is a mailbox, not a mail server and not a Gmail clone.

Try it now

Start a private local demo with one command. It needs only Docker, binds to 127.0.0.1, and does not require a domain or Resend account:

docker volume create litebox-demo-data
docker run --rm --name litebox-demo \
  -p 127.0.0.1:8080:8080 \
  -e APP_ENV=development \
  -e APP_BASE_URL=http://localhost:8080 \
  -v litebox-demo-data:/data \
  ghcr.io/nader-jo/litebox:0.4.1

Open http://localhost:8080/setup. Stop the demo with Ctrl-C; demo data remains in the litebox-demo-data Docker volume until you delete it. Real email receiving and sending are disabled in development mode.

Architecture

flowchart LR
    Internet["Internet email"] --> Resend["Resend transport"]
    Resend -->|"signed webhooks"| App["Litebox Go binary"]
    App -->|"retrieve / send"| Resend
    Browser["Browser"] -->|"HTTPS"| Proxy["Caddy / existing proxy"]
    Proxy --> App
    App --> SQLite["/data/mailbox.db"]
    App --> Blobs["/data/objects"]

The required runtime graph is deliberately small:

Component Default Purpose
Litebox Required UI, auth, webhooks, workers, provider adapter
SQLite Embedded Metadata, sessions, jobs, FTS5, mailbox state
Filesystem BlobStore Embedded Raw email and private attachments
Resend External Internet email receiving and delivery
Reverse proxy External or optional profile Public TLS termination

Read Architecture for invariants, module boundaries, data flow, and failure semantics.

Quick start

Prerequisites
  • Docker Engine with Compose v2;
  • a domain you can configure in Resend;
  • a Resend API key and webhook signing secret;
  • a public HTTPS hostname for webhook delivery.
1. Pull the multi-platform image
git clone --depth 1 --branch v0.4.1 https://github.com/Nader-jo/Litebox.git
cd Litebox
cp .env.example .env
# Set LITEBOX_DOMAIN to the public HTTPS hostname before starting Compose.
docker compose pull
docker compose up -d

Docker automatically selects the linux/amd64 or linux/arm64 image from the immutable release tag. The repository checkout supplies only the deployment templates (compose.yaml, Caddyfile, and .env.example); the application itself always runs from GHCR.

To build from source for development instead, follow the Development guide and use compose.build.yaml.

2. Complete the first-run wizard

Open the one-time /setup?token=… URL printed by the container. The wizard stores the mailbox identity, public URL, Resend credentials, and first administrator in SQLite. The token is invalidated after completion. Add more people and assign per-mailbox roles from Settings → People.

For headless setup:

docker compose exec mailbox /app/litebox create-admin \
  --email owner@example.com \
  --name "Mailbox Owner"
3. Connect Resend

In Resend:

  1. add and verify the receiving/sending domain;
  2. apply the exact MX, SPF, DKIM, and return-path records shown by Resend;
  3. create https://mail.example.com/webhooks/resend;
  4. subscribe it to email.received, email.sent, email.delivered, email.delivery_delayed, email.bounced, email.failed, email.suppressed, and email.complained;
  5. paste the webhook signing secret into the setup wizard or Settings → System. Credentials are encrypted using /data/.litebox/master.key.

See Resend and DNS setup, especially the MX conflict warning.

Operations

Published images are available at ghcr.io/nader-jo/litebox. Production deployments should use a complete version tag such as 0.4.1, not latest. Each release workflow builds, scans, and boots both supported platforms before publishing the GitHub release.

The image uses the same binary for the server and all administrative operations:

litebox serve
litebox migrate
litebox healthcheck
litebox doctor [--deep]
litebox backup --output <new-directory>
litebox restore --input <backup-directory>
litebox create-admin --email <email> --name <name>
litebox reset-password --email <email>
litebox reindex
litebox version
Health
  • GET /health/live checks the process only.
  • GET /health/ready checks SQLite and private blob storage, but deliberately does not depend on Resend availability.
  • /admin/system shows recent verified webhooks, job state, storage health, and database size without exposing secrets.
Mailboxes, aliases, and access
  • A mailbox has independent threads, drafts, folders, unread state, search results, and membership.
  • An alias receives into one mailbox and can be selected as an outbound From identity.
  • A user may belong to any number of mailboxes and switch between them without signing in again.
  • Roles are owner, admin, member, and viewer. Viewers cannot mutate mailbox state or send mail.
  • Each browser/device login is a separate session. Users can inspect and revoke sessions under Settings → Sessions.
  • Settings → Summary can send a daily or weekly count-only report to a private address, scoped to all or selected mailboxes.
  • Alias colors are assigned automatically and can be changed from Settings → Mailboxes; messages display the color of the address they matched.
  • If one provider message targets addresses in two independent mailboxes, Litebox archives an isolated local copy in each mailbox.

See Multi-mailbox access for role semantics, routing behavior, and migration details.

Runtime settings, encrypted secrets, setup-token recovery, alias colors, and summaries are covered in the User guide.

Backups

Litebox intentionally puts SQLite and blobs on one volume. That is simple, not redundant.

The supported MVP backup is quiesced:

docker compose stop mailbox
docker compose run --rm -v /srv/litebox-backups:/backup mailbox \
  backup --output /backup/backup-$(date +%F)
docker compose start mailbox

Every backup contains a consistent SQLite snapshot plus a manifest of logical blob keys, sizes, and SHA-256 hashes. A missing referenced blob fails the backup. Restore refuses to overwrite an existing installation.

Read Backup and restore before relying on it.

Terms search subject, sender, recipients, and plain-text content. Filters can be combined:

invoice
"renewal notice"
from:alice@example.com
to:hello@example.com
subject:invoice
has:attachment
is:unread
is:starred
after:2026-01-01
before:2026-08-01

Malformed dates and unsupported structured filters produce a visible error; they are never silently ignored or interpolated into SQL.

Security model

Litebox assumes every inbound message is hostile.

  • Webhooks are verified against their raw request body before JSON parsing.
  • Svix delivery IDs and provider email IDs provide two levels of idempotency.
  • HTML is parsed, CID references are rewritten to authenticated routes, remote images are removed, and a strict allow-list sanitizer runs before storage/display.
  • Attachments and raw mail are never exposed through the static asset handler.
  • SVG and HTML attachments download rather than render in the application origin.
  • Session and CSRF secrets are random 256-bit values; only hashes are stored in SQLite.
  • The mailbox selector cookie is untrusted: every request resolves it through the authenticated user's membership, and content repositories require a mailbox scope.
  • Authenticated sends are capped at 30 per user per rolling hour, and each message is capped at 20 recipients.
  • Production refuses an HTTP APP_BASE_URL or missing Resend credentials.
  • The shell-free scratch container is non-root, drops Linux capabilities, uses a read-only root filesystem, and writes only to /data and a bounded /tmp tmpfs.

Review SECURITY.md for reporting and supported versions, and Threat model for trust boundaries and residual risks.

Development

Requirements: Go 1.26.6+, Docker, and GNU Make (optional). The patch-level floor includes required Go standard-library security fixes.

make setup # install pinned tools, generate code, and validate the checkout
make check # generate, format, lint, race-test, audit, build, and validate Compose

Run locally with development defaults:

APP_ENV=development go run ./cmd/mailbox serve

Generated *_templ.go files are committed so release builds do not need a JavaScript toolchain. CI regenerates them and fails on drift.

See Development guide for package boundaries, tests, fake-provider usage, and pull-request expectations.

Project documentation

Document Audience
Architecture Maintainers and integrators
Multi-mailbox access Operators and administrators
User guide Mailbox users
Deployment Operators
Safe upgrades Operators
Resend setup Domain and webhook operators
Backup and restore Operators
Threat model Security reviewers
Development Contributors
Release process Maintainers
Repository settings Repository administrators
Roadmap Community
Vision Users and contributors
Contributing Contributors
Contributors Community
Governance Maintainers and contributors
Support Users and operators

Deliberate non-goals

Litebox does not implement SMTP, IMAP, POP3, JMAP, multi-tenant SaaS isolation, shared-inbox assignment/notes, contacts, calendars, rich-text composition, rules, scheduled sending, or a spam classifier. Optional S3-compatible storage is a future adapter; it is not a dependency of the default system.

Community

Bug reports, focused feature proposals, documentation improvements, tests, and careful security reviews are welcome. Start with the streamlined contribution guide, read the project vision, and meet the people in CONTRIBUTORS.md. Participation follows GOVERNANCE.md and the Code of Conduct.

License

Litebox is licensed under the Apache License 2.0. Vendored HTMX remains under its BSD 2-Clause license, and selected Tabler Icons v3.46.0 paths remain under MIT; see NOTICE.

Directories

Path Synopsis
cmd
mailbox command
internal
app
Package app assembles and runs the Litebox modular monolith.
Package app assembles and runs the Litebox modular monolith.
auth
Package auth implements password and browser-session security primitives.
Package auth implements password and browser-session security primitives.
blobstore
Package blobstore provides private provider-neutral durable byte storage.
Package blobstore provides private provider-neutral durable byte storage.
config
Package config loads and validates Litebox runtime configuration.
Package config loads and validates Litebox runtime configuration.
db
Package db owns SQLite lifecycle and embedded schema migrations.
Package db owns SQLite lifecycle and embedded schema migrations.
httpserver
Package httpserver exposes Litebox's secure server-rendered HTTP surface.
Package httpserver exposes Litebox's secure server-rendered HTTP surface.
ids
Package ids provides dependency-free UUIDv4 identifiers.
Package ids provides dependency-free UUIDv4 identifiers.
jobs
Package jobs runs durable SQLite jobs with bounded leases and retry backoff.
Package jobs runs durable SQLite jobs with bounded leases and retry backoff.
mail
Package mail contains provider-neutral email normalization and safety rules.
Package mail contains provider-neutral email normalization and safety rules.
model
Package model defines provider-neutral Litebox domain data.
Package model defines provider-neutral Litebox domain data.
ops
Package ops implements recovery-safe CLI operations.
Package ops implements recovery-safe CLI operations.
provider
Package provider defines the email-transport boundary used by application services.
Package provider defines the email-transport boundary used by application services.
repository
Package repository contains all SQL used by Litebox application services.
Package repository contains all SQL used by Litebox application services.
search
Package search parses Litebox's intentionally small search language.
Package search parses Litebox's intentionally small search language.
secrets
Package secrets provides small, file-backed encryption primitives for installation secrets.
Package secrets provides small, file-backed encryption primitives for installation secrets.
service
Package service coordinates mailbox workflows across repositories, providers, and blob storage.
Package service coordinates mailbox workflows across repositories, providers, and blob storage.
settings
Package settings persists installation-wide settings and encrypted provider credentials.
Package settings persists installation-wide settings and encrypted provider credentials.
ui
templ: version: v0.3.1020
templ: version: v0.3.1020
Package webassets embeds the complete dependency-free browser surface.
Package webassets embeds the complete dependency-free browser surface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL