Skip to content

Repository files navigation

Deltos

English | Español

WebsiteReleaseCILicenseSupport on Ko-fi

Deltos kanban board with three columns (New, In progress, Done), project and label filters, and task cards with priority and due dates

Deltos is a task-management PWA for everyday life: a shared kanban board with live sync, comments, attachments and push notifications, served by a single small Node + SQLite service. It works for a couple, a family, a group of friends planning a trip, or a small team, without the complexity of the big tools and without your data on somebody else's cloud.

The name

Deltos comes from the ancient Greek δέλτος (déltos): a writing tablet, and by extension any written record or letter. Before paper, that was how you kept notes on what mattered. The name fit an app whose whole point is writing tasks down and keeping them where the people who share them can see them.

Why does this exist?

Deltos started as the board for a friends' trip: six people, a spreadsheet nobody updated, and a chat where every decision got buried. Then we kept using it at home for the day-to-day stuff, and again through a renovation and the move that came with it. Everything we had tried before wanted an account and a subscription, kept our lists on someone else's server, or brought more process than a family needs. So I built the small thing: one service, one file of database, a board that syncs live. It does less than Trello or Jira, and for us that was the point.

Why this stack?

  • Node 22 + Hono + better-sqlite3: the app is mostly I/O: SSE live sync, uploads, a handful of concurrent users. Node's event loop fits that shape and Hono adds routing without framework tax.
  • SQLite, no external database: one file under /var/lib/deltos, WAL mode; a backup is a file copy. Nothing to administer for a few users.
  • systemd behind Nginx Proxy Manager, no Docker: it runs in a small LXC at home; fewer layers, logs in journald, an upgrade is a symlink swap (Docker is still available as an alternative, see Installation).
  • React 19 + Vite + Tailwind: the UI shell (sidebar, themes, i18n, settings) is shared with my other apps, so a fix lands everywhere at once.

Features

  • Shared kanban: New / In progress / Done columns with drag & drop, live between sessions over SSE (no refresh, no polling).
  • Push notifications: Web Push (VAPID) when someone creates, moves, comments on or assigns you a card, even with the app closed. Dormant on plain HTTP; turns itself on once the app is served over HTTPS.
  • Cards with everything: comments, attachments with an in-app image viewer, labels, priority, due dates and a per-card activity feed.
  • Multiuser: admin/user roles, per-user language (ES/EN), bcrypt passwords, rate-limited login, audit trail.
  • Installable PWA: light/dark theme following the system, offline service worker, "check for updates" against GitHub releases from Settings.
  • One-click demo mode: separate seeded database, no password; can be disabled in Settings.
  • SQLite storage: WAL mode, single file under /var/lib/deltos.

Screenshots

Card detail: tabs for details, attachments, comments and activity**

Task modal showing title, project, assignee, priority, due date, labels, description and move-to column actions

Settings: appearance with accent color, profile, labels, language**

Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector

Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.

curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh # (recommended)

The installer is a readable, dependency-free POSIX shell script. Inspect it before running: that's the point of keeping it plain. It detects your distro/arch, downloads the latest release and verifies its SHA-256 checksum, installs a versioned Node runtime and the app under /opt/deltos, creates a sandboxed deltos systemd service and prints the initial admin password once.

Running the same command again later upgrades to the latest release. To uninstall: curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh -s -- --uninstall.

Docker
docker build -t deltos .
docker run -d --name deltos -p 3000:3000 \
-e AUTH_USER=admin -e AUTH_PASS='use-a-strong-password' \
-v deltos-data:/app/data \
deltos

Multi-stage node:24-slim image: npm ci --omit=dev for the server + server/ + app/dist/. Mount a volume at /app/data (SQLite + uploads). The .env file is not copied into the image: everything comes from defaults + container environment.

Manual installation (from a release tarball)

Download the artifact for your architecture from Releases and verify it against checksums.txt (sha256sum -c checksums.txt --ignore-missing). Releases are published per v* tag with node_modules pre-built per arch (.github/workflows/release.yml); no compiler needed on the server.

Configuration

The service reads its environment (installer: /etc/deltos/env):

VariableDefaultDescription
PORT3000Listen port (behind Nginx Proxy Manager).
DATA_DIR/var/lib/deltosSQLite files + uploads.
STATIC_DIRapp/distBuilt frontend to serve.
AUTH_USER/AUTH_PASS-Bootstrap admin on first boot (idempotent).
COOKIE_SECUREfalsetrue only behind HTTPS.
SESSION_SECRETauto-generatedHMAC secret; persisted in the DB if unset.
MAX_SSE_CLIENTS20Concurrent live-sync clients.
MAX_UPLOAD_MB10Attachment size limit.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT-Web Push keys (all three or none). Generate with npx web-push generate-vapid-keys --json; subject must be a mailto:. Without them, push stays off and the app runs fine.

Restart after changes: sudo systemctl restart deltos.

Credentials

  • Production: first boot creates the admin from AUTH_USER / AUTH_PASS (if AUTH_PASS is missing, no admin is created and a warning is logged).
  • Demo: "Sign in as demo" button on the login screen (no password). Separate demo database (app_demo.db), seeded with 3 users, 4 projects, 6 labels and 15 tasks. Can be disabled in Settings (admin only).

