Skip to main content

All your open-source and social-media metrics in one place

Project description

velocirepo

Track your open-source project's pulse across package registries, GitHub, and the web.

Table of contents

Overview

velocirepo collects metrics from multiple sources, stores them as JSONL files, and exposes them via SQL (powered by DuckDB). It's designed to run on a schedule (e.g., nightly via GitHub Actions) and commit the results to git, giving you a permanent record of your project's growth.

Supported sources:

Source What it tracks
GitHub Events Individual events (stars, forks, issues, PRs) with user and timestamp
GitHub Traffic Daily page views and git clones (requires admin access)
PyPI Daily download counts
CRAN Daily download counts
Homebrew Install counts (30-day, 90-day, 365-day, lifetime)
Plausible Daily pageviews, visitors, visits
OpenVSX Total downloads, reviews, ratings
YouTube Views, likes, comments, subscribers (channel and per-video)

Installation

velocirepo can be used as a GitHub Action for automated nightly fetching, or installed locally for ad-hoc use.

GitHub Actions (recommended)

name: Fetch Metrics

on:
  schedule:
    - cron: '0 1 * * *'
  workflow_dispatch:

permissions:
  contents: write

jobs:
  fetch:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: posit-dev/velocirepo@v0
        with:
          github-token: ${{ secrets.GH_TOKEN }}
          # plausible-token: ${{ secrets.PLAUSIBLE_TOKEN }}
          # youtube-token: ${{ secrets.YOUTUBE_TOKEN }}

      - name: Commit and push
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git add velocirepo/
          git diff --staged --quiet || git commit -m "Update metrics - $(date -u +'%Y-%m-%d')"
          git push

Or generate this workflow automatically (no installation required):

uvx velocirepo install-ci

Local installation

Homebrew (macOS / Linux)

brew install posit-dev/tap/velocirepo

Scoop (Windows)

scoop bucket add posit-dev https://github.com/posit-dev/scoop-bucket
scoop install velocirepo

uv

uv tool install velocirepo

Or run without installing:

uvx velocirepo fetch

Go

go install github.com/posit-dev/velocirepo/cmd/velocirepo@latest

From source

git clone https://github.com/posit-dev/velocirepo.git
cd velocirepo
go build -o bin/velocirepo ./cmd/velocirepo
cp bin/velocirepo ~/.local/bin/

Shell installer (macOS / Linux)

curl -sSfL https://raw.githubusercontent.com/posit-dev/velocirepo/main/install.sh | sh

This downloads the latest binary to ./bin/velocirepo. Set INSTALL_DIR to install elsewhere:

curl -sSfL https://raw.githubusercontent.com/posit-dev/velocirepo/main/install.sh | INSTALL_DIR=/usr/local/bin sh

Download binary

Pre-built binaries for Linux, macOS, and Windows are available on the Releases page.

Shell completion

# Zsh (add to ~/.zshrc)
eval "$(velocirepo completion zsh)"

# Bash (add to ~/.bashrc)
eval "$(velocirepo completion bash)"

# Fish
velocirepo completion fish | source

Configuration

Create a velocirepo.toml in your project root:

[projects.my-project]
name = "My Project"
github = "owner/repo"
github-traffic = "owner/repo"
pypi = "my-package"

[projects.other-project]
name = "Other Project"
github = ["owner/other", "owner/other-utils"]
cran = "other"
homebrew = "other"
youtube = "@ChannelHandle"
linkedin = "urn:li:organization:123456"

Each source field accepts either a single string or an array of strings, so you can track multiple repositories or packages under one project.

The github-traffic source fetches daily page views and clone counts. GitHub only retains this data for 14 days, so velocirepo preserves it before it's lost. It requires a token with Administration:read permission (or the repo scope for classic tokens).

Or initialize one interactively (auto-detects sources from your repository):

velocirepo init

velocirepo looks for velocirepo.toml by walking up from the current directory. Override with --config or the VELOCIREPO_CONFIG environment variable.

Authentication

velocirepo uses API tokens to authenticate with external services. Tokens can be provided in three ways:

  1. Environment variables — export them in your shell (e.g., export GITHUB_TOKEN=ghp_...)
  2. .env file — place a .env file next to your velocirepo.toml; variables are loaded automatically
  3. GitHub Actions secrets — when using velocirepo install-ci or the GitHub Action, pass tokens as secrets (see Installation)
