The shape of the thing
DiPAgE is a single-page Angular application that runs entirely in the browser. There is no application server, no database to provision and no account system. The only server involved is the one serving the static bundle, and its job ends there. Everything the app knows lives in IndexedDB on the device that entered it.
Framework choices worth knowing
- Angular 22 with standalone components and signals throughout. Change detection is zoneless and every component is
OnPush. - TypeScript strict mode, including
strictTemplates. Note the gap this leaves:tscdoes not check templates, so a stale binding surfaces only at AOT build time. - Tailwind CSS 4 with DaisyUI 5. Custom CSS exists only where a utility cannot express the rule.
- UUIDv7 for every generated ID, so identifiers sort by creation time.
What zoneless costs you
If you write tests against this codebase, the one trap worth naming up front: under zoneless change detection a debounceTime or delay subscription created at component construction cannot be flushed by tick() inside fakeAsync. The assertion then passes without exercising the debounce at all. Create the subscription inside the test body instead.
What local-first costs you
No sync, no multi-device merge, no server-side backup. Moving data between devices is an explicit export and import, and the conflict resolution that goes with it is a user-facing flow rather than an algorithm running behind the scenes. That is a deliberate trade for working with no connectivity and holding no personal data centrally.