Development

Stack: Node 24 + Hono + better-sqlite3 (backend) · React 19 + Vite + Tailwind (frontend).

# Backend (port 3000 by default; see server/.env.example)cd server
npm ci
cp .env.example .env # adjust AUTH_USER / AUTH_PASS
npm run dev
# Frontend (another terminal, proxied to the backend in dev)cd app
npm ci
npm run dev
# Production frontend build (served by the backend itself)
npm run build

With npm run build done, the backend alone is enough: it serves the SPA from app/dist with SPA fallback.

Tests

cd server && npm test# vitest: 76 API/auth/push/label tests

License

AGPL-3.0

About

PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - gnacho/deltos: PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19. · GitHub
Skip to content

Repository files navigation

Deltos

English | Español

WebsiteReleaseCILicenseSupport on Ko-fi

Deltos kanban board with three columns (New, In progress, Done), project and label filters, and task cards with priority and due dates

Deltos is a task-management PWA for everyday life: a shared kanban board with live sync, comments, attachments and push notifications, served by a single small Node + SQLite service. It works for a couple, a family, a group of friends planning a trip, or a small team, without the complexity of the big tools and without your data on somebody else's cloud.

The name

Deltos comes from the ancient Greek δέλτος (déltos): a writing tablet, and by extension any written record or letter. Before paper, that was how you kept notes on what mattered. The name fit an app whose whole point is writing tasks down and keeping them where the people who share them can see them.

Why does this exist?

Deltos started as the board for a friends' trip: six people, a spreadsheet nobody updated, and a chat where every decision got buried. Then we kept using it at home for the day-to-day stuff, and again through a renovation and the move that came with it. Everything we had tried before wanted an account and a subscription, kept our lists on someone else's server, or brought more process than a family needs. So I built the small thing: one service, one file of database, a board that syncs live. It does less than Trello or Jira, and for us that was the point.

Why this stack?

  • Node 22 + Hono + better-sqlite3: the app is mostly I/O: SSE live sync, uploads, a handful of concurrent users. Node's event loop fits that shape and Hono adds routing without framework tax.
  • SQLite, no external database: one file under /var/lib/deltos, WAL mode; a backup is a file copy. Nothing to administer for a few users.
  • systemd behind Nginx Proxy Manager, no Docker: it runs in a small LXC at home; fewer layers, logs in journald, an upgrade is a symlink swap (Docker is still available as an alternative, see Installation).
  • React 19 + Vite + Tailwind: the UI shell (sidebar, themes, i18n, settings) is shared with my other apps, so a fix lands everywhere at once.

Features

  • Shared kanban: New / In progress / Done columns with drag & drop, live between sessions over SSE (no refresh, no polling).
  • Push notifications: Web Push (VAPID) when someone creates, moves, comments on or assigns you a card, even with the app closed. Dormant on plain HTTP; turns itself on once the app is served over HTTPS.
  • Cards with everything: comments, attachments with an in-app image viewer, labels, priority, due dates and a per-card activity feed.
  • Multiuser: admin/user roles, per-user language (ES/EN), bcrypt passwords, rate-limited login, audit trail.
  • Installable PWA: light/dark theme following the system, offline service worker, "check for updates" against GitHub releases from Settings.
  • One-click demo mode: separate seeded database, no password; can be disabled in Settings.
  • SQLite storage: WAL mode, single file under /var/lib/deltos.

Screenshots

Card detail: tabs for details, attachments, comments and activity**

Task modal showing title, project, assignee, priority, due date, labels, description and move-to column actions

Settings: appearance with accent color, profile, labels, language**

Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector

Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.

curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh # (recommended)

The installer is a readable, dependency-free POSIX shell script. Inspect it before running: that's the point of keeping it plain. It detects your distro/arch, downloads the latest release and verifies its SHA-256 checksum, installs a versioned Node runtime and the app under /opt/deltos, creates a sandboxed deltos systemd service and prints the initial admin password once.

Running the same command again later upgrades to the latest release. To uninstall: curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh -s -- --uninstall.

Docker
docker build -t deltos .
docker run -d --name deltos -p 3000:3000 \
-e AUTH_USER=admin -e AUTH_PASS='use-a-strong-password' \
-v deltos-data:/app/data \
deltos

Multi-stage node:24-slim image: npm ci --omit=dev for the server + server/ + app/dist/. Mount a volume at /app/data (SQLite + uploads). The .env file is not copied into the image: everything comes from defaults + container environment.

Manual installation (from a release tarball)

Download the artifact for your architecture from Releases and verify it against checksums.txt (sha256sum -c checksums.txt --ignore-missing). Releases are published per v* tag with node_modules pre-built per arch (.github/workflows/release.yml); no compiler needed on the server.

Configuration

The service reads its environment (installer: /etc/deltos/env):

VariableDefaultDescription
PORT3000Listen port (behind Nginx Proxy Manager).
DATA_DIR/var/lib/deltosSQLite files + uploads.
STATIC_DIRapp/distBuilt frontend to serve.
AUTH_USER/AUTH_PASS-Bootstrap admin on first boot (idempotent).
COOKIE_SECUREfalsetrue only behind HTTPS.
SESSION_SECRETauto-generatedHMAC secret; persisted in the DB if unset.
MAX_SSE_CLIENTS20Concurrent live-sync clients.
MAX_UPLOAD_MB10Attachment size limit.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT-Web Push keys (all three or none). Generate with npx web-push generate-vapid-keys --json; subject must be a mailto:. Without them, push stays off and the app runs fine.