Variable Required for How to get one
GITHUB_TOKEN GitHub Events, GitHub Traffic Create a personal access token — use a fine-grained token with Contents:read (add Administration:read for traffic data)
PLAUSIBLE_TOKEN Plausible Create an API key in your Plausible site settings
YOUTUBE_TOKEN YouTube Create an API key in the Google Cloud Console with the YouTube Data API v3 enabled
LINKEDIN_TOKEN LinkedIn Run velocirepo auth linkedin after creating a LinkedIn app; see LinkedIn OAuth setup
VELOCIREPO_CONFIG Path to config file (not a token, but supported as an env var)

Usage

velocirepo fetch                 Fetch from all configured sources
velocirepo fetch-github          Fetch GitHub events (stars, forks, issues, PRs)
velocirepo fetch-traffic         Fetch GitHub traffic (views and clones)
velocirepo fetch-pypi            Fetch PyPI download counts
velocirepo fetch-cran            Fetch CRAN download counts
velocirepo fetch-homebrew        Fetch Homebrew install counts
velocirepo fetch-plausible       Fetch Plausible analytics
velocirepo fetch-openvsx         Fetch Open VSX extension metrics
velocirepo fetch-youtube         Fetch YouTube metrics
velocirepo fetch-linkedin        Fetch LinkedIn post metrics and content
velocirepo auth linkedin         Authenticate with LinkedIn OAuth and save `.env`

velocirepo query <sql>           Run a SQL query against the metrics data
velocirepo schema                Show table schemas
velocirepo show-indicators       Print built-in indicator definitions as TOML

velocirepo export <dir>          Export data to Parquet or CSV files

velocirepo badge stars           Generate a stars badge
velocirepo badge forks           Generate a forks badge
velocirepo badge downloads       Generate a downloads badge
velocirepo badge pageviews       Generate a pageviews badge
velocirepo badge custom          Generate a badge from a custom query

velocirepo init                  Create a new velocirepo.toml
velocirepo add-project           Add a project to the config
velocirepo update-project        Update a project's configuration
velocirepo remove-project        Remove a project from the config
velocirepo rename-project        Rename a project's ID
velocirepo list-projects         List configured projects
velocirepo show-project          Show project details
velocirepo import-projects       Bulk-import from GitHub org/user or file
velocirepo validate-projects     Validate source URLs

velocirepo add-view <name>       Scaffold a new view directory
velocirepo remove-view <name>    Remove a view directory
velocirepo list-views            List all views
velocirepo show-view <name>      Show details about a view
velocirepo render-view <name>    Render a view (runs render.sh)
velocirepo render-views          Render all or filtered views
velocirepo serve-view <name>     Start a dev server (runs serve.sh)
velocirepo setup-views           Install dependencies for all views

velocirepo build-db              Build the DuckDB database file for external tools
velocirepo migrate               Migrate data to the latest schema version

velocirepo install-ci            Generate a GitHub Actions workflow
velocirepo sync-secrets          Sync .env secrets to GitHub Actions

velocirepo version               Print version information

Data storage

All data is stored as JSONL files under velocirepo/data/. This entire directory is meant to be committed to git — it's your permanent metric history. Data is organized into three categories:

  • data/metrics/<source>/<project-id>/<date>.jsonl — time-series metrics (date-partitioned)
  • data/events/<source>/<project-id>/<date>.jsonl — individual events (date-partitioned)
  • data/content/<source>/<project-id>/<name>.jsonl — entity data (upsert-by-id)

Metrics sources

Sources like PyPI, CRAN, Homebrew, Plausible, OpenVSX, GitHub Traffic, YouTube, and LinkedIn store one JSON object per metric per day:

{"source":"pypi","metric":"daily_downloads","project_id":"plotnine","target":"plotnine","date":"2026-06-15","value":1523}
{"source":"openvsx","metric":"total_downloads","project_id":"quarto","target":"quarto/quarto","date":"2026-06-15","value":1250000}

Metric names are prefixed with daily_ (for deltas — values that reset each day) or total_ (for snapshots — cumulative totals at a point in time). Homebrew metrics use their own naming (downloads_30d, downloads_365d, etc.).

Fields:

