This app is a tool for creating conditional pack lists. I use it for creating a pack list for my travels, depending on the duration, the activities, the expected weather, etc. It should be flexible enough to be used for other purposes as well.
Custom rules can be defined either with free text in a specific grammar or a graphical editor.
Use this link to access the app deployed on GitHub Pages. As it is a PWA, you can also install it on your home screen for easy access.
There is also an Android App available in the Play Store:
Data is stored in your browser's local storage and not shared with any server. The app has an export and import feature to backup and restore your data wherever you like. Read more on this in the privacy policy.
The app supports starting and saving sessions. Whenever you go back to a session, it will restore the state of the pack list and the associated rules. This functionality can be useful, when you pack for a multi-week trip in one session, do daily activities while you are there, and then want to do reverse packing for the return trip.
To get started with sessions, start a new session by clicking the "New Session" button on the config page. You can then select a slot for this session and give it a name. The session will track the current pack list and all of the actions you take in the app. To disconnect from this session, you can reset the packlist by clicking the "Reset Packlist" button on the config page. To reinstate a session, you can load it from the config page.
Here is a simplified diagram of the session states:
---
config:
flowchart:
curve: basis
---
flowchart LR
No_Session[No Session]
Starting_Session@{ shape: diamond, label: "Starting Session" }
Session[Session]
No_Session --> |New Session| Starting_Session
Starting_Session --> |Select Slot<br>Give Name| Session
Starting_Session --> |Abort| No_Session
No_Session --> |Restore Session| Session
Session --> |Disconnect Session| No_Session
This app is developed using Angular 20 with the new zoneless change detection strategy. Wherever possible, I used signals to model data flow.
The project uses Nx for managing the monorepo and the build process.
Managing the rules grammar and parsing it is done using Peggy.
Showdown is used in a build step for converting the syntax documentation for the rule format from markdown to HTML.
For packaging the app into an Android bundle, I use Capacitor.
For styling, I use TailwindCSS. The design system is implemented using Storybook. It is deployed here.
The app is available in multiple languages (English and German at the moment). The language can be selected in the settings.
The Angular build process is set up to build all languages and deploy them to the same location. The language switching is done by navigating to a different index.html. The build process merges the different localized Angular apps into the same folder.
- Google Material Icons
- Flags for the language selection from uxwing.com
Checkout the repository and install pnpm (npm i -g pnpm).
Then run pnpm install and pnpm dev to start the development server.
The app will be available at http://localhost:4200.
To build the app with multiple languages and service worker, run pnpm build.
You can also use pnpm start instead to build and start a local server.
The app will be available at http://localhost:8080.
The design system can be previewed with pnpm design and is available at http://localhost:4444.
Provided you have Docker installed, I recommend using VSCode with the included devcontainer for development. Simply open the workspace in VSCode and (you probably will be prompted to) re-open the workspace in the devcontainer. This will set up a development environment with all necessary tools and extensions installed.
The current format supports only a flat condition structure with
NOT,AND, andOR, which are evaluated in this precedence order. To make more elaborate conditions, you should be able to use brackets to structure the logic, right?
Yes, brackets would be a nice feature to have, but it will also complicate the design of the UI, which is already quite complex for users not familiar with boolean logic.
For users with complex logic, be aware that you can use the transitive disabling of rules to structure your logic. Questions always have a variable associated with them. Since questions are only displayed if a condition is met, the variable is transitively also only true if the condition is true. This means that most of the combinations in a complex condition are not possible due to the restriction of the variables themselves.
Imagine the following rule snippet:
:- Will it be cold? $cold;
cold :- Bring gloves? $gloves, Bring warm drink in thermos? $thermos;
With this structure, it is implicitly defined that gloves and thermos can only yield true values if cold is also true.
In other words, if cold is false, gloves and thermos are also false because the user will not see the questions associated with those variables.
This is a simple way to structure your complex logic without the need for brackets.
If that doesn't work for you, I recommend converting the condition to disjunctive normal form (DNF) to make it flat. This in turn makes the expression bigger and harder to read, but still implementable with the current restrictions.
The categories on the pack list are either displayed in alphabetical order or in the order they were defined by the rules. If weight tracking is enabled, you can also sort the categories by weight. Would it be possible to define a custom order?
Yes, it would totally be possible to add a user interface for defining a custom order, but this functionality will also add more complexity and error cases. What is the behavior if a category is missing in the custom order? What if a category is no longer used? What if a user swaps two pack lists all the time and wants to have a different order of categories for each? All those considerations leave me at the decision to not implement this feature.
If you want to define a custom order for your categories, you can use a prefix in the category name that is then sorted alphabetically.
For example, you can use 1Shelter, 2Clothing, 3Hygiene, etc.
This way, you can define the order of the categories by the prefix and you don't have to reorder the rules all the time.
The rule editor is quite complex and it is easy to make mistakes. Would it be possible to add an Undo/Redo feature?
The application provides an export and import feature that can be used as a backup mechanism. This way, you can always revert to a previous state of your rules. Adding an Undo/Redo feature would add a lot of complexity to the application and would also require a lot of testing to ensure that it works correctly in all cases. I decided to not implement this feature to keep the application simple and easy to maintain. Please backup your rules regularly to be able to revert to a previous state if needed.