Restart after changes: sudo systemctl restart deltos.

Credentials

  • Production: first boot creates the admin from AUTH_USER / AUTH_PASS (if AUTH_PASS is missing, no admin is created and a warning is logged).
  • Demo: "Sign in as demo" button on the login screen (no password). Separate demo database (app_demo.db), seeded with 3 users, 4 projects, 6 labels and 15 tasks. Can be disabled in Settings (admin only).

Development

Stack: Node 24 + Hono + better-sqlite3 (backend) · React 19 + Vite + Tailwind (frontend).

# Backend (port 3000 by default; see server/.env.example)cd server
npm ci
cp .env.example .env # adjust AUTH_USER / AUTH_PASS
npm run dev
# Frontend (another terminal, proxied to the backend in dev)cd app
npm ci
npm run dev
# Production frontend build (served by the backend itself)
npm run build

With npm run build done, the backend alone is enough: it serves the SPA from app/dist with SPA fallback.

Tests

cd server && npm test# vitest: 76 API/auth/push/label tests

License

AGPL-3.0

About

PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gnacho/deltos: PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19. · GitHub
Skip to content

Repository files navigation

Deltos

English | Español

WebsiteReleaseCILicenseSupport on Ko-fi

Deltos kanban board with three columns (New, In progress, Done), project and label filters, and task cards with priority and due dates

Deltos is a task-management PWA for everyday life: a shared kanban board with live sync, comments, attachments and push notifications, served by a single small Node + SQLite service. It works for a couple, a family, a group of friends planning a trip, or a small team, without the complexity of the big tools and without your data on somebody else's cloud.

The name

Deltos comes from the ancient Greek δέλτος (déltos): a writing tablet, and by extension any written record or letter. Before paper, that was how you kept notes on what mattered. The name fit an app whose whole point is writing tasks down and keeping them where the people who share them can see them.

Why does this exist?

Deltos started as the board for a friends' trip: six people, a spreadsheet nobody updated, and a chat where every decision got buried. Then we kept using it at home for the day-to-day stuff, and again through a renovation and the move that came with it. Everything we had tried before wanted an account and a subscription, kept our lists on someone else's server, or brought more process than a family needs. So I built the small thing: one service, one file of database, a board that syncs live. It does less than Trello or Jira, and for us that was the point.

Why this stack?

  • Node 22 + Hono + better-sqlite3: the app is mostly I/O: SSE live sync, uploads, a handful of concurrent users. Node's event loop fits that shape and Hono adds routing without framework tax.
  • SQLite, no external database: one file under /var/lib/deltos, WAL mode; a backup is a file copy. Nothing to administer for a few users.
  • systemd behind Nginx Proxy Manager, no Docker: it runs in a small LXC at home; fewer layers, logs in journald, an upgrade is a symlink swap (Docker is still available as an alternative, see Installation).
  • React 19 + Vite + Tailwind: the UI shell (sidebar, themes, i18n, settings) is shared with my other apps, so a fix lands everywhere at once.

Features

  • Shared kanban: New / In progress / Done columns with drag & drop, live between sessions over SSE (no refresh, no polling).
  • Push notifications: Web Push (VAPID) when someone creates, moves, comments on or assigns you a card, even with the app closed. Dormant on plain HTTP; turns itself on once the app is served over HTTPS.
  • Cards with everything: comments, attachments with an in-app image viewer, labels, priority, due dates and a per-card activity feed.
  • Multiuser: admin/user roles, per-user language (ES/EN), bcrypt passwords, rate-limited login, audit trail.
  • Installable PWA: light/dark theme following the system, offline service worker, "check for updates" against GitHub releases from Settings.
  • One-click demo mode: separate seeded database, no password; can be disabled in Settings.
  • SQLite storage: WAL mode, single file under /var/lib/deltos.

Screenshots

Card detail: tabs for details, attachments, comments and activity**

Task modal showing title, project, assignee, priority, due date, labels, description and move-to column actions

Settings: appearance with accent color, profile, labels, language**

Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector

Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.

curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh # (recommended)

The installer is a readable, dependency-free POSIX shell script. Inspect it before running: that's the point of keeping it plain. It detects your distro/arch, downloads the latest release and verifies its SHA-256 checksum, installs a versioned Node runtime and the app under /opt/deltos, creates a sandboxed deltos systemd service and prints the initial admin password once.

Running the same command again later upgrades to the latest release. To uninstall: curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh -s -- --uninstall.

Docker
docker build -t deltos .
docker run -d --name deltos -p 3000:3000 \
-e AUTH_USER=admin -e AUTH_PASS='use-a-strong-password' \
-v deltos-data:/app/data \
deltos

Multi-stage node:24-slim image: npm ci --omit=dev for the server + server/ + app/dist/. Mount a volume at /app/data (SQLite + uploads). The .env file is not copied into the image: everything comes from defaults + container environment.

Manual installation (from a release tarball)

