Skip to main content

Storage Providers

Kanban Lite decouples what you store from where you store it through the capability-based plugin system. Two namespaces control storage: card.storage for cards and comments, and attachment.storage for file attachments. Swap providers in .kanban.json without changing any application code.

markdown default Cards stored as plain .md files with YAML frontmatter. Human-readable, git-friendly, zero dependencies.
sqlite Built-in SQLite provider via kl-sqlite-storage. Better query performance for large boards. Single-file database.
kl-mysql-storage External npm package for MySQL/MariaDB-backed card storage. Suitable for shared team deployments.
kl-s3-attachment-storage External npm package — store attachments in S3 or any S3-compatible object storage (MinIO, Cloudflare R2, etc.).

Configure providers

Select providers in .kanban.json at your workspace root:

{
  "storage": {
    "card.storage":        { "provider": "sqlite" },
    "attachment.storage": { "provider": "kl-s3-attachment-storage" }
  }
}

Migrate between providers

Migrate in place without losing data using the CLI or REST API:

# Check the current provider status
kl storage status

# Migrate cards to SQLite
kl storage migrate-to-sqlite --sqlite-path .kanban/kanban.db

# Migrate back to markdown files
kl storage migrate-to-markdown

REST API equivalents:

GET  /api/storage                                   # provider status
POST /api/storage/migrate-to-sqlite                 # { "sqlitePath": ".kanban/kanban.db" }
POST /api/storage/migrate-to-markdown

S3 / MinIO attachment storage

Install the package and point it at any S3-compatible endpoint via environment variables or .kanban.json:

npm install kl-s3-attachment-storage
{
  "storage": {
    "attachment.storage": {
      "provider": "kl-s3-attachment-storage",
      "config": {
        "endpoint": "http://127.0.0.1:9000",
        "bucket":   "kanban",
        "region":   "us-east-1"
      }
    }
  }
}

Provider Configuration Examples

Below are complete install & configure snippets for every first-party storage provider.

Markdown (default)

The built-in markdown provider requires no extra packages and no .kanban.json entry — it is active by default. Cards are stored as .md files with YAML frontmatter.

{
  "version": 2
}

SQLite (card.storage + attachment.storage)

# Install
npm install kl-sqlite-storage better-sqlite3

# Migrate existing cards into SQLite
kl storage migrate-to-sqlite --sqlite-path .kanban/kanban.db
{
  "version": 2,
  "plugins": {
    "card.storage": {
      "provider": "sqlite",
      "options": {
        "sqlitePath": ".kanban/kanban.db"
      }
    },
    "attachment.storage": {
      "provider": "sqlite"
    }
  }
}

MySQL (card.storage)

# Install
npm install kl-mysql-storage mysql2
{
  "version": 2,
  "plugins": {
    "card.storage": {
      "provider": "mysql",
      "options": {
        "host": "localhost",
        "port": 3306,
        "user": "kanban",
        "password": "secret",
        "database": "kanban_db"
      }
    }
  }
}

Required option: database. All other options (host, port, user, password, ssl) have sensible defaults. Attachments remain on the local filesystem; pair with kl-s3-attachment-storage for cloud attachments.

S3 Attachment Storage (attachment.storage)

# Install
npm install kl-s3-attachment-storage

# Set required environment variables
export KL_S3_BUCKET=my-kanban-attachments
export AWS_REGION=us-east-1
# AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY picked up automatically

# MinIO / LocalStack users also need:
# export KL_S3_ENDPOINT=http://localhost:9000
# export KL_S3_FORCE_PATH_STYLE=true
{
  "version": 2,
  "plugins": {
    "attachment.storage": {
      "provider": "kl-s3-attachment-storage"
    }
  }
}

All credentials and endpoint configuration are read from environment variables — nothing sensitive goes into .kanban.json.

SQLite Card State (card.state)

# Install
npm install kl-sqlite-card-state
{
  "version": 2,
  "plugins": {
    "card.state": {
      "provider": "sqlite",
      "options": {
        "sqlitePath": ".kanban/card-state.db"
      }
    }
  }
}

Stores actor-scoped unread and open-card state in a lightweight SQLite database. Independent of the card.storage provider — works with markdown, SQLite, or MySQL cards.

Combined Example

Use multiple providers together — for example MySQL cards with S3 attachments and SQLite card state:

{
  "version": 2,
  "plugins": {
    "card.storage": {
      "provider": "mysql",
      "options": {
        "host": "db.example.com",
        "database": "kanban_prod"
      }
    },
    "attachment.storage": {
      "provider": "kl-s3-attachment-storage"
    },
    "card.state": {
      "provider": "sqlite",
      "options": {
        "sqlitePath": ".kanban/card-state.db"
      }
    }
  }
}

Build your own provider

Any npm package that implements the card.storage or attachment.storage capability contract can be used as a provider. See the Plugin System deep dive and the kanban-storage-plugin-author skill for scaffolding a new plugin package.