Installation
Docker Compose
The easiest way to get started is using Docker Compose. This method requires
minimal setup and handles all dependencies automatically.
Prerequisites:
DockerandDocker Composeinstalled on your system
Installation steps:
- Create a new directory for your Zen installation:
$ mkdir zen && cd zen
- Create a
docker-compose.ymlfile:
services:
zen:
image: ghcr.io/sheshbabu/zen/zen:latest
container_name: zen
network_mode: 'bridge'
ports:
- 8080:8080
volumes:
- /path/to/data:/data
- /path/to/images:/images
restart: 'unless-stopped'
- Start the application:
$ docker compose up -d
- Access Zen in your browser at
http://localhost:8080
Note: Your notes and images will be stored in the
./dataand./imagesdirectories respectively, ensuring your data persists between container restarts.
Build from Scratch
For developers who want more control or need to modify the source code, you can build Zen from the source repository.
Prerequisites:
- Go 1.23 or later
- Git
- esbuild
Build steps:
- Install tools:
- Install Go
- Install esbuild
$ go install github.com/evanw/esbuild/cmd/esbuild@latest
- Clone the repository:
$ git clone https://github.com/sheshbabu/zen.git
$ cd zen
- Build the application:
$ make build
- Run the application:
$ ./zen
- Access Zen in your browser at
http://localhost:8080
Keyboard Shortcuts
Shortcuts use Ctrl on Windows/Linux and Cmd on macOS.
Global Shortcuts
These shortcuts work from anywhere in the application:
Ctrl/Cmd + N- Create a new noteCtrl/Cmd + K- Open searchCtrl/Cmd + \- Toggle editor widthEscape- Close modals and dialogs
Editor Shortcuts
These shortcuts work when editing notes:
Ctrl/Cmd + Enter- Save note (or start editing when viewing)Ctrl/Cmd + B- Bold selected textCtrl/Cmd + I- Italicize selected textCtrl/Cmd + Shift + H- Highlight selected textTab- Insert indentation (2 spaces)Enter- Continue the current list item (bullets, numbers, and task lists)Escape- Close editor popup
Navigation Shortcuts
These shortcuts help you navigate through search results and suggestions:
Arrow Up/Down- Navigate through search resultsTab- Cycle through the search tabs (All, Notes, Tags)Enter- Select highlighted search result or tag suggestionEscape- Close search or tag suggestionsBackspace- Close tag suggestions when input is empty
Image Gallery Shortcuts
These shortcuts work when viewing images in the lightbox:
Escape- Close the image lightboxArrow Left- Navigate to previous imageArrow Right- Navigate to next image
Canvas Shortcuts
These shortcuts work while a canvas is open:
Ctrl/Cmd + K- Toggle the canvas sidebarCtrl/Cmd + D- Duplicate the selected nodesDelete/Backspace- Delete the selected nodesEscape- Finish editing a sticky note's text
Tip: Most shortcuts work contextually, they only activate when you're in the relevant part of the interface.
Backup
PowerShell
To back up your notes, you can use the following PowerShell script. This script creates a timestamped backup of your SQLite database and verifies its integrity.
$sourceDbPath = "C:\path\to\data\zen.db"
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupDbPath = "C:\path\to\backup\zen_backup_$timestamp.db"
Write-Host "Backing up Zen..."
sqlite3 $sourceDbPath ".backup '$backupDbPath'"
Write-Host "`n--- Checking integrity of the backup database ---"
$integrityResult = sqlite3 $backupDbPath "PRAGMA integrity_check;"
$integrityResult = $integrityResult.Trim()
if ($integrityResult -eq "ok") {
Write-Host "Backup successful and verified: $backupDbPath"
Write-Host "`n--- Checking for notes in the backup database ---"
$notesCheckOutput = sqlite3 $backupDbPath "SELECT COUNT(*) FROM notes;"
$notesCheckOutput = $notesCheckOutput.Trim()
if ($notesCheckOutput -match "^\d+$") {
$notesCount = [int]$notesCheckOutput
if ($notesCount -gt 0) {
Write-Host "Notes table found with $notesCount rows."
} else {
Write-Host "Notes table exists but is empty (0 rows)."
}
} elseif ($notesCheckOutput -like "Error: no such table:*") {
Write-Host "Notes table not found in the backup database."
} else {
Write-Host "Could not determine notes table status. SQLite output: '$notesCheckOutput'"
}
} else {
Write-Host "Backup verification failed for: $backupDbPath"
Write-Host "Integrity check result: '$integrityResult'"
}
# Restart so the WAL file is created again
Write-Host "`nRestarting Zen..."
docker compose restart
MCP Integration
Zen provides Model Context Protocol (MCP) integration, allowing you to connect with external tools and services like Claude Code. This enables you to search, read, and manage your notes directly from supported applications.
Generate Token
Before you can use MCP integration, you need to generate an access token:
- Open Zen in your browser
- Click on Settings in the sidebar
- Click on the MCP tab
- Click Generate Token to create a new access token
- Copy the generated token - you'll need this for the next step
Claude Code
To integrate Zen with Claude Code, use the following command with the token you generated in the previous step:
$ claude mcp add --transport http zen-notes http://<ZEN_URL>/mcp --header "Authorization: Bearer <TOKEN>"
Replace <TOKEN> with the actual token you generated.
Once configured, you can use Claude Code to:
- Search through your notes
- Read specific notes by ID
- List all your notes
- Access notes from your development workflow
LM Studio
To integrate Zen with LM Studio, you can configure the MCP server in your LM Studio settings. See the LM Studio MCP documentation for detailed setup instructions.
Add the following configuration to your mcp.json file:
{
"mcpServers": {
"zen-notes": {
"url": "http://<ZEN_URL>/mcp",
"headers": {
"Authorization": "Bearer <TOKEN>"
}
}
}
}
Replace <TOKEN> with the actual token you generated.
Import
You can import existing Markdown files into Zen from Settings → Import. By default, the note title is taken from the filename and the content is imported as-is.
Frontmatter
If a file starts with a YAML frontmatter block, Zen reads it to set the note's title, tags, and
timestamps. The block must be the very first thing in the file, opening with --- on its
own line and closing with another --- on its own line. The frontmatter itself is
stripped from the imported note's content.
title- Note title. Falls back to the filename when omitted.tags- Comma-separated tag names. Tags that don't exist yet are created.created- Creation timestamp in RFC 3339 format.updated- Last modified timestamp in RFC 3339 format.
Example
---
title: Trip to Kyoto
tags: travel, japan
created: 2025-03-14T09:30:00Z
updated: 2025-04-02T18:45:00Z
---
# Trip to Kyoto
Notes from the trip...
Note: If only one of
createdorupdatedis provided, the other is set to the same value. If neither is provided, or a timestamp can't be parsed, the import time is used instead.
Templates
Templates let you create reusable note structures with dynamic placeholders. They're perfect for recurring note types like daily journals, meeting notes, or project plans.
Creating Templates
To create a new template:
- Click on Templates in the sidebar
- Click the New button
- Enter a template name (e.g., "Daily Journal", "Meeting Notes")
- Optionally set a default note title
- Write your template content using Markdown
- Add tags if needed
- Click Save
Placeholders
Templates support dynamic placeholders that are automatically replaced when creating a new note:
{{date}}- Current date in YYYY-MM-DD format (e.g., 2025-01-15){{time}}- Current time in HH:MM:SS format (e.g., 14:30:00){{datetime}}- Current date and time (e.g., 2025-01-15 14:30:00){{datetime:FORMAT}}- Custom datetime format using Go's time format
Custom Datetime Formats
You can use custom datetime formats with the {{datetime:FORMAT}} placeholder:
{{datetime:01/02/2006}}- US date format (MM/DD/YYYY){{datetime:02-01-2006}}- European date format (DD-MM-YYYY){{datetime:Monday, January 2, 2006}}- Long date format{{datetime:15:04}}- 24-hour time without seconds{{datetime:3:04 PM}}- 12-hour time with AM/PM
Format Reference: Go uses a reference time of
Mon Jan 2 15:04:05 MST 2006for formatting. Use these values to create your custom format.
Example Template
# Daily Journal - {{datetime:Monday, January 2, 2006}}
## Morning Reflection
- What am I grateful for today?
## Tasks
- [ ]
## Evening Notes
- What went well today?
- What could be improved?
---
Created at {{time}}