Field Description
source Source name (pypi, cran, homebrew, plausible, openvsx, github-traffic, youtube, linkedin)
metric Metric name (e.g., daily_downloads, total_views, daily_pageviews)
project_id Project ID from your config
target Specific package, repo, site, or extension being tracked
date Date of the measurement (YYYY-MM-DD)
value Integer value
tags Optional key-value metadata (e.g., {"video_id": "..."} for YouTube)

Events sources

Event sources store individual events rather than pre-computed counts, giving you full historical detail including who performed each action and when. Currently, GitHub is the only event source.

{"source":"github","type":"star","project_id":"quarto","target":"quarto-dev/quarto-cli","datetime":"2026-06-15T14:23:01Z","tags":{"user":"alice"}}
{"source":"github","type":"fork","project_id":"quarto","target":"quarto-dev/quarto-cli","datetime":"2026-06-15T09:11:44Z","tags":{"user":"bob"}}

Fields:

Field Description
source Source name (e.g., github)
type Event type (e.g., star, fork, issue_open, issue_close, pr_open, pr_merge)
project_id Project ID from your config
target Specific repo or resource being tracked (e.g., owner/repo)
datetime Full timestamp of the event (ISO 8601)
tags Optional key-value metadata (e.g., {"user": "alice"})

These events are automatically aggregated into daily counts in the metrics DuckDB view (as daily_stars, daily_forks, etc.) so you can query them alongside other sources.

Content sources

Sources that implement the ContentProvider interface also write entity data to data/content/<source>/<project-id>/<name>.jsonl. These files use upsert-by-id (new entries are merged with existing ones) rather than date-partitioned concatenation.

Currently, YouTube and LinkedIn are content sources. YouTube writes video metadata to velocirepo/data/content/youtube/<project-id>/videos.jsonl:

{"source":"youtube","target":"@Fireship","id":"ML3q7Ok4hJg","title":"God-Tier Developer Roadmap","published_at":"2024-03-15T16:00:00Z","duration":423,"tags":["programming","roadmap"]}

LinkedIn writes post metadata to velocirepo/data/content/linkedin/<project-id>/posts.jsonl. Content is exposed as the content DuckDB view; filter by source to query source-specific entities.

Concatenation

Daily JSONL files are automatically concatenated into monthly and yearly files once a period is complete. For example, once all days in January 2026 have been fetched, they're concatenated into 2026-01.jsonl. This keeps the file count manageable for long-running histories. The original daily files are removed after concatenation.

Repository layout

You can either keep metrics in the same repository as your code, or create a dedicated metrics repository. A separate repo is useful when you want to track multiple projects in one place or keep metric history out of your main codebase.

Migrating data

When a new version of velocirepo changes the on-disk data format, it tracks this with a schema version number in velocirepo/data/.schema-version. Commands like fetch, query, and export will refuse to run against stale data:

Error: data schema is at version 0, but version 1 is required; run `velocirepo migrate` to update

To migrate your data to the latest schema:

velocirepo migrate

If you've copied in data from an older schema (e.g., merged data from another repository), some files may be at a different version than what .schema-version claims. Use --force to re-run all migrations from scratch:

velocirepo migrate --force

This is safe to run repeatedly — all migrations are idempotent.

Querying the data

The query command reads JSONL files directly using DuckDB and exposes these views:

View Description
metrics Unified time-series: all sources including aggregated events
indicators Derived growth rate and trend for daily metrics (28-day windows)
events Raw events with timestamp and tags (e.g., GitHub stars, forks, issues, PRs)
content Entity data from content providers (e.g., YouTube video metadata)
projects Project metadata from your config

Daily star counts

velocirepo query "
  SELECT project, date, value AS stars
  FROM metrics
  WHERE source = 'github' AND metric = 'daily_stars'
  ORDER BY date DESC
  LIMIT 5
"
┌──────────────────┬────────────┬───────┐
│     project      │    date    │ stars │
├──────────────────┼────────────┼───────┤
│ ggsql            │ 2026-06-22 │ 1     │
│ gt               │ 2026-06-22 │ 1     │
│ images-workbench │ 2026-06-22 │ 1     │
│ rmarkdown        │ 2026-06-22 │ 1     │
│ pointblank       │ 2026-06-22 │ 1     │
└──────────────────┴────────────┴───────┘

