Install and build
This page covers installing a release, building from source, and producing the release binaries and Debian packages yourself.
Install a release
Section titled “Install a release”From the apt repository
Section titled “From the apt repository”On Debian and Ubuntu, use the apt repository on Codeberg: it installs tmail, and the system updates it with the other packages. It has the packages for amd64 and arm64, and it works on Debian 12 and 13 and on Ubuntu 22.04 and 24.04 (these are the versions it was tested on). No account is needed to read it.
sudo curl https://codeberg.org/api/packages/squidd/debian/repository.key -o /etc/apt/keyrings/forgejo-squidd.ascecho "deb [signed-by=/etc/apt/keyrings/forgejo-squidd.asc] https://codeberg.org/api/packages/squidd/debian stable main" | sudo tee /etc/apt/sources.list.d/tmail.listsudo apt update && sudo apt install tmailThe repository has two distributions, stable and nightly. stable holds the packages of the releases; nightly holds the builds of every night (see Nightly builds). The distribution is a word in the line above, not the name of your system, so the same line works on every version. The key of the registry signs the repository and apt checks every package with it.
Download a release
Section titled “Download a release”Each release on Codeberg has one archive per platform, a .deb file per architecture and a SHA256SUMS file.
On Debian and Ubuntu, a downloaded package installs with:
sudo apt install ./tmail_<version>-1_amd64.debOn other systems, unpack tmail-<version>-<rid>.tar.gz (.zip on Windows) and copy tmail to a folder on your PATH.
Check a download
Section titled “Check a download”Each release carries SHA256SUMS and SHA256SUMS.asc, a signature of that file made with a key that only signs the releases of tmail. If you download an archive or a package by hand, check where it comes from:
Get the key from the keyserver:
gpg --keyserver hkps://keys.openpgp.org --recv-keys 4C26F8B053103FD18BD144847C1034F0B3541CAAor from the repository, if you do not want to ask a server:
curl -fsSLO https://codeberg.org/squidd/TildeMail/raw/branch/develop/RELEASE-KEY.ascgpg --import RELEASE-KEY.ascThen check the signature and the files:
gpg --verify SHA256SUMS.asc SHA256SUMSsha256sum --check --ignore-missing SHA256SUMSThe key is TildeMail release signing <tom@orivega.io>, and its fingerprint is 4C26 F8B0 5310 3FD1 8BD1 4484 7C10 34F0 B354 1CAA. It is published on keys.openpgp.org for tom@orivega.io. gpg says that the key is not certified, because you have not signed it: what matters is that Good signature shows that fingerprint, so compare it with this page. The packages of the apt repository do not need this check: apt verifies them with the key of the registry.
Nightly builds
Section titled “Nightly builds”The packages of develop are built every night and put in the nightly distribution of the same registry. Their version carries a pre-release marker, for example 0.3.0-nightly.202610310300.g1a2b3c4 (tmail --version prints it), and Debian sorts it before the release it leads to. The last seven are kept; a night without a new commit builds nothing.
Use one distribution at a time: nightly and stable hold a package of the same name, and apt installs the newest version it can see.
sudo curl https://codeberg.org/api/packages/squidd/debian/repository.key -o /etc/apt/keyrings/forgejo-squidd.ascecho "deb [signed-by=/etc/apt/keyrings/forgejo-squidd.asc] https://codeberg.org/api/packages/squidd/debian nightly main" | sudo tee /etc/apt/sources.list.d/tmail.listsudo apt update && sudo apt install tmailShell completion
Section titled “Shell completion”tmail completion <shell> prints a completion script for bash, zsh or fish. It completes the commands, the second word of cache, gpg, rules and themes, the option names, and file names for --config and --body-file.
Save the script to a file once. Sourcing it with source <(tmail completion ...) is the alternative: it works, but it starts tmail at every shell start. That is quick, and it reads no config.toml, creates no file and needs no configuration, but a saved file starts nothing.
Save the script where bash-completion looks for it:
mkdir -p ~/.local/share/bash-completion/completionstmail completion bash > ~/.local/share/bash-completion/completions/tmailOr add this line to ~/.bashrc:
source <(tmail completion bash)Save the script as _tmail in a folder of $fpath:
mkdir -p ~/.zfunctmail completion zsh > ~/.zfunc/_tmailand add fpath=(~/.zfunc $fpath) to ~/.zshrc, above autoload -Uz compinit && compinit.
Or add this line to ~/.zshrc, after the compinit line:
source <(tmail completion zsh)Sourced before compinit, the script fails with command not found: compdef.
tmail completion fish > ~/.config/fish/completions/tmail.fishfish loads the file the next time it starts.
The script lists the commands of the version that printed it, so print it again after an upgrade. The Debian package does not install it.
Requirements
Section titled “Requirements”- The .NET 10 SDK, to build.
global.jsonrolls forward to the latest patch. gpgonPATH, for signing, verifying, encrypting and decrypting. Without it, the GPG tests are skipped.- Optional:
notify-send, whichsys.notifycalls. - Optional: Docker, for the live IMAP and SMTP tests (see Development).
Build from source
Section titled “Build from source”dotnet build TildeMail.slnxdotnet test TildeMail.slnxdotnet build produces a framework-dependent tmail under src/TildeMail.App/bin/. To run it from the source tree:
dotnet run --project src/TildeMail.App -- checkSingle-file executable
Section titled “Single-file executable”scripts/build-binaries.shThe script publishes a self-contained, single-file tmail that needs no .NET runtime. By default it builds these targets: linux-x64, linux-arm64, osx-x64, osx-arm64 and win-x64. win-arm64 is accepted with --rid.
It leaves in dist/:
- one archive per target,
tmail-<version>-<rid>.tar.gz(.zipfor Windows), holding atmail-<version>-<rid>/folder withtmail(tmail.exeon Windows),LICENSE,THIRD-PARTY-NOTICES.mdand thethemes/andlangs/folders (copy what you want into~/.config/tildemail/: tmail does not read the folders of the archive); - a
SHA256SUMSfile.
The version is the project’s version, so it is the number tmail --version prints.
Run the script on Linux. It needs GNU realpath, sha256sum and tar, plus zip for the Windows targets. Every target is built on that machine: the first time, the .NET SDK downloads the runtime pack of each target.
| Option | Effect |
|---|---|
-r, --rid RID |
Build only this runtime identifier; repeat for several. |
-o, --output DIR |
Output folder (default dist). |
-n, --dry-run |
Print the steps and do nothing. |
--no-archive |
Leave the plain binaries in DIR/<rid>/; no archives, no checksums. |
To publish by hand, use the project, not TildeMail.slnx:
dotnet publish src/TildeMail.App -c Release -r linux-x64 -o outOn its first run the binary unpacks one native library (libonigwrap.so on Linux) under ~/.net. Set DOTNET_BUNDLE_EXTRACT_BASE_DIR to change that location.
Debian packages
Section titled “Debian packages”scripts/build-deb.shThe script builds tmail_<version>-1_amd64.deb and tmail_<version>-1_arm64.deb in dist/; each also carries the manual pages (man tmail, man tmail-config), the ready-made themes (see Themes), the translations (see Languages) and the third-party licenses in /usr/share/doc/tmail/THIRD-PARTY-NOTICES.md. It needs dpkg-deb (apt install dpkg-dev).
| Option | Effect |
|---|---|
-a, --arch ARCH |
Build only this Debian architecture, amd64 or arm64; repeat for several. |
-o, --output DIR |
Folder with the binaries and the .deb files (default dist). |
-n, --dry-run |
Print the steps and do nothing. |
The script always rebuilds the binary first with scripts/build-binaries.sh --no-archive, so a package never carries an older build.
The package:
- installs
/usr/bin/tmail, the manual pagestmail(1)andtmail-config(5), made bytmail man, the themes of thethemes/folder in/usr/share/tildemail/themes/and the languages of thelangs/folder in/usr/share/tildemail/langs/; - depends on
ca-certificatesand on the C and C++ runtime, zlib, OpenSSL and ICU libraries; - recommends
gnupgand suggestslibnotify-bin.
A pre-release version such as 0.2.0-rc1 is written 0.2.0~rc1, so that it sorts before 0.2.0.