Download the artifact for your architecture from Releases and verify it against checksums.txt (sha256sum -c checksums.txt --ignore-missing). Releases are published per v* tag with node_modules pre-built per arch (.github/workflows/release.yml); no compiler needed on the server.

Configuration

The service reads its environment (installer: /etc/deltos/env):

VariableDefaultDescription
PORT3000Listen port (behind Nginx Proxy Manager).
DATA_DIR/var/lib/deltosSQLite files + uploads.
STATIC_DIRapp/distBuilt frontend to serve.
AUTH_USER/AUTH_PASS-Bootstrap admin on first boot (idempotent).
COOKIE_SECUREfalsetrue only behind HTTPS.
SESSION_SECRETauto-generatedHMAC secret; persisted in the DB if unset.
MAX_SSE_CLIENTS20Concurrent live-sync clients.
MAX_UPLOAD_MB10Attachment size limit.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT-Web Push keys (all three or none). Generate with npx web-push generate-vapid-keys --json; subject must be a mailto:. Without them, push stays off and the app runs fine.

Restart after changes: sudo systemctl restart deltos.

Credentials

  • Production: first boot creates the admin from AUTH_USER / AUTH_PASS (if AUTH_PASS is missing, no admin is created and a warning is logged).
  • Demo: "Sign in as demo" button on the login screen (no password). Separate demo database (app_demo.db), seeded with 3 users, 4 projects, 6 labels and 15 tasks. Can be disabled in Settings (admin only).

Development

Stack: Node 24 + Hono + better-sqlite3 (backend) · React 19 + Vite + Tailwind (frontend).

# Backend (port 3000 by default; see server/.env.example)cd server
npm ci
cp .env.example .env # adjust AUTH_USER / AUTH_PASS
npm run dev
# Frontend (another terminal, proxied to the backend in dev)cd app
npm ci
npm run dev
# Production frontend build (served by the backend itself)
npm run build

With npm run build done, the backend alone is enough: it serves the SPA from app/dist with SPA fallback.

Tests

cd server && npm test# vitest: 76 API/auth/push/label tests

License

AGPL-3.0

About

PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gnacho/deltos: PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19. · GitHub
Skip to content

Repository files navigation

Deltos

English | Español

WebsiteReleaseCILicenseSupport on Ko-fi

Deltos kanban board with three columns (New, In progress, Done), project and label filters, and task cards with priority and due dates

Deltos is a task-management PWA for everyday life: a shared kanban board with live sync, comments, attachments and push notifications, served by a single small Node + SQLite service. It works for a couple, a family, a group of friends planning a trip, or a small team, without the complexity of the big tools and without your data on somebody else's cloud.

The name

Deltos comes from the ancient Greek δέλτος (déltos): a writing tablet, and by extension any written record or letter. Before paper, that was how you kept notes on what mattered. The name fit an app whose whole point is writing tasks down and keeping them where the people who share them can see them.

Why does this exist?

Deltos started as the board for a friends' trip: six people, a spreadsheet nobody updated, and a chat where every decision got buried. Then we kept using it at home for the day-to-day stuff, and again through a renovation and the move that came with it. Everything we had tried before wanted an account and a subscription, kept our lists on someone else's server, or brought more process than a family needs. So I built the small thing: one service, one file of database, a board that syncs live. It does less than Trello or Jira, and for us that was the point.

Why this stack?

  • Node 22 + Hono + better-sqlite3: the app is mostly I/O: SSE live sync, uploads, a handful of concurrent users. Node's event loop fits that shape and Hono adds routing without framework tax.
  • SQLite, no external database: one file under /var/lib/deltos, WAL mode; a backup is a file copy. Nothing to administer for a few users.
  • systemd behind Nginx Proxy Manager, no Docker: it runs in a small LXC at home; fewer layers, logs in journald, an upgrade is a symlink swap (Docker is still available as an alternative, see Installation).
  • React 19 + Vite + Tailwind: the UI shell (sidebar, themes, i18n, settings) is shared with my other apps, so a fix lands everywhere at once.

Features

  • Shared kanban: New / In progress / Done columns with drag & drop, live between sessions over SSE (no refresh, no polling).
  • Push notifications: Web Push (VAPID) when someone creates, moves, comments on or assigns you a card, even with the app closed. Dormant on plain HTTP; turns itself on once the app is served over HTTPS.
  • Cards with everything: comments, attachments with an in-app image viewer, labels, priority, due dates and a per-card activity feed.
  • Multiuser: admin/user roles, per-user language (ES/EN), bcrypt passwords, rate-limited login, audit trail.
  • Installable PWA: light/dark theme following the system, offline service worker, "check for updates" against GitHub releases from Settings.
  • One-click demo mode: separate seeded database, no password; can be disabled in Settings.
  • SQLite storage: WAL mode, single file under /var/lib/deltos.

Screenshots

Card detail: tabs for details, attachments, comments and activity**

Task modal showing title, project, assignee, priority, due date, labels, description and move-to column actions

Settings: appearance with accent color, profile, labels, language**

Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector

Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.

curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh # (recommended)

The installer is a readable, dependency-free POSIX shell script. Inspect it before running: that's the point of keeping it plain. It detects your distro/arch, downloads the latest release and verifies its SHA-256 checksum, installs a versioned Node runtime and the app under /opt/deltos, creates a sandboxed deltos systemd service and prints the initial admin password once.