Total stars per project

velocirepo query "
  SELECT p.name, SUM(value) AS stars
  FROM metrics m
  JOIN projects p ON m.project = p.id
  WHERE m.source = 'github' AND m.metric = 'daily_stars'
  GROUP BY p.name
  ORDER BY stars DESC
  LIMIT 5
"
┌─────────────┬───────┐
│    name     │ stars │
├─────────────┼───────┤
│ ggplot2     │ 6877  │
│ cheatsheets │ 6360  │
│ shiny       │ 5655  │
│ Shiny for R │ 5600  │
│ Quarto      │ 5274  │
└─────────────┴───────┘

Monthly star activity using raw events

The events view gives you access to individual events when you need per-user or per-timestamp detail:

velocirepo query "
  SELECT date_trunc('month', datetime)::DATE AS month, COUNT(*) AS stars
  FROM events
  WHERE project = 'quarto' AND type = 'star'
  GROUP BY month
  ORDER BY month DESC
  LIMIT 5
"
┌────────────┬───────┐
│   month    │ stars │
├────────────┼───────┤
│ 2026-02-01 │ 40    │
│ 2026-01-01 │ 107   │
│ 2025-12-01 │ 91    │
│ 2025-11-01 │ 97    │
│ 2025-10-01 │ 85    │
└────────────┴───────┘

Top YouTube videos by views

velocirepo query "
  SELECT c.title, m.value AS views
  FROM metrics m
  JOIN content c ON m.tags->>'video_id' = c.id
  WHERE m.source = 'youtube' AND m.metric = 'total_views'
  ORDER BY m.value DESC
  LIMIT 5
"

Latest metrics across sources

velocirepo query "
  SELECT project, source, metric, date, value
  FROM metrics
  WHERE source != 'github'
  ORDER BY date DESC
  LIMIT 5
"
┌───────────────────┬─────────┬─────────────────┬────────────┬─────────┐
│      project      │ source  │     metric      │    date    │  value  │
├───────────────────┼─────────┼─────────────────┼────────────┼─────────┤
│ shiny-r           │ openvsx │ total_downloads │ 2026-06-22 │ 2404755 │
│ shiny-r           │ openvsx │ rating          │ 2026-06-22 │ 5       │
│ shiny-r           │ openvsx │ reviews         │ 2026-06-22 │ 2       │
│ pointblank-python │ pypi    │ daily_downloads │ 2026-06-22 │ 604     │
│ orbital-r         │ cran    │ daily_downloads │ 2026-06-22 │ 37      │
└───────────────────┴─────────┴─────────────────┴────────────┴─────────┘

Output formats

By default, results are printed as a table. Use --json, --csv, or --parquet for machine-readable output:

velocirepo query --csv "SELECT project, metric, value FROM metrics LIMIT 3"
velocirepo query --json "SELECT project, metric, value FROM metrics LIMIT 3"
velocirepo query --parquet "SELECT * FROM metrics" > metrics.parquet

The schema command shows all available columns:

velocirepo schema
┌───────────────┬──────────────┬───────────┐
│ TABLE         │ COLUMN       │ TYPE      │
├───────────────┼──────────────┼───────────┤
│ content       │ source       │ VARCHAR   │
│ content       │ target       │ VARCHAR   │
│ content       │ id           │ VARCHAR   │
│ content       │ title        │ VARCHAR   │
│ content       │ description  │ VARCHAR   │
│ content       │ published_at │ TIMESTAMP │
│ content       │ url          │ VARCHAR   │
│ content       │ duration     │ BIGINT    │
│ content       │ tags         │ JSON      │
│ content       │ type         │ VARCHAR   │
│ content       │ metadata     │ JSON      │
│ events        │ project      │ VARCHAR   │
│ events        │ source       │ VARCHAR   │
│ events        │ type         │ VARCHAR   │
│ events        │ target       │ VARCHAR   │
│ events        │ datetime     │ TIMESTAMP │
│ events        │ tags         │ JSON      │
│ indicators    │ project      │ VARCHAR   │
│ indicators    │ source       │ VARCHAR   │
│ indicators    │ target       │ VARCHAR   │
│ indicators    │ metric       │ VARCHAR   │
│ indicators    │ indicator    │ VARCHAR   │
│ indicators    │ date         │ DATE      │
│ indicators    │ value        │ DOUBLE    │
│ indicators    │ tags         │ JSON      │
│ metrics       │ project      │ VARCHAR   │
│ metrics       │ source       │ VARCHAR   │
│ metrics       │ target       │ VARCHAR   │
│ metrics       │ metric       │ VARCHAR   │
│ metrics       │ date         │ DATE      │
│ metrics       │ value        │ BIGINT    │
│ metrics       │ tags         │ JSON      │
│ projects      │ id           │ VARCHAR   │
│ projects      │ name         │ VARCHAR   │
│ projects      │ description  │ VARCHAR   │
│ projects      │ color        │ VARCHAR   │
│ projects      │ tags         │ VARCHAR[] │
│ projects      │ website      │ VARCHAR   │
│ projects      │ logo         │ VARCHAR   │
└───────────────┴──────────────┴───────────┘

