Muru is a personal workspace for the things that accumulate during a day: a thought to keep, a snippet to reuse, a task to finish, a password to retrieve, or a purchase to record. I built it to bring those tools into one home, with a small illustrated keeper that gives the application its name and personality.
The workspace now connects notes, credentials, tasks, calendar, shopping, and finance, alongside a file module with limited upload availability. The work has grown from separate tools into shared routines: a task can become a calendar event, and a shopping basket can become a receipt linked to a finance entry.
Purpose and constraints#
The challenge is to make several kinds of personal information feel coherent without giving them all the same security rules. A user signing in and a user unlocking an encrypted vault are different operations. A hidden balance is a display preference, while an encrypted password requires a key. Those distinctions need to survive both the architecture and the interface.
Desktop use favors editing and organization; phone use favors quick capture and retrieval. Hosted storage limits also shape availability: basic accounts currently see Files as coming soon, while staff accounts can upload. Existing files remain available to their owners for download or deletion.
An illustrated daybook#
The current design is called Compact Daybook. Lavender Paper colors, plum ink, Newsreader headings, and Figtree controls sit on flat, ruled surfaces. Light and charcoal-plum dark themes carry the same visual identity.
I used an open collection index and roomier working areas to make notes, credentials, files, and other collections easier to scan. Phone tabs and a full navigation drawer give smaller screens their own navigation pattern. A keyboard page finder helps move between modules on desktop.
Muru's lavender keeper appears in greetings, loading states, empty states, and vault interactions. Painted windows change with the time of day, while a presence setting controls the character's involvement. These details support the daybook atmosphere alongside the actual work: writing, planning, and keeping records.
Notes that support different kinds of work#
Notes support rich text, plain text, code snippets, and saved links, organized with folders and tags. The Tiptap editor adds formatting, checklists, tables, a Markdown source view, focus mode, and export; Monaco remains available for code.
I serialized note saves so an older request cannot overwrite a newer edit. Pending, saved, failure, and retry states make persistence visible, and the editor drains pending changes before its own navigation and lock transitions. Locked note bodies are encrypted in the browser before saving; their titles and organizational metadata remain separate.
Planning, shopping, and money in one routine#
Tasks support nested subtasks and list, board, and tree views. Calendar events support recurrence, and task due dates appear alongside scheduled events. Putting a task on the calendar creates an event linked back to the task, making it possible to return to the original work from the schedule.
Shopping combines quick capture, quantities, categories, bought items, and receipts. Remaining items can be copied with their quantities and notes. Bought items can seed a receipt, and an optional finance link records that receipt as an expense. Editing a linked receipt updates the corresponding transaction.
Finance provides month and year views, category breakdowns, comparisons, and CSV import and export. Savings pots record money moved out of the budget and returned later; they are balance containers rather than goal-progress forecasts. A shared eye toggle hides displayed amounts across the dashboard, finance, and receipts. This changes presentation, not storage or encryption.
Architecture and my implementation focus#
Muru uses Next.js, React, TypeScript, and Tailwind CSS with a hand-built component library. Supabase supplies authentication, PostgreSQL records, and file storage, with Drizzle ORM defining the schema and migrations. Recharts supports finance views, Tiptap and Monaco support editing, and FullCalendar supports calendar presentation.
I built the credential vault around browser-side encryption and kept its unlock state separate from Supabase account authentication. The implementation resides in the Sudo Arx repository, whose README identifies the product as Muru.
The credential form derives a 32-byte key from the vault passphrase and a fresh 16-byte salt using Argon2id. The configured derivation uses 19,456 KiB of memory, two iterations, and parallelism of one. These are source parameters, not a measured claim about unlock speed on every device.
The AES helper uses Web Crypto's AES-GCM implementation with a fresh 12-byte IV generated through crypto.getRandomValues. The credential form submits the encrypted password, IV, and salt to its server action. Service name, username, URL, category, and notes are separate form fields; the password-encryption boundary does not make all credential metadata secret.
Design decision#
Client-side credential encryption separates vault confidentiality from the database's storage responsibility. The PostgreSQL migrations enable row-level security and scope ordinary workspace access to the authenticated user's ID. The vault-verifier table uses an owner-read policy with privileged server-side writes. Those mechanisms solve different parts of the design and should be described separately.
Unlock state and offline behavior#
The vault provider keeps the passphrase in React memory, rather than localStorage or sessionStorage. Its lock function clears that state, and the idle timer defaults to ten minutes when no preference is supplied. Settings offer five-, ten-, thirty-, and sixty-minute timeouts. A reload starts with a locked provider.
The unlock form derives the key locally and decrypts a stored verifier. An account session can therefore be active while the credential vault remains locked. Locked notes use the same unlock boundary. The companion encryption article traces these flows and explains which fields stay outside encryption.
Muru is an installable PWA with opt-in Web Push reminders. Its service worker supports previously visited workspace pages offline and clears personal caches on sign-out and authentication-route returns. It excludes API calls, Server Actions, cross-origin file bodies, and admission routes from caching. Offline page availability depends on prior visits; writes and online services still require a connection.
Controlled access and account operations#
The public website offers an early-access request flow. Requests are validated and rate-limited through Upstash Redis, then reviewed by an administrator before an invitation is issued. Invitation setup asks the new account holder to choose a password and accept the terms. React Email supplies the invitation and setup email layouts.
Account permissions distinguish users, admins, and superadmins. Privileged pages and server operations check the current role before using administrative database access. The superadmin console provides account controls, module usage, and aggregate operational information without using note bodies or decrypted passwords as analytics content.
JSON export and import cover workspace records, including shopping, receipts, savings pots, and the vault verifier. Credential passwords and locked note bodies travel as ciphertext, while ordinary records remain readable JSON. File contents are excluded, so this is a record backup rather than a full file-storage backup.
Demonstrable outcomes and limits#
The current source demonstrates connected planning and receipt workflows, rich-note editing, encrypted password and locked-note saves, local unlock verification, and invitation-based onboarding. The portfolio screenshot illustrates the workspace presentation; it does not validate cryptographic behavior. This update reflects completed implementation through October 12, 2026.
Browser-side encryption does not protect an unlocked session from malicious code executing in that browser. Clearing React state is also not a guarantee that JavaScript memory has been securely erased. Passphrase strength, database configuration, dependency behavior, and recovery procedures still matter.
No audited security outcome, deployment-scale metric, or independently measured performance result is asserted here.
Explore the project#
Open Muru to explore the public product presentation and request early access, or read how the browser-side encryption works. The implementation source is private; the observations here come from its interface components, server actions, crypto helpers, and database migrations.