Running the same command again later upgrades to the latest release. To uninstall: curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh -s -- --uninstall.

Docker
docker build -t deltos .
docker run -d --name deltos -p 3000:3000 \
-e AUTH_USER=admin -e AUTH_PASS='use-a-strong-password' \
-v deltos-data:/app/data \
deltos

Multi-stage node:24-slim image: npm ci --omit=dev for the server + server/ + app/dist/. Mount a volume at /app/data (SQLite + uploads). The .env file is not copied into the image: everything comes from defaults + container environment.

Manual installation (from a release tarball)

Download the artifact for your architecture from Releases and verify it against checksums.txt (sha256sum -c checksums.txt --ignore-missing). Releases are published per v* tag with node_modules pre-built per arch (.github/workflows/release.yml); no compiler needed on the server.

Configuration

The service reads its environment (installer: /etc/deltos/env):

VariableDefaultDescription
PORT3000Listen port (behind Nginx Proxy Manager).
DATA_DIR/var/lib/deltosSQLite files + uploads.
STATIC_DIRapp/distBuilt frontend to serve.
AUTH_USER/AUTH_PASS-Bootstrap admin on first boot (idempotent).
COOKIE_SECUREfalsetrue only behind HTTPS.
SESSION_SECRETauto-generatedHMAC secret; persisted in the DB if unset.
MAX_SSE_CLIENTS20Concurrent live-sync clients.
MAX_UPLOAD_MB10Attachment size limit.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT-Web Push keys (all three or none). Generate with npx web-push generate-vapid-keys --json; subject must be a mailto:. Without them, push stays off and the app runs fine.

Restart after changes: sudo systemctl restart deltos.

Credentials

  • Production: first boot creates the admin from AUTH_USER / AUTH_PASS (if AUTH_PASS is missing, no admin is created and a warning is logged).
  • Demo: "Sign in as demo" button on the login screen (no password). Separate demo database (app_demo.db), seeded with 3 users, 4 projects, 6 labels and 15 tasks. Can be disabled in Settings (admin only).

Development

Stack: Node 24 + Hono + better-sqlite3 (backend) · React 19 + Vite + Tailwind (frontend).

# Backend (port 3000 by default; see server/.env.example)cd server
npm ci
cp .env.example .env # adjust AUTH_USER / AUTH_PASS
npm run dev
# Frontend (another terminal, proxied to the backend in dev)cd app
npm ci
npm run dev
# Production frontend build (served by the backend itself)
npm run build

With npm run build done, the backend alone is enough: it serves the SPA from app/dist with SPA fallback.

Tests

cd server && npm test# vitest: 76 API/auth/push/label tests

License

AGPL-3.0

About

PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - gnacho/deltos: PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19. · GitHub
Skip to content

Repository files navigation

Deltos

English | Español

WebsiteReleaseCILicenseSupport on Ko-fi

Deltos kanban board with three columns (New, In progress, Done), project and label filters, and task cards with priority and due dates

Deltos is a task-management PWA for everyday life: a shared kanban board with live sync, comments, attachments and push notifications, served by a single small Node + SQLite service. It works for a couple, a family, a group of friends planning a trip, or a small team, without the complexity of the big tools and without your data on somebody else's cloud.

The name

Deltos comes from the ancient Greek δέλτος (déltos): a writing tablet, and by extension any written record or letter. Before paper, that was how you kept notes on what mattered. The name fit an app whose whole point is writing tasks down and keeping them where the people who share them can see them.

Why does this exist?

Deltos started as the board for a friends' trip: six people, a spreadsheet nobody updated, and a chat where every decision got buried. Then we kept using it at home for the day-to-day stuff, and again through a renovation and the move that came with it. Everything we had tried before wanted an account and a subscription, kept our lists on someone else's server, or brought more process than a family needs. So I built the small thing: one service, one file of database, a board that syncs live. It does less than Trello or Jira, and for us that was the point.

Why this stack?

  • Node 22 + Hono + better-sqlite3: the app is mostly I/O: SSE live sync, uploads, a handful of concurrent users. Node's event loop fits that shape and Hono adds routing without framework tax.
  • SQLite, no external database: one file under /var/lib/deltos, WAL mode; a backup is a file copy. Nothing to administer for a few users.
  • systemd behind Nginx Proxy Manager, no Docker: it runs in a small LXC at home; fewer layers, logs in journald, an upgrade is a symlink swap (Docker is still available as an alternative, see Installation).
  • React 19 + Vite + Tailwind: the UI shell (sidebar, themes, i18n, settings) is shared with my other apps, so a fix lands everywhere at once.

Features

  • Shared kanban: New / In progress / Done columns with drag & drop, live between sessions over SSE (no refresh, no polling).
  • Push notifications: Web Push (VAPID) when someone creates, moves, comments on or assigns you a card, even with the app closed. Dormant on plain HTTP; turns itself on once the app is served over HTTPS.
  • Cards with everything: comments, attachments with an in-app image viewer, labels, priority, due dates and a per-card activity feed.
  • Multiuser: admin/user roles, per-user language (ES/EN), bcrypt passwords, rate-limited login, audit trail.
  • Installable PWA: light/dark theme following the system, offline service worker, "check for updates" against GitHub releases from Settings.
  • One-click demo mode: separate seeded database, no password; can be disabled in Settings.
  • SQLite storage: WAL mode, single file under /var/lib/deltos.

