GitHub - IHaBiS02/SideNote

GitHub

8 min read Original article ↗

A simple notes browser extension that provides a note-taking interface in the browser's side panel. SideNote supports Markdown editing with live preview, syntax highlighting, dark/light modes, and import/export functionality.

Features

  • Configurable WYSIWYG Preview: Use the same rendered document in editable or read-only mode while keeping Markdown as the stored format
  • Full Markdown Source Editing: Double-click Preview or press Edit to edit the complete note as plain Markdown text
  • Soft Line Breaks: Preview renders normal newlines without requiring trailing spaces
  • Configurable Empty Paragraphs: By default, repeated Enter in an empty top-level paragraph does not create a transient block that disappears after source editing; the global setting can restore normal repeated-Enter behavior
  • Extensible Editing: Lit/ProseMirror editor with commands, shortcuts, and input-rule extensions
  • Code Blocks: Language/copy headers with brief success feedback, editable highlight.js syntax highlighting, and aligned multi-line line numbers
  • Link Navigation: Open rendered links in a new tab with middle-click, Ctrl+click, or Cmd+click
  • Dark/Light Mode: Toggle between themes for comfortable viewing
  • Pinned Note Ordering: Hold a pinned note, then drag its lifted card into the animated gap between pinned rows; the order is restored on next launch
  • Import/Export: Save and load notes in .snote and .snotes formats, or export the current note as a standalone HTML file or a directly generated PDF
  • Image Support: Paste and embed images directly into notes; the centered preview modal supports Ctrl+wheel, Firefox touchpad-pinch zoom, direct two-finger touchscreen pinch, and mouse or single-finger drag panning
  • Recycle Bin: Soft delete with 30-day auto-cleanup
  • Fast Large-List Startup: The list reads lightweight note summaries and renders them in one batch; Markdown bodies, cleanup work, and feature-specific libraries are deferred until they are needed. Deferred image cleanup scans indexed deletion keys without loading stored image Blob values
  • Browser Integration: Works in Chrome AND Firefox (Firefox is in development)
  • Keyboard Shortcut: Quick access with Shift+Alt+W; a new-install setup popup appears when the browser leaves the command unassigned

Installation

From Store

Chrome
Firefox

For Development

  1. Clone this repository:

    git clone https://github.com/IHaBiS02/SideNote
    cd SideNote
  2. Install dependencies:

  3. Build the extension:

  4. Load the extension:

    • Chrome: Go to chrome://extensions/, enable Developer mode, click "Load unpacked", select build/chrome/
    • Firefox: Go to about:debugging, click "This Firefox", click "Load Temporary Add-on", select the built extension

Usage

  1. Click the SideNote icon in your browser toolbar or use Shift+Alt+W
  2. The side panel will open with the notes interface
  3. Make a new note and write notes
  4. In full Markdown source mode, use the WYSIWYG button when editable Preview is enabled, or the Preview button when it is read-only. You can also press Shift+Enter or Ctrl/Cmd+Enter to return. While editing a custom title, Enter or Escape finishes only the title edit and keeps the current note open.

Pinned notes remain above regular notes. Hold a pinned note for about 150 ms, then drag the smaller floating card vertically. An animated rounded gap opens at the current drop position, and the drag continues outside the original row. Stable row-center boundaries and a 10px hysteresis zone keep the gap from reopening repeatedly when the pointer rests near a boundary. A short click still opens the note, and dragging from the pin or delete buttons does not start reordering. Cancelling the pointer or leaving the extension window restores the original order. The hold delay is a global-only setting adjustable from 100 to 2000ms; it defaults to 150ms and applies the next time the note list is shown.

The image modal supports physical touchpad pinch in Firefox. Chromium extension Side Panels can consume that gesture before a DOM wheel event reaches SideNote, so touchpad pinch is not supported there; use Ctrl+wheel instead. Direct two-finger touchscreen pinch remains handled through Pointer Events.

On a new installation, SideNote checks the browser's registered command. If the shortcut is unassigned, a small setup window links directly to the browser's extension shortcut settings. The check runs only on initial installation, so a shortcut intentionally removed later does not cause repeated prompts.

You can paste image on the clipboard directly into notes by Ctrl+V.
Legacy text-processing options are available in settings for older Markdown workflows that used trailing spaces for line breaks.

In settings, you can choose theme, Mode of Title (Default use first line as title, Custom let user type own title by double-click title in note), text size, whether Preview is directly editable, code block header behavior, image deletion behavior, and legacy Markdown line-break behavior. WYSIWYG text, full-document plain text, and fenced code blocks have independent line-spacing controls from 1.0 to 3.0, available globally or per note. Their defaults are 1.5, 1.2, and 1.2, respectively. Editable WYSIWYG Preview is enabled by default; disabling it keeps the same rendering and switches Preview to read-only mode.

The global Prevent Extra Empty Paragraphs setting is enabled by default. It ignores another Enter when the caret is already in an empty top-level paragraph so source-mode round trips do not remove a temporary blank block. Disable it to allow repeated Enter presses to create additional empty paragraphs using normal ProseMirror behavior. Hover over the checkbox itself for a tooltip explaining both modes and the source-mode round-trip limitation. All other settings checkboxes, selection fields, and number inputs also provide control-specific hover explanations, with each sentence displayed on its own line for readability.

Images button show all images used in the notes, showing that which one is used in which note. Recycle bin shows all soft-deleted notes and images, and let user delete all at once. Licenses show license of libraries used in this project.

Export buttons keep the default .snote / .snotes behavior on left click. Right-click an export button to choose .zip or .snote / .snotes; right-click the .zip option to show original Markdown and two-space line-break Markdown export options above the .zip row. The current-note export button also offers Save as PDF and Save as HTML. HTML export creates one self-contained document and embeds both SideNote-stored and reachable external images as Base64 data URLs for offline viewing. If an external image cannot be downloaded because of network or cross-origin rules, the export fails instead of leaving an online dependency in the file. Fenced code headers retain the SideNote copy button through a small embedded handler. The exported note body shares Preview typography, lists, links, tables, checkboxes, and syntax colors. Checklist boxes remain clickable in the saved HTML; those temporary changes are not written back to SideNote or the file, so reopening it restores the exported check state. PDF export renders the same sanitized document locally without opening the browser print dialog or sending the note to a server; interactive copy buttons are omitted. PDF pages preserve browser-rendered fonts and formatting, but their note content is rasterized rather than selectable text. All-notes .zip exports use sanitized note titles as folder names, with suffixes added when titles collide. .snotes archives include a manifest that preserves displayed note order, pinned state, and pinned order. When merging an archive into an existing note list, imported pinned positions are rebased after existing pinned notes and regular-note timestamps are made unique while retaining the archive order.

SideNote keeps JSZip, Marked, DOMPurify, and html2pdf packaged inside the extension for offline use, but loads them into the side panel only when archive import/export, license rendering, HTML export, or PDF export needs them.

HTML/PDF export dependency licenses

Direct PDF export uses html2pdf.js 0.14.0, html2canvas 1.4.1, and jsPDF 4.2.1, all under the MIT License. The remaining newly installed transitive packages are also MIT-licensed. Document export reuses Marked (MIT), highlight.js (BSD-3-Clause), and DOMPurify (dual Apache-2.0/MPL-2.0; SideNote distributes it under the Apache-2.0 option). These terms are compatible with SideNote's MIT license when their notices are retained. Complete notices are generated in LIBRARY_LICENSES.md, and the html2pdf distribution notice is packaged beside its browser bundle.

Development

Build Commands

# Install the extension and editor workspace dependencies
npm ci

# Type-check and test the editor and extension
npm run typecheck
npm run test:run

# Build the editor, Chrome/Firefox packages, and Firefox reviewer source ZIP
npm run build

The SideNote runtime is maintained as TypeScript in background.ts and src/. The reusable editor source is part of this repository at packages/wysiwyg-markdown/. The root build compiles both into JavaScript before packaging the extension, then creates the AMO reviewer source archive, so a SideNote checkout is sufficient for development and releases. npm run release:amo remains an alias of npm run build for compatibility.

Architecture references:

Build output is written to build/. See FIREFOX_AMO_SOURCE_SUBMISSION_GUIDE.md for the Firefox source-review package workflow.

License

See LICENSE file for details.