By [Rob Bearman](https://twitter.com/robbearman) on March 12, 2018

I built [Memoui](https://memoui.com/), a fast, small-payload scratch
pad application with data persistence and offline
support using [Elix](/content/elix/index.html) web components and mixins.
Thanks to service workers and seamless Android support for adding to the
device's home screen, the application has a native feel and user experience,
with the benefit of installing from a URL rather than an app store.

While working on a longer term PWA project, I wanted to deliver a more limited
sample application so I could more quickly gain insights into the end-to-end
patterns and pitfalls. What I ended up with is
Memoui (/ˈmemwē/ 😉). This was incidentally a useful app for me, as I like having
on my phone a means to write down or dictate something very quickly, without a
care for network backup, accounts, etc. I’m also determined not to download and
congest my device with native apps from the app stores. Memoui would be, and is,
an app I’d actually use, no matter how simple it looks.

Beyond the functionality of the app, I had very specific learning and
implementation objectives:

- I wanted to leverage work I’d already begun on my larger project, making
   use of my existing build and server side patterns.
- The front-end must be written almost exclusively with web components, and
   specifically with Elix elements and mixins.
- The network experience is exclusively for download/install. No network
   connection is required thereafter except for updates.
- Local device persistence of data. No accounts. No network backup. It’s a
   scratch pad, after all.

And, finally, I wanted to explore the subtleties involved in the full
development lifecycle from conception to delivery as a proof of concept
project.

Thinking about the project in these terms, it was striking to me how similar
this was to the early development of native iOS and Android applications where so
many apps were designed to be installed and run independent from network
connectivity. We’re not really talking about PWAs in this world, where you care
about scalability to desktop browsers, or progressive enhancement. The target is
a mobile device, and the subject is an application, pure and simple. It's not
necessarily PWA; it’s more WAP — web app, period.

The result was a functional application delivered to a device through a URL,
with an initial download size of about 90 KB, and the actual client code
contributing about 23 KB, compressed. The application runs fully offline where
service workers are supported, and makes use of:

- [Elix Tabs](/content/elix/Tabs/index.html) element
- [Elix Drawer](/content/elix/Drawer/index.html) element
- [Elix ReactiveElement](/content/elix/ReactiveElement/index.html)
   and its collection of mixins
- An IndexedDB database
- Service workers!
- A [web app manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest)
- Server-side Preact, minimally for routing and page hosting
- Webpack

From a
[functional reactive programming](/content/blog/posts/a-compact-javascript-mixin-for-creating-native-web-components-in-frpreact-style/index.html)
perspective, Memoui follows the React pattern of components for UI interfaces,
starting with componentization at the page level. Rather than incurring
framework costs, Memoui takes advantage of its target device’s support for
native web components. Everything of interest is a web component (modulo work
I’d eventually do, server side, to eliminate even my minimal use of Preact for
routing and master page framework). And all Memoui’s components are built with
Elix.

Elix shines in that, even with its 1.0.0 release, it is a comprehensive library
of valuable semantics, organized as mixins that work both synergistically with
other mixins, or independently. Elix elements are mostly groupings of mixins.
While the Elix code base is growing in size and sophistication, Memoui’s
download size remains anchored only to what it needs from Elix.
As an interesting comparison with building small Android APKs,
[read this great article](http://engineering.khanacademy.org/posts/a-really-small-app.htm)
by Charlie Marsh at Khan Academy.

I spent most of my time on the IndexedDB portion of Memoui, learning how best to
organize the transaction-based persistence of its two datastores, and the data
structure representing the tabbed (fixed) collection of notes and current tab
state. If you look at the code, you’ll notice the strange name of the class
managing the application state JSON, a result of my modeling Memoui against the
similar needs of my more sophisticated app in progress whose UI centerpiece is an
[Elix Carousel](/content/elix/Carousel/index.html)
rather than Tabs.

I should mention this learning point. I grew unhappy with the data structure
names, but they were tied into the schema of Memoui’s IndexedDB stores. Since I
already had a small set of users, making a naming change
would require adding support for the IndexedDB `onupgradeneeded`
event, capturing the current persisted data, creating new versions of the
store(s), populating those with the saved data, and blowing away the old stores.
While this will be necessary work in future projects, I didn’t care to do so for
Memoui. It’s a lesson in careful planning.

No application, even the simplest, is ever done and this exercise opens the door
to endless improvements and changes based on learned insights. For now, I’m
satisfied both with the learning exercise and with having a minimal app on my
phone that, due to its speed and simplicity, I actually find myself using every
day.