Screenshots

Card detail: tabs for details, attachments, comments and activity**

Task modal showing title, project, assignee, priority, due date, labels, description and move-to column actions

Settings: appearance with accent color, profile, labels, language**

Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector

Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.

curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh # (recommended)

The installer is a readable, dependency-free POSIX shell script. Inspect it before running: that's the point of keeping it plain. It detects your distro/arch, downloads the latest release and verifies its SHA-256 checksum, installs a versioned Node runtime and the app under /opt/deltos, creates a sandboxed deltos systemd service and prints the initial admin password once.

Running the same command again later upgrades to the latest release. To uninstall: curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh -s -- --uninstall.

Docker
docker build -t deltos .
docker run -d --name deltos -p 3000:3000 \
-e AUTH_USER=admin -e AUTH_PASS='use-a-strong-password' \
-v deltos-data:/app/data \
deltos

Multi-stage node:24-slim image: npm ci --omit=dev for the server + server/ + app/dist/. Mount a volume at /app/data (SQLite + uploads). The .env file is not copied into the image: everything comes from defaults + container environment.

Manual installation (from a release tarball)

Download the artifact for your architecture from Releases and verify it against checksums.txt (sha256sum -c checksums.txt --ignore-missing). Releases are published per v* tag with node_modules pre-built per arch (.github/workflows/release.yml); no compiler needed on the server.

Configuration

The service reads its environment (installer: /etc/deltos/env):

VariableDefaultDescription
PORT3000Listen port (behind Nginx Proxy Manager).
DATA_DIR/var/lib/deltosSQLite files + uploads.
STATIC_DIRapp/distBuilt frontend to serve.
AUTH_USER/AUTH_PASS-Bootstrap admin on first boot (idempotent).
COOKIE_SECUREfalsetrue only behind HTTPS.
SESSION_SECRETauto-generatedHMAC secret; persisted in the DB if unset.
MAX_SSE_CLIENTS20Concurrent live-sync clients.
MAX_UPLOAD_MB10Attachment size limit.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT-Web Push keys (all three or none). Generate with npx web-push generate-vapid-keys --json; subject must be a mailto:. Without them, push stays off and the app runs fine.

Restart after changes: sudo systemctl restart deltos.

Credentials

  • Production: first boot creates the admin from AUTH_USER / AUTH_PASS (if AUTH_PASS is missing, no admin is created and a warning is logged).
  • Demo: "Sign in as demo" button on the login screen (no password). Separate demo database (app_demo.db), seeded with 3 users, 4 projects, 6 labels and 15 tasks. Can be disabled in Settings (admin only).

Development

Stack: Node 24 + Hono + better-sqlite3 (backend) · React 19 + Vite + Tailwind (frontend).

# Backend (port 3000 by default; see server/.env.example)cd server
npm ci
cp .env.example .env # adjust AUTH_USER / AUTH_PASS
npm run dev
# Frontend (another terminal, proxied to the backend in dev)cd app
npm ci
npm run dev
# Production frontend build (served by the backend itself)
npm run build

With npm run build done, the backend alone is enough: it serves the SPA from app/dist with SPA fallback.

Tests

cd server && npm test# vitest: 76 API/auth/push/label tests

License

AGPL-3.0

About

PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gnacho/deltos: PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19. · GitHub
Skip to content

Repository files navigation

Deltos

English | Español

WebsiteReleaseCILicenseSupport on Ko-fi

Deltos kanban board with three columns (New, In progress, Done), project and label filters, and task cards with priority and due dates

Deltos is a task-management PWA for everyday life: a shared kanban board with live sync, comments, attachments and push notifications, served by a single small Node + SQLite service. It works for a couple, a family, a group of friends planning a trip, or a small team, without the complexity of the big tools and without your data on somebody else's cloud.

The name

Deltos comes from the ancient Greek δέλτος (déltos): a writing tablet, and by extension any written record or letter. Before paper, that was how you kept notes on what mattered. The name fit an app whose whole point is writing tasks down and keeping them where the people who share them can see them.

Why does this exist?

Deltos started as the board for a friends' trip: six people, a spreadsheet nobody updated, and a chat where every decision got buried. Then we kept using it at home for the day-to-day stuff, and again through a renovation and the move that came with it. Everything we had tried before wanted an account and a subscription, kept our lists on someone else's server, or brought more process than a family needs. So I built the small thing: one service, one file of database, a board that syncs live. It does less than Trello or Jira, and for us that was the point.

Why this stack?

  • Node 22 + Hono + better-sqlite3: the app is mostly I/O: SSE live sync, uploads, a handful of concurrent users. Node's event loop fits that shape and Hono adds routing without framework tax.
  • SQLite, no external database: one file under /var/lib/deltos, WAL mode; a backup is a file copy. Nothing to administer for a few users.
  • systemd behind Nginx Proxy Manager, no Docker: it runs in a small LXC at home; fewer layers, logs in journald, an upgrade is a symlink swap (Docker is still available as an alternative, see Installation).
  • React 19 + Vite + Tailwind: the UI shell (sidebar, themes, i18n, settings) is shared with my other apps, so a fix lands everywhere at once.