Exporting data

Export metrics, events, and project metadata to Parquet or CSV for use in other tools:

velocirepo export ./out/

This writes one file per table:

  out/metrics.parquet (257 KB)
  out/events.parquet (2.9 MB)
  out/content.parquet (15 KB)
  out/indicators.parquet (42 KB)
  out/projects.parquet (2 KB)

Use --format csv for CSV output, and --source or --project to filter:

velocirepo export ./out/ --format csv
velocirepo export ./out/ --source github
velocirepo export ./out/ --project quarto

Using the data with other tools

velocirepo provides two ways to access your metrics data from external tools:

  1. DuckDB file — a persistent velocirepo/data/velocirepo.duckdb file with views over the raw JSONL data and a projects table. Open it directly from any tool that supports DuckDB.
  2. Parquet export — use velocirepo export ./out/ to write Parquet (or CSV) files that any data tool can read.

The DuckDB file is rebuilt automatically after every fetch and project mutation command. You can also rebuild it manually:

velocirepo build-db

Note: The DuckDB file uses relative paths, so external tools must open it from the data directory (or set DuckDB's working directory to it).

Tool compatibility

Tool / Package DuckDB file Parquet
DuckDB CLI Yes Yes
Python duckdb Yes Yes
Polars (Python/Rust) No Yes
pandas No Yes
Marimo Yes (via duckdb) Yes
R duckdb / DBI Yes Yes
R arrow No Yes
Observable / Evidence Yes Yes
Excel / Google Sheets No Yes (via CSV)

Examples

DuckDB CLI:

cd velocirepo/data
duckdb velocirepo.duckdb "SELECT project, SUM(value) AS stars FROM metrics WHERE metric = 'daily_stars' GROUP BY project ORDER BY stars DESC"

Python (duckdb):

import duckdb
import os

os.chdir("velocirepo/data")
con = duckdb.connect("velocirepo.duckdb", read_only=True)
df = con.sql("SELECT * FROM metrics WHERE source = 'pypi' ORDER BY date DESC LIMIT 10").df()

Polars (from Parquet export):

import polars as pl

metrics = pl.read_parquet("out/metrics.parquet")
stars = metrics.filter(pl.col("metric") == "daily_stars").group_by("project").agg(pl.col("value").sum())

Indicators

The indicators view computes derived signals from your daily metrics, giving you a sense of how fast a project is growing and in which direction it's heading. Indicators are computed using 28-day trailing windows and are available wherever you query data — via velocirepo query, the persistent .duckdb file, and Parquet exports.

Only metrics with a daily_ prefix are included (these represent per-day deltas like daily_stars, daily_downloads, daily_pageviews). Cumulative total_* metrics are excluded since growth rates on snapshots aren't meaningful.

Schema

Column Type Description
project VARCHAR Project ID
source VARCHAR Source name (github, pypi, etc.)
target VARCHAR Specific package, repo, or site being tracked
metric VARCHAR Underlying metric (e.g., daily_stars)
indicator VARCHAR Indicator name (growth_rate or trend)
date DATE Date of computation
value DOUBLE Computed value
tags JSON Optional metadata from the underlying metric

Growth rate

Measures how much activity increased or decreased compared to the prior period. Computed as:

growth_rate = (sum_last_28d - sum_prior_28d) / sum_prior_28d

A value of 0.15 means 15% more activity in the last 28 days compared to the 28 days before that. Negative values indicate declining activity.

velocirepo query "
  SELECT project, metric, date, ROUND(value, 3) AS growth_rate
  FROM indicators
  WHERE indicator = 'growth_rate'
    AND metric = 'daily_stars'
  ORDER BY date DESC
  LIMIT 5
"
┌──────────────┬─────────────┬────────────┬─────────────┐
│   project    │   metric    │    date    │ growth_rate │
├──────────────┼─────────────┼────────────┼─────────────┤
│ py-shiny     │ daily_stars │ 2026-06-22 │ 0.114       │
│ dplyr        │ daily_stars │ 2026-06-22 │ -0.182      │
│ plotnine     │ daily_stars │ 2026-06-22 │ -0.488      │
│ great-tables │ daily_stars │ 2026-06-22 │ -0.174      │
│ ggsql        │ daily_stars │ 2026-06-22 │ -0.875      │
└──────────────┴─────────────┴────────────┴─────────────┘

Trend

Measures the daily rate of change via linear regression over the trailing 28 days. The value represents units per day — for example, a trend of 3.2 on daily_stars means the project is gaining roughly 3.2 more stars per day than it was at the start of the window.

velocirepo query "
  SELECT project, metric, date, ROUND(value, 2) AS trend_per_day
  FROM indicators
  WHERE indicator = 'trend'
    AND metric = 'daily_downloads'
    AND project = 'plotnine'
  ORDER BY date DESC
  LIMIT 5
"
┌──────────┬─────────────────┬────────────┬───────────────┐
│ project  │     metric      │    date    │ trend_per_day │
├──────────┼─────────────────┼────────────┼───────────────┤
│ plotnine │ daily_downloads │ 2026-06-22 │ -140.39       │
│ plotnine │ daily_downloads │ 2026-06-21 │ -60.35        │
│ plotnine │ daily_downloads │ 2026-06-20 │ 135.05        │
│ plotnine │ daily_downloads │ 2026-06-19 │ 186.6         │
│ plotnine │ daily_downloads │ 2026-06-18 │ 112.38        │
└──────────┴─────────────────┴────────────┴───────────────┘

Querying indicators

You can join indicators with project metadata for richer views:

velocirepo query "
  SELECT p.name, i.metric, i.indicator, i.date, ROUND(i.value, 3) AS value
  FROM indicators i
  JOIN projects p ON i.project = p.id
  WHERE i.date = (SELECT MAX(date) FROM indicators)
  ORDER BY i.indicator, i.value DESC
  LIMIT 5
"
┌────────────┬─────────────────────┬─────────────┬────────────┬───────┐
│    name    │       metric        │  indicator  │    date    │ value │
├────────────┼─────────────────────┼─────────────┼────────────┼───────┤
│ great-docs │ daily_issues_closed │ growth_rate │ 2026-06-22 │ 5.143 │
│ mcp-repl   │ daily_prs_merged    │ growth_rate │ 2026-06-22 │ 3.143 │
│ mcp-repl   │ daily_prs_opened    │ growth_rate │ 2026-06-22 │ 2.815 │
│ great-docs │ daily_issues_opened │ growth_rate │ 2026-06-22 │ 1.647 │
│ Positron   │ daily_pr_comment    │ growth_rate │ 2026-06-22 │ 1.271 │
└────────────┴─────────────────────┴─────────────┴────────────┴───────┘

Custom indicators

You can define your own indicators in velocirepo.toml. Each indicator is a named TOML table with a description and a SQL query:

[indicators.weekly_momentum]
description = "7-day trailing sum"
query = """
  SELECT project, source, target, metric,
    '{{indicator_name}}' AS indicator, date,
    SUM(value) OVER w AS value,
    tags
  FROM metrics WHERE metric LIKE 'daily_%'
  WINDOW w AS (PARTITION BY project, source, target, metric, tags ORDER BY date ROWS 6 PRECEDING)
"""

The {{indicator_name}} placeholder is replaced with the TOML key at runtime (e.g., weekly_momentum).

Behavior: Custom indicators are added alongside the built-in defaults. To disable the defaults, set:

[settings]
include_default_indicators = false

To inspect the built-in defaults:

velocirepo show-indicators --defaults

Without --defaults, show-indicators prints all active indicators (defaults + custom). You can redirect to your config to use as a starting point:

velocirepo show-indicators --defaults >> velocirepo.toml

Generating badges

Generate shields.io-style SVG badges from your metrics data:

velocirepo badge stars -o stars.svg
velocirepo badge forks --project quarto -o forks.svg
velocirepo badge downloads --project ggplot2 -o downloads.svg

For custom metrics, provide a SQL query that returns a single value:

velocirepo badge custom \
  --label "contributors" \
  --query "SELECT COUNT(DISTINCT tags->>'user') AS value FROM events" \
  --color "#ea7233" \
  -o contributors.svg

Styles

Three styles are available via --style:

Style Description
flat (default) Subtle gradient, rounded corners
flat-square No gradient, sharp corners
plastic Heavy gradient, more rounded

Options

Flag Default Description
--project all Scope to a specific project
--style flat Badge style
--color preset-dependent Message background color (hex)
--label-color #555 Label background color
--label preset-dependent Override label text
--height style-dependent Badge height in pixels
--radius style-dependent Corner radius (0 = square)
-o stdout Output file path

Numbers are automatically formatted for readability (e.g., 5274 becomes 5.3k, 1500000 becomes 1.5M).

Views

Views are self-contained directories that produce dashboards, reports, or visualizations from your metrics data. Each view has a render.sh script as the contract — velocirepo handles discovery and orchestration, while rendering is delegated to whatever tools the view needs.

Structure

A view is any directory under views/ that contains a render.sh file:

views/
  weekly-stars/
    render.sh          # the render contract (executable)
    pyproject.toml     # Python dependencies (managed by uv)
    view.qmd           # the actual view file
  monthly-report/
    render.sh
    pyproject.toml
    app.py             # marimo notebook
  r-summary/
    render.sh
    view.R

Quick start

# Scaffold a Quarto view (creates directory with render.sh, view.qmd, pyproject.toml)
velocirepo add-view weekly-stars --framework quarto-python

# Install dependencies
velocirepo setup-views

# Render the view (rebuilds DuckDB, then runs render.sh)
velocirepo render-view weekly-stars

# Or start a live dev server (requires serve.sh in the view)
velocirepo serve-view weekly-stars

Supported frameworks

Framework Flag View file render.sh runs
Quarto (Python) -f quarto-python view.qmd uv run quarto render view.qmd
Quarto (R) -f quarto-r view.qmd quarto render view.qmd
Jupyter -f jupyter view.ipynb uv run jupyter nbconvert ...
Marimo -f marimo app.py uv run marimo export html app.py
R -f r view.R Rscript view.R
ggsql -f sql view.sql ggsql run view.sql

Data access

Views connect to velocirepo.duckdb by default (via a relative path embedded at scaffold time). The DB is rebuilt before every render, so views always see fresh data.

For views that need Parquet files instead, use --source parquet when scaffolding and call velocirepo export in the view's own render.sh.

Flags for add-view

Flag Description
-f, --framework Framework: quarto-python, quarto-r, jupyter, marimo, r, sql (required)
-s, --source Data source: duckdb (default) or parquet
--no-uv Skip pyproject.toml generation
--renv Scaffold renv for R views (-f r or -f quarto-r)

Rendering

velocirepo render-view weekly-stars  # render one view
velocirepo render-views              # render all views
velocirepo render-views reports      # render views matching a prefix

Setup and CI

# Install dependencies for all views (runs uv sync / renv::restore)
velocirepo setup-views

In GitHub Actions:

- name: Setup views
  run: velocirepo setup-views

- name: Render views
  run: velocirepo render-views

MCP server

velocirepo includes a built-in Model Context Protocol (MCP) server, allowing AI assistants like Claude to query your metrics, trigger fetches, and manage projects conversationally.

Starting the server

velocirepo mcp                          # stdio (for Claude Desktop / Claude Code)
velocirepo mcp --http 127.0.0.1:8080    # Streamable HTTP
velocirepo mcp --read-only              # Disable fetch/write tools

Claude Desktop configuration

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "velocirepo": {
      "command": "velocirepo",
      "args": ["mcp", "--config", "/path/to/velocirepo.toml"]
    }
  }
}

