Skip to content

Rebranding

ihasmail is AGPL-3.0-or-later, and a rebrand is a modified version

Read this part before the artwork, because it is the only obligation on the page. Everything below it is a choice.

The GNU Affero General Public License v3 lets you do what you are presumably here to do: run it, study it, change it, and deploy it under your own name, commercially if you like. Nobody needs your permission and you do not need anybody's. What it asks in return is that the freedom travels with the software.

Three things follow, and the third is the one people miss:

Your modified version is AGPL too. A rebranded ihasmail is a derivative work, so it carries the same licence, and the copyright and licence notices stay where they are.

Your users are owed your source, not upstream's. Not the tree you forked from — yours, with your changes in it.

Running it as a service counts as distribution. This is section 13, the part that separates the AGPL from the ordinary GPL. Under the GPL, handing nobody a binary means owing nobody source, and webmail is nearly always run rather than handed over. Section 13 closes that gap: if people interact with your modified version over a network, they must be offered its source.

Which is what SOURCE_URL is for

ihasmail's answer to section 13 is an environment variable. Point SOURCE_URL at your repository and the offer is made: the sign-in page and Settings › About both show it, so the people using your instance are told where the code they are actually running can be found.

Left at its default, a rebranded instance points its users at upstream — which is both the wrong tree and, since it is the only offer being made, a licence problem rather than an oversight.

One thing the licence does not cover: it governs the code, not a project's name or artwork. Trademarks are a separate question from copyright, which is a practical reason to replace the mark and the wordmark rather than only the config — a rebrand that leaves the original branding in place is a different kind of problem from a licence one.

This is a plain-language summary of what the licence asks, not legal advice. The text that governs is in LICENSE.

What is a setting, and what is a fork

Two of these are settings. The rest is a fork.

APP_NAME and SOURCE_URL are environment variables, read at runtime and changeable without touching the code. Everything else — the sign-in heading, the artwork, the colours, the manifest — is compiled into web/dist when the image is built, so changing it means keeping your own tree and building your own image.

What APP_NAME changes

No rebuild needed. Set it and restart.

Where What it looks like
The browser tab, after sign-in Acme Mail — with an unread count in front of it
/api/health {"ok":true,"name":"Acme Mail","version":"…"}
The two-factor issuer what an authenticator app files the account under
App passwords ihasmail mints for a browser Acme Mail (Firefox)
The startup log line [ihasmail] Acme Mail listening on …

That last one keeps the [ihasmail] prefix: it identifies the software in a log, not the instance.

What it does not change

These are compiled in. Each needs an edit in your own tree and a rebuilt image.

What Where
Sign-in heading and tagline web/src/views/Login.tsx
Sign-in footer — the version line and the ihasmail.org link web/src/views/Login.tsx
The brand beside the logo in the top bar web/src/views/AppShell.tsx
The tab title before sign-in <title> in web/index.html
The installed-app name web/public/manifest.webmanifest

The sign-in page does not read APP_NAME at all

It fetches /api/config, which returns the name — and then uses only sourceUrl from that response. So an instance with APP_NAME set still says ihasmail on the page where a new user meets it first. If you change nothing else on this page, change this.

The artwork

File Used for
web/public/img/logo.png the sign-in card and the top bar
web/public/img/icon-192.png · icon-512.png the installed app
web/public/img/icon-maskable.png Android's masked icon — keep the safe area
web/public/img/apple-touch-icon.png iOS home screen
web/public/img/favicon-64.png · web/public/favicon.ico the browser tab

The sign-in card renders the logo at 120×143, so it is a portrait mark rather than a square one. ihasmail's own artwork carries no wordmark — the name beside it is text — which is worth copying: a mark with the name baked into the pixels has to be redrawn for every size and every rebrand.

The colours

web/src/styles/app.css, in four places:

:root                            { --accent: #0f766e;  }  /* light */
:root[data-theme="dark"]         { --accent: #2dd4bf;  }  /* dark */
:root[data-palette="ihasmail"]   { --accent: #46cac3;  }  /* the house palette */
:root[data-accent="blue"]        { --accent: #2563eb;  }  /* user accents */

The third is the palette a new account starts on, so it is the one most people will see. The fourth is a set of accents a user can pick over the top of any theme — leave those alone unless you want to offer a different set, because overriding the brand is what they are for.

Two more colours live outside that file and are easy to miss:

  • theme_color in web/public/manifest.webmanifest — the installed app's system chrome
  • <meta name="theme-color"> in web/index.html — mobile browser chrome

These two currently disagree in upstream ihasmail (#0f766e and #0d2430). Set both deliberately rather than copying one.

Leave these alone

They contain the name, and none of them are brand surface. Renaming them costs something and gains nothing.

Name Renaming it costs
VERSION and VERIFY_KEY in web/public/sw.js invalidates every cached shell and every stored push verification at once
ihasmail:lastUser, ihasmail-theme in localStorage every user's remembered address and theme, silently
application/x-ihasmail-emails · -folder drag and drop, until every producer and consumer agrees again
the "ihasmail" theme value in settings.json strands the stored preference of everyone already on it, since the value is what is saved, not the label

The last one is the one to think about: the theme's palette is yours to change — that is the [data-palette="ihasmail"] block above — while its stored value is data that already exists in your users' accounts.

Rebuilding

Same as any build, with the version passed in, since .dockerignore keeps .git out of the context:

docker build --build-arg IHASMAIL_VERSION="$(node scripts/version.mjs)" -t acme-mail:2.16 .

If you are carrying your own patches, your own version scheme probably makes more sense than upstream's 2.16.<PR> — the argument is a plain string.

Checklist

  • SOURCE_URL points at your repository
  • APP_NAME set
  • Sign-in heading, tagline and footer link
  • Top-bar brand
  • <title> in web/index.html
  • manifest.webmanifestname, short_name, description, theme_color
  • Logo, both app icons, the maskable icon, apple-touch, both favicons
  • Accent colours in the three theme blocks
  • <meta name="theme-color">
  • Nothing in Leave these alone touched
  • Image rebuilt, and the sign-in page checked in a private window

Related: Configuring for APP_NAME and SOURCE_URL in context, and Installing for the build.