Features

  • Shared kanban: New / In progress / Done columns with drag & drop, live between sessions over SSE (no refresh, no polling).
  • Push notifications: Web Push (VAPID) when someone creates, moves, comments on or assigns you a card, even with the app closed. Dormant on plain HTTP; turns itself on once the app is served over HTTPS.
  • Cards with everything: comments, attachments with an in-app image viewer, labels, priority, due dates and a per-card activity feed.
  • Multiuser: admin/user roles, per-user language (ES/EN), bcrypt passwords, rate-limited login, audit trail.
  • Installable PWA: light/dark theme following the system, offline service worker, "check for updates" against GitHub releases from Settings.
  • One-click demo mode: separate seeded database, no password; can be disabled in Settings.
  • SQLite storage: WAL mode, single file under /var/lib/deltos.

Screenshots

Card detail: tabs for details, attachments, comments and activity**

Task modal showing title, project, assignee, priority, due date, labels, description and move-to column actions

Settings: appearance with accent color, profile, labels, language**

Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector

Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.

curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh # (recommended)

The installer is a readable, dependency-free POSIX shell script. Inspect it before running: that's the point of keeping it plain. It detects your distro/arch, downloads the latest release and verifies its SHA-256 checksum, installs a versioned Node runtime and the app under /opt/deltos, creates a sandboxed deltos systemd service and prints the initial admin password once.

Running the same command again later upgrades to the latest release. To uninstall: curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh -s -- --uninstall.

Docker
docker build -t deltos .
docker run -d --name deltos -p 3000:3000 \
-e AUTH_USER=admin -e AUTH_PASS='use-a-strong-password' \
-v deltos-data:/app/data \
deltos

Multi-stage node:24-slim image: npm ci --omit=dev for the server + server/ + app/dist/. Mount a volume at /app/data (SQLite + uploads). The .env file is not copied into the image: everything comes from defaults + container environment.

Manual installation (from a release tarball)

Download the artifact for your architecture from Releases and verify it against checksums.txt (sha256sum -c checksums.txt --ignore-missing). Releases are published per v* tag with node_modules pre-built per arch (.github/workflows/release.yml); no compiler needed on the server.

Configuration

The service reads its environment (installer: /etc/deltos/env):

VariableDefaultDescription
PORT3000Listen port (behind Nginx Proxy Manager).
DATA_DIR/var/lib/deltosSQLite files + uploads.
STATIC_DIRapp/distBuilt frontend to serve.
AUTH_USER/AUTH_PASS-Bootstrap admin on first boot (idempotent).
COOKIE_SECUREfalsetrue only behind HTTPS.
SESSION_SECRETauto-generatedHMAC secret; persisted in the DB if unset.
MAX_SSE_CLIENTS20Concurrent live-sync clients.
MAX_UPLOAD_MB10Attachment size limit.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT-Web Push keys (all three or none). Generate with npx web-push generate-vapid-keys --json; subject must be a mailto:. Without them, push stays off and the app runs fine.

Restart after changes: sudo systemctl restart deltos.

Credentials

  • Production: first boot creates the admin from AUTH_USER / AUTH_PASS (if AUTH_PASS is missing, no admin is created and a warning is logged).
  • Demo: "Sign in as demo" button on the login screen (no password). Separate demo database (app_demo.db), seeded with 3 users, 4 projects, 6 labels and 15 tasks. Can be disabled in Settings (admin only).

Development

Stack: Node 24 + Hono + better-sqlite3 (backend) · React 19 + Vite + Tailwind (frontend).

# Backend (port 3000 by default; see server/.env.example)cd server
npm ci
cp .env.example .env # adjust AUTH_USER / AUTH_PASS
npm run dev
# Frontend (another terminal, proxied to the backend in dev)cd app
npm ci
npm run dev
# Production frontend build (served by the backend itself)
npm run build

With npm run build done, the backend alone is enough: it serves the SPA from app/dist with SPA fallback.

Tests

cd server && npm test# vitest: 76 API/auth/push/label tests

License

AGPL-3.0

About

PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - gnacho/deltos: PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19. · GitHub
Skip to content

Repository files navigation

Deltos

English | Español

WebsiteReleaseCILicenseSupport on Ko-fi

Deltos kanban board with three columns (New, In progress, Done), project and label filters, and task cards with priority and due dates

Deltos is a task-management PWA for everyday life: a shared kanban board with live sync, comments, attachments and push notifications, served by a single small Node + SQLite service. It works for a couple, a family, a group of friends planning a trip, or a small team, without the complexity of the big tools and without your data on somebody else's cloud.

The name

Deltos comes from the ancient Greek δέλτος (déltos): a writing tablet, and by extension any written record or letter. Before paper, that was how you kept notes on what mattered. The name fit an app whose whole point is writing tasks down and keeping them where the people who share them can see them.

Why does this exist?

