A study app you run on your own device.
Animated docs Β· Install Β· Sync safety Β· Admin proof Β· Screenshots
It includes:
- Focus timer
- Tasks and subjects
- Study sessions and stats
- Habits, exams, tests, and mock tests
- Optional Supabase login, backup, restore, and community features
Start here:
- Animated web guide: https://suydev.github.io/isotope-code/
- Install guide: https://suydev.github.io/isotope-code/install.html
- Screenshot gallery: https://suydev.github.io/isotope-code/gallery.html
- Admin guide: ADMIN.md
- Sync details: docs/sync-system.md
- Backup storage details: docs/storage-backup-system.md
Install Termux from F-Droid or GitHub, not the old Play Store app.
bash <(curl -fsSL https://raw.githubusercontent.com/Suydev/isotope-code/main/install-termux.sh)After install:
isotope startOpen:
http://127.0.0.1:3000
git clone https://github.com/Suydev/isotope-code.git
cd isotope-code
bash setup.sh
isotope startInstall Git and Node.js first if you do not have them.
git clone https://github.com/Suydev/isotope-code.git
cd isotope-code
bash setup.sh
isotope startUse PowerShell:
git clone https://github.com/Suydev/isotope-code.git
cd isotope-code
.\install.ps1Or use Command Prompt:
git clone https://github.com/Suydev/isotope-code.git
cd isotope-code
setup.batThen open:
http://127.0.0.1:3000
Setup checks for:
- Node.js 18 or newer
- npm
- Git
.env- required scripts
It then installs the isotope command.
isotope start # start the app
isotope stop # stop the app
isotope restart # restart the app
isotope open # open in browser
isotope update # update from GitHub
isotope status # show status
isotope doctor # find problems
isotope logs # show logs
isotope repair # repair install
isotope reinstall-widgets # Android Termux widget shortcutsThe app works best with your own Supabase project.
You need Supabase for:
- login
- sync
- cloud backup
- restore on a new device
- avatars
- groups and community features
Steps:
- Create a free project at https://supabase.com
- Open SQL Editor.
- Paste and run isotope-complete.sql.
- Create these Storage buckets if they do not already exist:
avatarsuser-contentnotes
- Copy your Project URL and anon key.
- Put them in
.env.
Example:
SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_ANON_KEY=your-anon-public-key
PORT=3000
ENABLE_ADMIN_MODE=falseDo not put a service-role key in the browser.
Do not commit .env.
.envis the preferred runtime env file.- If
.envis missing andyeh.envexists, setup copiesyeh.envto.env. - If
ISOTOPE_ENV_FILEis set, setup reads that file, copies it to.env, and uses the copied values. - Existing
SUPABASE_URL,SUPABASE_ANON_KEY, andENABLE_ADMIN_MODEvalues are preserved. - If
ENABLE_ADMIN_MODEis missing, setup writesENABLE_ADMIN_MODE=false.
The app now uses one backup system.
Main backup:
{userId}/backups/latest.json
Backup history:
{userId}/backups/history/{timestamp}-{hash}.json
Cloud mirror:
{userId}/cloud-snapshot/latest.json
Old folders are still read for safety:
{userId}/imports/latest.json
{userId}/exports/latest.json
{userId}/cloud-snapshot/latest.json
Important rule:
If this device is empty and cloud has a richer backup, upload is blocked. The app must restore cloud data first.
Blocked code:
BLOCKED_EMPTY_OVERWRITE
Admin mode is optional.
Use it only on your own machine.
ENABLE_ADMIN_MODE=true
ADMIN_SECRET=<long-random-secret>
ADMIN_EMAIL=<your-email@example.com>Add SUPABASE_SERVICE_ROLE_KEY only in your private .env when you need admin repair tools.
Open:
http://127.0.0.1:3000/__admin
Useful admin pages:
/__admin/verify/__admin/sync/__admin/storage/__admin/roles/__admin/patch
Dry-run first:
node scripts/repair-user-backup.mjs --user <user-id> --dry-runApply only after the dry-run looks safe:
node scripts/repair-user-backup.mjs --user <user-id> --applyCheck backups:
node scripts/validate-backup-files.mjs --user <user-id>Preview cleanup:
node scripts/validate-storage-cleanup.mjs --user <user-id> --dry-run| Problem | Try this |
|---|---|
| App does not open | isotope start then open http://127.0.0.1:3000 |
| Port is busy | isotope stop or set PORT=3001 in .env |
| Login fails | Check SUPABASE_URL and SUPABASE_ANON_KEY |
| Sync is blocked | Restore the cloud backup first |
| Storage permission error | Re-run isotope-complete.sql |
| Android widget is missing | isotope reinstall-widgets |
| Update failed | isotope doctor, then isotope repair |
Do not test browser globals in the Node REPL. Node has no window, so typeof window.__isoLogin is not a valid Node check.
Use the browser console on http://127.0.0.1:3000/auth:
typeof window.__isoLogin
typeof window.__isoUpBoth should return "function".
Use the Node smoke test when a browser is not available:
npm run test:auth-bridgeTo prove the configured Supabase project can perform the Storage-backed sync path end to end:
npm run test:supabase-syncIf a stale PWA or browser cache is serving old runtime files, clear runtime caches from the browser console:
caches.keys().then(keys => Promise.all(keys.map(k => caches.delete(k)))).then(() => location.reload())If the top-right cloud sync button says Authentication required, the browser is not holding a valid Supabase session even if the app shell still looks logged in. Sign out, sign in again through /auth, then run:
typeof window.__isoGetValidJwtBefore changing sync, backup, auth, or SQL:
node --check server.mjs
node --check server/backup-manager.mjs
node --check public/sync/backup-normalizer.js
node --check public/sync/local-data-adapter.js
node scripts/validate-backup-files.mjs --user <user-id>
node scripts/repair-user-backup.mjs --user <user-id> --dry-run
npm run assets:compareRules:
- Do not commit
.env. - Do not expose service-role keys to the frontend.
- Do not weaken RLS to hide a bug.
- Do not let empty local data overwrite rich cloud data.
- Do not replace compiled assets from the live site unless the asset report proves the same chunk graph is available.
- Keep docs simple and true.
MIT. See LICENSE.