When designing Quint Project, we were guided by two principles: complete user autonomy and absolute deployment simplicity. To achieve this, we combined a Local-first philosophy with a modern, yet lightweight technical stack.
In this article, we take a look under the hood of the system to explore its architecture, synchronization logic, and engineering choices.
1. Overall Architecture: Everything in a Single Binary
The project is clearly decoupled into backend and frontend. However, during the final build phase, they compile into a single standalone binary executable file written in Go. The Golang ecosystem allows us to fully embed all static frontend assets (HTML, CSS, JS) directly inside the executable container.
For the end-user, this translates to trivial updates and deployment: one file manages the system logic, the storage backend, and the user interface.
2. Frontend: Vanilla JavaScript and Client Autonomy
The user interface of Quint Project is built entirely without bulky modern frameworks. Our stack relies on HTML, Vanilla JavaScript, Tailwind CSS, and Vite. Node.js is utilized strictly during development and asset compilation via Vite—the production build outputs clean, lightweight, standalone code.
For advanced functionality, we only use highly targeted, modular libraries:
-
marked+marked-katex-extension— for fast Markdown rendering and mathematical notation support. -
dompurify— for secure DOM interactions and client-side data sanitization. -
jszip+file-saver— for generating compressed ZIP archives on-the-fly during note export operations.
Where is data stored? All notes and folders are committed first to the browser's local transactional database — IndexedDB. Search indexing, record addition, and modifications execute instantly on the client device. Backed by PWA (Progressive Web App) support, the application can be installed natively on desktop or mobile, operating seamlessly without any active internet connection.
3. Backend: The Efficiency of Go and the Choice of SQLite
The server component is engineered using Go (1.25.0+) alongside the Gin routing framework and SQLite as the storage engine.
Why SQLite?
The project is tailored specifically for individual workloads and
small teams. We needed a database model that brings near-zero
operational maintenance overhead. SQLite stores the entire relational
database inside a single flat file, making backup orchestration and
data migrations incredibly straightforward.
Despite typical misconceptions surrounding SQLite's scalability limitations, it delivers remarkable performance within our architecture:
- Zero Latency: Because the system utilizes a Local-first architecture, the user interacts directly with the local IndexedDB with sub-millisecond response times. The remote server never sits in the critical path of UI responsiveness.
- Background Aggregation: The server-side SQLite instance operates as a coordination hub for processing data deltas (push/pull operations). It effortlessly services over 100 concurrent users.
- WAL Mode (Write-Ahead Logging): Enforcing WAL mode allows the database engine to concurrently ingest sync payloads (writes) from multiple clients without blocking read operations.
4. Seamless Background Synchronization
Client-to-server data synchronization is entirely asynchronous. When you create or update a note, the app commits it locally with instantaneous interface feedback, periodically dispatching mutations to the server in the background. If connectivity drops, deltas safely queue on the local device and push automatically once a network path re-establishes.
Server-side updates pull down to the client under two primary triggers: window focus changes (when a user navigates back to the application tab) or immediately when the deviceTransitions from offline to online status.
5. Team Concurrency Guardrails
Currently, a strict limit of up to 10 users is enforced per instance. This is an intentional architectural boundary designed to completely avoid race conditions and complex merge conflicts when multiple users attempt to concurrently modify identical files.
If your organizational unit exceeds this scale, you can easily partition into sub-teams of up to 10 people and spin up dedicated, isolated instances for each group.
6. Resource Footprint and Deployment
By pairing Go with SQLite, Quint Project maintains an incredibly lightweight footprint. In testing, a running Docker container consumes under 20 MB of RAM, allowing you to comfortably host it on entry-level Virtual Private Servers (VPS).
Orchestrating deployment takes just a few moments via Docker Compose:
-
1. Copy the
docker-compose.ymlbaseline layout from our project README file. - 2. Adjust your configuration variables (ports, environment keys) as needed.
- 3. Spin up the infrastructure using the following command:
docker compose up -d
(For developers and open-source enthusiasts, building the system directly from raw source files is also fully supported).