Web app · PWA
Carnet, an offline note-taking app with no account
Carnet is a progressive web app for taking notes that I designed and built. It works fully offline and without an account: notes are stored in the browser and never leave the device.
- PWA
- IndexedDB
- JavaScript
- Playwright
The idea
Jot down a note quickly, on a phone or a computer, without signing up and without handing your notes to a server. Carnet installs on the home screen and opens without a network.
The code follows the same frugal principle: no dependencies, no build step. The folder deploys as is to any static HTTPS host. Only visits are counted, without cookies; the content of notes is never sent.
- No account, no notes sent anywhere
- Works without a network
- No dependencies, no build step
- Export and import of all notes
Key features
Notes and autosave
Create, pin and delete notes, with an undoable delete. Notes are saved as you type and the app asks the browser for persistent storage.
Light Markdown and Reading mode
Headings, lists, clickable checkboxes, quotes, colors and highlights. A formatting bar sits above the keyboard on mobile.
Search and tags
Instant, accent-insensitive search across titles and text, with highlighting. Any #keyword becomes a filter.
Voice dictation
Dictated text is inserted at the cursor, in French, when the browser offers speech recognition.
Photos and sketches
Attached images are resized to 1600 px, and sketches are drawn with a finger or a mouse using a pen, a highlighter and an eraser.
Trash and export
A deleted note stays in the trash for thirty days. JSON export, import by merge where the most recent version wins, and a reminder when the last export is more than thirty days old.
Sharing from Android
Sharing a text or a link to Carnet offers to create a note. A “Quick note” shortcut opens the editor directly.
Everyday comfort
Automatic dark mode, a single-screen mobile layout, keyboard shortcuts and sorting by date or title.
Technical choices
HTML, CSS and JavaScript with no framework and no dependencies, relying on browser APIs for everything else.
IndexedDB
Notes and their attachments are stored in the browser. The JSON export includes images as base64 and the trash.
Service worker
The app is cached to work offline. A new version is detected when the app returns to the foreground, when the network comes back and every hour, then announced with a message.
Share target
An Android share arrives as a POST to the service worker, which stores the text in IndexedDB and redirects to the home page: shared content never reaches the server.
Playwright tests
Critical scenarios run on desktop Chrome and a Pixel 5: persistence, trash, search, Reading mode, attachments, export then import, and service worker updates.
Continuous deployment
Each push runs the tests, then a two-pass SSH deployment and a check of what the site actually serves.
Technologies
- JavaScript
- PWA
- IndexedDB
- Service worker
- Web Share Target
- Playwright
- GitHub Actions
Challenges and lessons learned
Updates despite the CDN cache
The CDN keeps JavaScript and CSS files for a year. Each version therefore gets a new URL, and the service worker, always re-fetched from the network, activates immediately and offers to reload.
Sharing that never touches the server
Shared text is intercepted by the service worker and never enters a cache. Since any site can open Carnet with text in the URL, the page asks for confirmation before creating the note.
Not losing notes
With no account and no server, backups are up to the user: persistent storage requested, a thirty-day trash, export reminders and import by merge.
Going further
- Live site: note.erdus.fr (opens in a new tab)
- Related service: Website development
- Other projects: Erdus Games, Cadence
- All projects
Need a custom web app?
Offline, installable, respectful of user data: let's talk about your project in thirty minutes.
A 30-minute video call, no commitment, to frame your needs.