Writerly is a calm, browser-based writing workspace for organizing manuscripts and chapters. It includes a rich-text editor, automatic saving, chapter goals, and PDF export.
- Create, rename, and delete manuscripts and chapters
- Write with headings, bold, italics, underlines, lists, and quotes
- Text alignment (left, center, right, justify) preserved in both editor and PDF export
- Autosave chapter content and word counts
- Set a chapter goal and track progress
- Export a chapter as a PDF
- Local Bun + SQLite API; no separate database service is needed
- Frontend: React, TypeScript, Vite, TipTap, and Tailwind CSS
- Backend: Bun, Elysia, and SQLite
- Bun 1.0 or later
bun install
cd backend
bun install
cd ..Start the API in one terminal:
cd backend
bun run index.tsStart the frontend in another terminal:
bun run devOpen the local URL printed by Vite (normally http://localhost:5173). The frontend forwards /api requests to the backend at http://localhost:3001.
The backend creates and seeds backend/data/writerly.sqlite automatically on first run.
| Command | Description |
|---|---|
bun run dev |
Start the frontend development server |
bun run build |
Type-check and create a production build |
bun run lint |
Run Oxlint |
bun run preview |
Preview the production build |
src/ React app and styling
src/components/ Editor, dialogs, and interface components
src/lib/ Client-side helpers, including PDF export
backend/ Bun/Elysia API and SQLite database
backend/schema.sql Database schema
Contributions are welcome. Please read CONTRIBUTING.md for setup, coding, and pull-request guidance.
- Added an Appearance menu with Green, Pink, and Dark themes; preference is remembered in local storage
- Themed the sidebar, editor chrome, dialogs, and controls so colors stay consistent across the app
- Fixed sticky MANUSCRIPTS / CHAPTERS labels and selected manuscript/chapter blocks so their backgrounds match the active theme
- Hid the default Electron application menu on desktop
- Improved the left navbar so manuscripts and chapters share one scrollable column, with sticky section labels and a pinned brand/footer
- Added more writing fonts (EB Garamond, Literata, Spectral, Cormorant Garamond, Newsreader, Crimson Pro, Cardo, Fraunces, Instrument Sans)
- Replaced the native font
<select>with a compact scrollable font picker so the menu stays clear of the writing page
Problem: Opening the packaged Writerly .exe (Electron) showed a blank white screen.
Root cause: The production build loaded the UI over file://, which blocked ES module scripts, and the desktop app did not start the bundled backend/API.
Fix:
- Bundle and start the compiled Bun backend with the desktop app
- Serve the built frontend over
http://127.0.0.1:3001instead offile:// - Point API requests at the local backend when running in the packaged app
Problem: Text alignment (center, right, justify) set in the editor was not reflected in exported PDFs. Headings appeared left-aligned regardless of the alignment chosen.
Root cause: Two issues in src/lib/exportChapterPdf.ts:
- The heading styling loop used
el.style.cssText = ..., which replaced the entirestyleattribute and wiped out thetext-aligninline style written by Tiptap. - Tiptap wraps heading text in
<span>elements. Because html2canvas has limited CSS inheritance support,text-alignon the parent<h*>was not applied to the inner<span>, causing alignment to be lost during canvas rendering.
Fix:
- Replaced
el.style.cssText = ...with individual property assignments to preserve existing inline styles. - Added a loop that explicitly copies
text-alignfrom each block element to its child<span>elements before rendering. - Added a
<style>tag inside the printable element to reinforce inheritance rules for html2canvas.
File changed: src/lib/exportChapterPdf.ts
- Create, rename, and delete manuscripts and chapters
- Rich-text editor with headings, bold, italics, underline, lists, and quotes
- Autosave with word count tracking
- Chapter goals and progress bar
- PDF export via jsPDF + html2canvas
- Local Bun + SQLite backend, no external database required
This project is licensed under the MIT License.