The app is built with only client-side libraries. The project is a vanilla TypeScript template of vite
.
All the code is contained in a single
src
folder. Runningbuild
will generate adist
folder with the compiled code, that you can deploy to any static hosting service.
Routing is implemented using TanStack Router, that offers a simple and type-safe API for routing on the client.
The architecture is based on effect
. The core logic is implemented as effect services, that are then wrapped inside Layer
and composed to define each feature.
The local database is provided by Pglite. Pglite is a WASM build of postgres
that runs in the browser. It is used to store and query the data locally with SQL.
Pglite also provides a
live
extension that unlocks reactive queries. Every change in the data is automatically reflected in the UI.
Queries are defined by integrating Pglite with drizzle-orm
. Drizzle is a TypeScript ORM that allows to define the database schema and query the data using TypeScript types.
State management used xstate
and the actor model. Each feature is implemented as a state machine composed by multiple smaller actors. This allows to easily handle asynchronous operations, loading states and error messages.
Finally, the UI is based on react-aria-components
and tailwindcss
(v4).
These are the core dependencies:
@tanstack/react-router
effect
@electric-sql/pglite
drizzle-orm
xstate
react-aria-components
The app then uses vite-plugin-pwa
to generate a service worker and a manifest file, making the app available as a Progressive Web App (PWA).
This allows the app to be installed on the user's device and work completely offline.
Let's dive into the project. First step is setting up the database structure 🚀