NOTE: The primary repository is on Codeberg. Issues and pull requests should be submitted there.
A local-first daily habit tracker with real-time sync across devices.
I have the same TO-DO list every day and it makes me feel good to check off my items as I do them. I hate most todo list apps because:
- I want local first, I don't want to wait for it to load
- I want it on my desktop PC, any browser, on my phone - and sync'd
- I want public accountability. Some days are hard. Knowing people can see me and even react can help a lot.
Eventually I'd like this app to publish to ActivityPub (Fediverse) and ATProto (Bluesky). First I'll get this working on just web.
- Daily checklist with completion tracking
- Real-time sync across tabs/devices via PubSub
- Drag-and-drop task reordering
- Inline task editing
- Archive/restore tasks
- CRDT-compatible data structures for future offline-first support
- Backend: Elixir, Phoenix 1.8, Ecto
- Database: SQLite
- Frontend: Phoenix LiveView, Tailwind CSS, daisyUI
- Elixir 1.18+
- Erlang/OTP 27+ (with wxWidgets support for desktop mode)
# Clone the repository
git clone https://codeberg.org/ellyxir/habitlist.git
cd habitlist
# Install dependencies
mix setup
# Start the development server
mix phx.serverVisit http://localhost:4000 in your browser.
Development uses default settings with a local SQLite database and a mailbox viewer for emails at http://localhost:4000/dev/mailbox.
Set these environment variables:
| Variable | Required | Description |
|---|---|---|
SECRET_KEY_BASE |
Yes | Generate with mix phx.gen.secret |
DATABASE_PATH |
Yes | Path to SQLite database file |
PHX_HOST |
Yes | Production hostname (e.g., habitlist.example.com) |
PORT |
No | HTTP port (default: 4000) |
SMTP_RELAY |
No | SMTP server hostname |
SMTP_PORT |
No | SMTP port (default: 587, uses STARTTLS) |
SMTP_USERNAME |
If SMTP | SMTP username |
SMTP_PASSWORD |
If SMTP | SMTP password |
MAILER_FROM |
No | Email "from" address (default: [email protected]) |
Habitlist can run as a native desktop application using elixir-desktop.
Add these to your configuration.nix or home.nix:
environment.systemPackages = with pkgs; [
# Erlang with wx support (included in nixpkgs erlang)
erlang
elixir
# wxWidgets with WebView support
wxGTK32
webkitgtk_4_1
# Build dependencies
gcc
gnumake
pkg-config
];Or in a development shell:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
erlang
elixir
wxGTK32
webkitgtk_4_1
gcc
gnumake
pkg-config
];
}Install the equivalent packages:
# Debian/Ubuntu
sudo apt install libwxgtk-webview3.0-gtk3-dev libssl-dev
# Fedora
sudo dnf install wxGTK3-devel webkit2gtk3-develHABITLIST_DESKTOP=1 mix run --no-haltThe application will open in a native window with data stored in:
- Database:
~/.local/share/habitlist/habitlist.db - Config:
~/.config/habitlist/
-
Erlang/OTP 27+ with wxWidgets support
winget install Erlang.ErlangOTP
-
Elixir 1.18+
- Download from elixir-lang.org/install
-
Visual C++ Build Tools (for NIF compilation)
winget install Microsoft.VisualStudio.2022.BuildToolsThen open Visual Studio Installer and add the "Desktop development with C++" workload.
Clone the repository and use the build script:
git clone https://codeberg.org/ellyxir/habitlist.git
cd habitlist
.\scripts\build-windows.ps1
.\scripts\run-desktop.ps1Or manually:
$env:HABITLIST_DESKTOP=1; mix run --no-haltThe application will open in a native window with data stored in:
- Database:
%LOCALAPPDATA%\habitlist\habitlist.db - Config:
%APPDATA%\habitlist\
Build a release:
MIX_ENV=prod mix releaseRun migrations in production:
bin/habitlist eval "Habitlist.Release.migrate"Start the server:
PHX_SERVER=true bin/habitlist startYes, contributions are welcome, send a PR!
Copyright 2026 Ellyse Cedeno
Licensed under the Apache License, Version 2.0. See LICENSE for details.