Deltos started as the board for a friends' trip: six people, a spreadsheet nobody updated, and a chat where every decision got buried. Then we kept using it at home for the day-to-day stuff, and again through a renovation and the move that came with it. Everything we had tried before wanted an account and a subscription, kept our lists on someone else's server, or brought more process than a family needs. So I built the small thing: one service, one file of database, a board that syncs live. It does less than Trello or Jira, and for us that was the point.

Why this stack?

  • Node 22 + Hono + better-sqlite3: the app is mostly I/O: SSE live sync, uploads, a handful of concurrent users. Node's event loop fits that shape and Hono adds routing without framework tax.
  • SQLite, no external database: one file under /var/lib/deltos, WAL mode; a backup is a file copy. Nothing to administer for a few users.
  • systemd behind Nginx Proxy Manager, no Docker: it runs in a small LXC at home; fewer layers, logs in journald, an upgrade is a symlink swap (Docker is still available as an alternative, see Installation).
  • React 19 + Vite + Tailwind: the UI shell (sidebar, themes, i18n, settings) is shared with my other apps, so a fix lands everywhere at once.

Features

  • Shared kanban: New / In progress / Done columns with drag & drop, live between sessions over SSE (no refresh, no polling).
  • Push notifications: Web Push (VAPID) when someone creates, moves, comments on or assigns you a card, even with the app closed. Dormant on plain HTTP; turns itself on once the app is served over HTTPS.
  • Cards with everything: comments, attachments with an in-app image viewer, labels, priority, due dates and a per-card activity feed.
  • Multiuser: admin/user roles, per-user language (ES/EN), bcrypt passwords, rate-limited login, audit trail.
  • Installable PWA: light/dark theme following the system, offline service worker, "check for updates" against GitHub releases from Settings.
  • One-click demo mode: separate seeded database, no password; can be disabled in Settings.
  • SQLite storage: WAL mode, single file under /var/lib/deltos.

Screenshots

Card detail: tabs for details, attachments, comments and activity**

Task modal showing title, project, assignee, priority, due date, labels, description and move-to column actions

Settings: appearance with accent color, profile, labels, language**

Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector

Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.

curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh # (recommended)

The installer is a readable, dependency-free POSIX shell script. Inspect it before running: that's the point of keeping it plain. It detects your distro/arch, downloads the latest release and verifies its SHA-256 checksum, installs a versioned Node runtime and the app under /opt/deltos, creates a sandboxed deltos systemd service and prints the initial admin password once.

Running the same command again later upgrades to the latest release. To uninstall: curl -fsSL https://raw.githubusercontent.com/gnacho/deltos/main/install.sh | sudo sh -s -- --uninstall.

Docker
docker build -t deltos .
docker run -d --name deltos -p 3000:3000 \
-e AUTH_USER=admin -e AUTH_PASS='use-a-strong-password' \
-v deltos-data:/app/data \
deltos

Multi-stage node:24-slim image: npm ci --omit=dev for the server + server/ + app/dist/. Mount a volume at /app/data (SQLite + uploads). The .env file is not copied into the image: everything comes from defaults + container environment.

Manual installation (from a release tarball)

Download the artifact for your architecture from Releases and verify it against checksums.txt (sha256sum -c checksums.txt --ignore-missing). Releases are published per v* tag with node_modules pre-built per arch (.github/workflows/release.yml); no compiler needed on the server.

Configuration

The service reads its environment (installer: /etc/deltos/env):

VariableDefaultDescription
PORT3000Listen port (behind Nginx Proxy Manager).
DATA_DIR/var/lib/deltosSQLite files + uploads.
STATIC_DIRapp/distBuilt frontend to serve.
AUTH_USER/AUTH_PASS-Bootstrap admin on first boot (idempotent).
COOKIE_SECUREfalsetrue only behind HTTPS.
SESSION_SECRETauto-generatedHMAC secret; persisted in the DB if unset.
MAX_SSE_CLIENTS20Concurrent live-sync clients.
MAX_UPLOAD_MB10Attachment size limit.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT-Web Push keys (all three or none). Generate with npx web-push generate-vapid-keys --json; subject must be a mailto:. Without them, push stays off and the app runs fine.

Restart after changes: sudo systemctl restart deltos.

Credentials

  • Production: first boot creates the admin from AUTH_USER / AUTH_PASS (if AUTH_PASS is missing, no admin is created and a warning is logged).
  • Demo: "Sign in as demo" button on the login screen (no password). Separate demo database (app_demo.db), seeded with 3 users, 4 projects, 6 labels and 15 tasks. Can be disabled in Settings (admin only).

Development

Stack: Node 24 + Hono + better-sqlite3 (backend) · React 19 + Vite + Tailwind (frontend).

# Backend (port 3000 by default; see server/.env.example)cd server
npm ci
cp .env.example .env # adjust AUTH_USER / AUTH_PASS
npm run dev
# Frontend (another terminal, proxied to the backend in dev)cd app
npm ci
npm run dev
# Production frontend build (served by the backend itself)
npm run build

With npm run build done, the backend alone is enough: it serves the SPA from app/dist with SPA fallback.

Tests

cd server && npm test# vitest: 76 API/auth/push/label tests

License

AGPL-3.0

About

PWA kanban de tareas en pareja: SSE en vivo, comentarios, adjuntos con visor de imágenes, i18n es/en. Node 22 + Hono + SQLite + React 19.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages