Super Task is a task board that runs directly in the browser from static files, with optional Supabase-backed cloud sync. There is no build step and no package install; it runs standalone locally, or with cloud sync once Supabase is configured.
Live deployment: https://super-task.samfraser-au.workers.dev (Cloudflare Workers static assets, auto-deploys from main; build command npm run www:build, assets directory www per wrangler.jsonc)
- Add, edit, complete, and delete tasks via a floating "+" button that opens a task editor popup (works the same on web and Android)
- Drag and drop rows to reorder tasks in manual mode (table view), or drag task cards to reorder within their group (card view)
- Sort by Group, Due date, or Priority in either view; card view has a dedicated sort menu (manual order keeps drag reordering enabled)
- Manage groups (add, rename, delete) from the Groups panel
- Auto-register groups when you type a new group while creating or editing a task
- Resize table columns, with widths remembered between sessions
- Card view groups cards scroll internally once a group has more tasks than fit, instead of clipping them
- Export and import backups as JSON
- Delete all completed tasks in one action
- Persist data with IndexedDB
- Automatic localStorage fallback when IndexedDB is unavailable
- Offline support with a service worker and installable PWA manifest
- Optional Supabase email magic-link sign-in (including deep-link sign-in on the Android app)
- Optional cloud sync of tasks/groups, scoped per signed-in user
- Offline-safe cloud sync: edits made offline or signed-out are queued locally and pushed automatically once signed in and online
- Realtime sync between open tabs/devices for the same account (no manual refresh needed)
- Timestamp-aware conflict handling so a stale cloud pull can't clobber a more recent local edit
- Compact header: secondary actions (Export/Import backup, Refresh from cloud, Sign out) live under a single "More ⋮" menu
- Card view is used automatically on narrow/mobile screens until you explicitly pick a view (your choice is then remembered)
- Live task/group counts and a group count badge on the Groups toggle for quick at-a-glance status
- Packaged as a native Android app via Capacitor, with magic-link sign-in working through a custom URL scheme deep link
Use either option:
- Double-click
index.html - Double-click
open-super-task.cmd
The app works fully local-only with no Supabase configuration. Cloud sync is opt-in (see below).
- Tap the floating "+" button (bottom-right) to open the task editor popup; fill out Task, Group, Due date, Priority, and Notes, then select Add task.
- Click any row field to edit in place in table view, or click a task card in card view to reopen the same task editor popup pre-filled for editing.
- Toggle completion with the checkbox.
- Use the drag handle to reorder tasks in table view (only when sort is in manual mode), or drag a task within its card in card view.
- Use column headers to sort and cycle back to manual ordering in table view, or the Sort tasks menu in card view.
- Open Groups to manage saved groups (the button shows a live count of your groups).
- Open the "More ⋮" menu for Export backup and Import backup.
- If cloud sync is configured, sign in with a magic link to sync tasks/groups across devices; once signed in, "Refresh from cloud" and "Sign out" are also in the "More ⋮" menu.
See SUPABASE_SETUP.md for full setup steps. In short:
- Copy
auth-config.example.jstoauth-config.jsand add your Supabase project URL + anon key. - Sign in with the magic-link form in the app header.
- While signed in, the cloud copy (Supabase
tasks/groupstables) is treated as the source of truth: every app load / sign-in pulls the latest cloud data, and every local task/group edit is pushed to the cloud immediately. - If offline or signed out, edits are saved locally and queued; a "N changes pending sync" indicator shows in the header, and affected rows get a small amber marker. Queued changes push automatically once you're back online and signed in (also retried on a timer and on browser reconnect), or you can use "Refresh from cloud" (in the "More ⋮" menu) / re-visit the app to trigger a push+pull.
- On Android cold app launches, initial cloud bootstrap now auto-retries briefly if the first request fails (a WebView startup timing edge case), so users usually do not need to close/reopen the app.
- Once signed in, the header shows a single combined "Logged in - your@email.com" pill; "Refresh from cloud" and "Sign out" live in the "More ⋮" menu.
- While signed in, other open tabs/devices on the same account are notified of changes via Supabase Realtime and refresh automatically (requires Realtime enabled on the
tasks/groupstables; see SUPABASE_SETUP.md). - Each task/group tracks an
updatedAttimestamp; cloud pulls merge per-record instead of blanket-overwriting, so a more recently edited local row survives a pull from slightly older cloud data. - Import backup and Export backup remain available at all times (including signed out) for local testing and manual backups. Importing a backup while signed in also pushes the imported data to your cloud account, so it survives future syncs.
Known limitation: conflict resolution is per-record (whole row wins by timestamp), not field-level merging.
- Primary storage: IndexedDB database
super-task-db - Stores:
tasksgroups
- Fallback storage key:
super-task-fallback(localStorage) - Column widths key:
super-task-col-widths(localStorage) - Offline/pending cloud sync queue key:
super-task-sync-queue(localStorage) - Cloud copy (when configured): Supabase Postgres
tasks/groupstables, scoped byuser_id, RLS-protected (see SUPABASE_SETUP.md)
service-worker.jscaches app shell assets for offline usemanifest.jsonenables install-to-home-screen / standalone app behavior on supported browsers
index.html: UI structure and service worker registrationstyles.css: visual styling and layoutcore.js: shared constants and initial state shapedom.js: centralized DOM element lookupsbootstrap.js: preference restore and event listener wiringauth-config.js/auth-config.example.js: Supabase project URL + anon key (not committed with real secrets)auth.js: Supabase client init, magic-link sign-in, session/callback handling, sign-outstorage.js: IndexedDB/localStorage persistence layerrepositories.js: task/group mutation methods; calls local persistence + cloud syncsync-queue.js: persistent offline/pending cloud-sync queue with retryapp.js: app state, rendering, interactions, cloud bootstrap/sync orchestration, backup/restoremanifest.json: PWA metadata and iconsservice-worker.js: offline cache and fetch strategyopen-super-task.cmd: quick launcher for WindowsSUPABASE_SETUP.md: step-by-step Supabase project/schema setupAUTH_IMPLEMENTATION_PLAN.md/IMPLEMENTATION_ROADMAP.md: auth/sync design plan and status
The web app is packaged for Android via Capacitor, with no changes to how the static app itself runs.
package.json/node_modules/: Capacitor CLI + Android platform tooling (npm-only, no bundler/build step for the web code itself)capacitor.config.json: app id (com.neworchard.supertask), app name, andwebDir: "www"scripts/build-www.js: copies just the runtime web files (no docs, no tooling) intowww/, which is the folder Capacitor packages into the Android appandroid/: the generated native Android Studio project (tracked in git per Capacitor convention)
Prerequisites to build/run on Android (not needed for the web app itself):
- Node.js + npm (already used for the Capacitor CLI)
- A JDK (17 or 21; NOT the JDK 25 bundled with newer Android Studio installs — Gradle 8.11/AGP 8.7 here don't support it yet and fail with "Unsupported class file major version 69"). Microsoft Build of OpenJDK 21 (
winget install Microsoft.OpenJDK.21) is known to work. - Android Studio + Android SDK
JAVA_HOMEpointed at the JDK 17/21 install, andANDROID_HOMEpointed at the Android SDK (e.g.%LOCALAPPDATA%\Android\Sdk)
Workflow once those are installed:
npm install
npm run cap:sync # rebuilds www/ from source files and syncs the android/ project
npm run android:open # opens the project in Android Studio
Run npm run cap:sync again any time the web source files change, before opening/building in Android Studio. The app has been built and run successfully on both an emulator and a physical device (Pixel 10 Pro).
Note: browser deploys do not auto-update an installed Android build. After web code changes, run npm run cap:sync, rebuild in Android Studio, and reinstall/update the app.
Tapping a magic-link email on a phone normally opens the phone's browser, not the installed app (they have separate storage). To make sign-in work inside the native app:
- The app registers a custom URL scheme,
supertask://auth-callback, as an Android intent-filter (android/app/src/main/AndroidManifest.xml). auth.jssends that URL as the magic-link redirect when running natively (detected viawindow.Capacitor.isNativePlatform()), and uses the@capacitor/appplugin'sappUrlOpen/getLaunchUrlto catch the deep link and complete sign-in.- You must add
supertask://auth-callbackas a Redirect URL in the Supabase dashboard (Authentication -> URL Configuration) for this to work — see SUPABASE_SETUP.md. - This requires a full Android rebuild (not just
npm run www:build) since it touchesAndroidManifest.xmland native plugins.