Claude Code configuration

Add to your project's .mcp.json:

{
  "mcpServers": {
    "velocirepo": {
      "command": "velocirepo",
      "args": ["mcp"]
    }
  }
}

Available tools

Tool Description
query Run SQL against metrics, events, content, projects views
schema Show all table columns and types
fetch Fetch from all configured sources
fetch_github Fetch GitHub events
fetch_traffic Fetch GitHub traffic
fetch_pypi Fetch PyPI downloads
fetch_cran Fetch CRAN downloads
fetch_homebrew Fetch Homebrew installs
fetch_plausible Fetch Plausible analytics
fetch_openvsx Fetch Open VSX metrics
fetch_youtube Fetch YouTube metrics
fetch_linkedin Fetch LinkedIn post metrics and content
list_projects List configured projects
show_project Show project details and fetch stats
add_project Add a project to the config
update_project Update project configuration
remove_project Remove a project
rename_project Rename a project ID
import_projects Bulk-import from GitHub org/user
validate_projects Check that source URLs are reachable
list_views List all views with framework and source
show_view Show view details
add_view Scaffold a new view
remove_view Remove a view
render_view Render a single view
render_views Render all or filtered views
badge Generate an SVG badge
export Export data to Parquet or CSV
migrate Migrate data to latest schema
version Show version info

