A self-hosted web application for managing crochet patterns, tracking project progress, and organizing your crochet library.
Try out the demo yourself (username: demo, password: demo) or read the docs to get started.
- Upload PDF patterns or create Markdown patterns with automatic thumbnail generation
- Organize by categories and hashtags
- Integrated PDF viewer with row counters, timer, page navigation, zoom, keyboard controls and annotations
- Pattern notes stored as markdown files
- Group patterns into projects with progress tracking
- Built-in row and stitch counters with keyboard shortcuts
- Unlimited custom counters per pattern
- Project timer with auto-timer and inactivity detection
- Remembers your page position in each pattern
- Single-user mode (no login) or multi-user with role-based access
- OIDC/SSO integration for external authentication
- Per-user permissions for PDF uploads and markdown creation
- Admin panel for user management
- Manual and scheduled backups (daily/weekly/monthly)
- Selective backup options (PDFs, markdown, archive, notes)
- Auto-prune old backups by count or age
- Pushover notifications for backup events
- Optional external backup storage — just mount a volume to
:/backupsand Yarnl automatically detects it
- 15+ color themes with light/dark modes
- Custom Google Fonts support
- Configurable keyboard shortcuts
- Bluetooth/media remote support for hands-free counting
- Mobile-optimized responsive design
Yarnl is easy to get up and running with Docker. You'll be crocheting in no time.
Prerequisites:
- Open terminal and run the following commands:
Linux / macOS
mkdir yarnl && cd yarnl
curl -O https://raw.githubusercontent.com/titandrive/yarnl/main/docker-compose.yml
docker compose up -dWindows (PowerShell)
mkdir yarnl; cd yarnl
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/titandrive/yarnl/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up -d- Open your browser and navigate to
http://localhost:3000
By default, Yarnl starts in single-user mode with an admin account and no password.
To configure passwords, timezone, and other options, download the .env.example file, rename it to .env, and edit as needed before starting.
If you prefer to write the compose file yourself instead of downloading it:
services:
postgres:
container_name: yarnl-db
image: postgres:16-alpine
volumes:
- yarnl-postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=yarnl
- POSTGRES_USER=yarnl
- POSTGRES_PASSWORD=yarnl
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U yarnl"]
interval: 5s
timeout: 5s
retries: 5
yarnl:
container_name: yarnl
image: titandrive/yarnl:latest
ports:
- "3000:3000"
volumes:
- ./users:/app/users
# Optional: mount an external path for backups
# - /mnt/user/drive:/backups
environment:
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_DB=yarnl
- POSTGRES_USER=yarnl
- POSTGRES_PASSWORD=yarnl
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=
- TZ=UTC
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
volumes:
yarnl-postgres-data:Most configuration is done via settings once Yarnl is up and running. There are a few environment variables available to customize your installation:
| Variable | Default | Description |
|---|---|---|
POSTGRES_DB |
yarnl |
Database name |
POSTGRES_USER |
yarnl |
Database user |
POSTGRES_PASSWORD |
yarnl |
Database password |
POSTGRES_HOST |
postgres |
Database hostname (use default with Docker Compose) |
POSTGRES_PORT |
5432 |
Database port |
ADMIN_USERNAME |
admin |
Initial admin username |
ADMIN_PASSWORD |
(empty) | Admin password (empty = passwordless login) |
PORT |
3000 |
Port exposed on the host |
NODE_ENV |
production |
Defaults to production in the Docker image |
TZ |
UTC |
Timezone for scheduled backups |
SECURE_COOKIES |
false |
Set to true to mark session cookies as HTTPS-only |
FORCE_LOCAL_LOGIN |
false |
Force local login even when OIDC/SSO is configured |
OIDC is configured through the admin settings panel in the app (Settings > Admin > SSO). Yarnl supports any OpenID Connect provider with auto-discovery. If SSO is misconfigured and you get locked out, set FORCE_LOCAL_LOGIN=true to bypass SSO and log in with your local credentials.
All user data is stored in the ./users directory on the host, mounted as a Docker volume:
- Pattern files (PDFs, markdown, images)
- Thumbnails
- Notes
- Archive
- Backups
The PostgreSQL database uses a named Docker volume (yarnl-postgres-data) for metadata, counters, and settings.
- Install Node.js (v18+) and PostgreSQL
- Install dependencies:
npm install - Set database environment variables
- Start the server:
npm start
Clone the repo and create a docker-compose.override.yml to build from source and mount the public directory for live editing:
services:
yarnl:
build: .
volumes:
- ./public:/app/publicThen run docker compose up -d --build.
- Backend: Node.js, Express
- Database: PostgreSQL 16 (pg)
- Frontend: Vanilla JavaScript, HTML5, CSS3
- Markdown: Marked.js (rendering)
- PDF: PDF.js (viewing), Sharp (thumbnails), Poppler (processing), pdf-parse (text extraction)
- Uploads: multer
- Auth: bcrypt, openid-client
- Backup: archiver, unzipper, node-cron (scheduling)
- Containerization: Docker & Docker Compose
Yarnl was developed with the assistance of Claude.

