I'm working on this GTD-oriented task manager with support for nested tasks and a focus on helping the user make tasks actionable and surfacing next tasks. It's inspired by MyLifeOrganized, OmniFocus, Amazing Marvin and Everdo.
This project is a work-in-progress. Expect bugs, and make sure to manually back
up your work with the buttons on the top bar. The Electron application saves
data in ~/.config/nextool/tasks.json
, and the web client uses local storage.
Nextool is licensed under the terms of the GNU AGPLv3 or any later version as
described in the file LICENSE.md
.
Try it in your browser here. Data is saved locally in your browser. Use the buttons in the top bar to back up your data.
Download the latest release here.
On Windows and macOS, you may need to do something special to convince them to
run the program, since we don't sign the file. On Linux, just run chmod +x <filename>.AppImage
to make it executable.
Nextool has two clients, an Electron-based desktop application, and a website which contains a web-based version of the application. These clients share most of their code, but they plug in different platform-specefic functions, and they each have their own build process.
The shared code is its own NPM package, which resides in the app/
directory.
The Electron client is in the electron/
directory. The code for the website is
in website/
.
Unfortunately, working on a project that consists of multiple NPM packages can
be a bit painful. In theory, NPM will let you add a local dependency with npm install ../app
(for example). However, the problem with this is that it just
adds a symbolic link.
When the bundler for the Electron client (for example) tries to look up
dependencies, it will find the node_modules
folder of the package for the
shared code. However, when we build the shared code package in production, it
builds a clean package that consists of just package.json
and the output
that's built into dist/
(see the package.json
). This gives different results
in development and production.
Instead, we use a somewhat hacky approach where we have configured the Electron
package to build a clean release (using npm pack
) of the shared code package,
and then install that at runtime. The disadvantage of this approach is that we
have to rebuild the entire thing each time we make a change.
This is the main way of doing development on Nextool. To watch for changes and
continually generate an example of the app (according to dev.tsx
) in
dist/index.html
, run:
$ cd app
$ npx webpack -wc dev.config.js
Then, run a server in the dist/
directory:
$ cd app/dist
$ python -m http.server 3000
To get around the fact that we need to rebuild the entire app
package each
time we make a change, we can add yet another hack on top of this build process,
where we manually symlink node_modules/nextool/dist
to the true dist/
directory inside the shared code package, but without symlinking anything else.
Thus, to work on the Electron client in development, while seeing updates made
in the shared code package, we first build the dependencies (which automatically
runs npm pack
on the shared code package), and then we symlink dist/
inside
the package:
$ cd electron
$ npm ci
$ ln -sf $PWD/../app/dist node_modules/nextool/dist
Then, we run webpack -w
in the shared code package to continually rebuild
changes:
$ cd app
$ npx webpack -w
And then we also watch for changes in the Electron client package:
$ cd electron
$ npx webpack -w
Finally, we can open the Electron application:
$ cd electron
$ npx electron dist/main.js
To refresh, press F5, and to show the developer tools, press F12.
The website is automatically deployed to https://nextool.app/ from Vercel whenever this repository is updated.
To serve the website locally, run:
$ cd website
$ npm run dev
Apparently, Next.js doesn't like the approach described above for linking the
shared code package, so you just have to recompile the app
package whenever
you change it:
$ cd website
$ npm ci
$ rm -r .next
$ npm run dev
Run test suite:
$ cd app
$ npx jest --verbose
Watch unit tests:
$ cd app
$ npx jest --watch-all --verbose
Run unit tests with coverage:
$ cd app
$ npx jest --verbose --coverage=true --collectCoverageFrom=*.ts
$ open ./coverage/lcov-report/index.html
The screenshot above can be generated automatically. First, start the
application on localhost:3000
as described in Working on the shared code
above. Then run:
$ gem install bundler
$ bundle install
$ ruby screenshot.rb
To build a production release of the Electron application, run:
$ cd electron
$ npm ci
$ npm run build-linux # or build-macos, build-windows
$ cp dist/Nextool-*.AppImage ~/bin/nextool # or dist/Nextool-*.dmg, dist/Nextool-*.exe
To format code, install Prettier and run prettier -w .
. It's recommended that
you add the following script to .git/hooks/pre-commit
:
#!/bin/bash
prettier -c .
app/package.json
and electron/package.json
git tag vX.X.X
and git push --tags