Example prompts

Once connected, you can ask things like:

  • "Which project got the most stars this month?"
  • "Show me PyPI download trends for plotnine over the last 6 months"
  • "Fetch the latest metrics for all projects"
  • "Add a new project called 'my-lib' tracking pypi package my-lib and github owner/my-lib"
  • "Generate a stars badge for quarto"

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

velocirepo-0.7.0-py3-none-win_amd64.whl (18.1 MB view details)

Uploaded Python 3Windows x86-64

velocirepo-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (18.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

velocirepo-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (17.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

velocirepo-0.7.0-py3-none-macosx_11_0_x86_64.whl (17.6 MB view details)

Uploaded Python 3macOS 11.0+ x86-64

velocirepo-0.7.0-py3-none-macosx_11_0_arm64.whl (15.7 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file velocirepo-0.7.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: velocirepo-0.7.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 18.1 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for velocirepo-0.7.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 b1d15094eaa3e77a44228325caa8cf3b21ae959ddb784054e3aba28d03119eb1
MD5 bb2c888d991a1404455829e3ea45f924
BLAKE2b-256 0cebdb1e295d6ae277557487e2ed5a1bf58318fef5ee009170d150fe3e8e9784

See more details on using hashes here.

File details

Details for the file velocirepo-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: velocirepo-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 18.4 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for velocirepo-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 459e3ddfaa3d862cc5369b179be38355d76dc7f9da60d8a40f15a33d18395faf
MD5 0ffd484fd1df2e672bed5b57dc1bba8e
BLAKE2b-256 1077d1786135e9417b87a7269d159bcad0250ad34f3306f61b05a9b878babada

See more details on using hashes here.

File details

Details for the file velocirepo-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

  • Download URL: velocirepo-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
  • Upload date:
  • Size: 17.0 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for velocirepo-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6727e39026294682adc5a76cfdffa104be024ac57ba0d8366a2eb7662e63adbb
MD5 134606156a3d4238ea69f8e014239dec
BLAKE2b-256 c5a7804b91abeb8af9418d0321c8bad124dc57d623ab86397283a83caa449d66

See more details on using hashes here.

File details

Details for the file velocirepo-0.7.0-py3-none-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: velocirepo-0.7.0-py3-none-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 17.6 MB
  • Tags: Python 3, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for velocirepo-0.7.0-py3-none-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 8dd76415d9a068aefb0b6be12e4b2b2ecc81a13481676a6169e0469a1e18c0e5
MD5 dd48576444ee88cfdf080a57bc841aef
BLAKE2b-256 a0c790aa5f1c9158cd6cc14736b73bd55c2eec7277ace37e0cf0b4728f1521f6

See more details on using hashes here.

File details

Details for the file velocirepo-0.7.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: velocirepo-0.7.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 15.7 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for velocirepo-0.7.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 051ba349a06902a49f268458927132832b74eab07b8d264d5e4553295991d055
MD5 362cdb2b22c58020f369d9074d03d7a9
BLAKE2b-256 5be01d146582c7b1cca30be170b7effa20076422eb24c0028d0ac446acfee3b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page