Skip to main content

Overview

The data loader module provides functions for loading and parsing Claude Code usage data from JSONL files stored in Claude data directories. It handles data aggregation for daily, monthly, weekly, session-based, and session block reporting.

Core Functions

getClaudePaths()

Get Claude data directories to search for usage data.
returns
string[]
required
Array of valid Claude data directory paths
Behavior:
  • When CLAUDE_CONFIG_DIR is set: uses only those paths
  • When not set: uses default paths (~/.config/claude and ~/.claude)
  • Throws error if no valid directories found
import { getClaudePaths } from 'ccusage/data-loader';

const paths = getClaudePaths();
console.log(paths);
// ['/home/user/.config/claude', '/home/user/.claude']

extractProjectFromPath()

Extract project name from Claude JSONL file path.
jsonlPath
string
required
Absolute path to JSONL file
returns
string
Project name extracted from path, or “unknown” if malformed
import { extractProjectFromPath } from 'ccusage/data-loader';

const project = extractProjectFromPath(
  '/home/user/.claude/projects/my-app/session-123.jsonl'
);
console.log(project); // "my-app"

loadDailyUsageData()

Loads and aggregates Claude usage data by day.
export async function loadDailyUsageData(
  options?: LoadOptions
): Promise<DailyUsage[]>
options
LoadOptions
Configuration for loading and filtering data
returns
Promise<DailyUsage[]>
Array of daily usage summaries sorted by date
LoadOptions:
claudePath
string
Custom path to Claude data directory
mode
'auto' | 'calculate' | 'display'
Cost calculation mode (default: ‘auto’)
order
'asc' | 'desc'
Sort order for dates (default: ‘desc’)
offline
boolean
Use offline mode for pricing (default: false)
groupByProject
boolean
Group data by project instead of aggregating (default: false)
project
string
Filter to specific project name
since
string
Start date filter (YYYYMMDD format)
until
string
End date filter (YYYYMMDD format)
timezone
string
Timezone for date grouping (e.g., ‘UTC’, ‘America/New_York’)
locale
string
Locale for date/time formatting (e.g., ‘en-US’, ‘ja-JP’)
DailyUsage Type:
date
string
Date in YYYY-MM-DD format
inputTokens
number
Total input tokens for the day
outputTokens
number
Total output tokens for the day
cacheCreationTokens
number
Total cache creation tokens
cacheReadTokens
number
Total cache read tokens
totalCost
number
Total cost in USD
modelsUsed
string[]
Array of unique model names used
modelBreakdowns
ModelBreakdown[]
Per-model usage breakdowns
project
string
Project name (when groupByProject is enabled)
import { loadDailyUsageData } from 'ccusage/data-loader';

const dailyData = await loadDailyUsageData({
  since: '20240101',
  until: '20240131',
  mode: 'auto',
  order: 'desc'
});

for (const day of dailyData) {
  console.log(`${day.date}: $${day.totalCost.toFixed(4)}`);
}

loadMonthlyUsageData()

Loads and aggregates Claude usage data by month.
export async function loadMonthlyUsageData(
  options?: LoadOptions
): Promise<MonthlyUsage[]>
options
LoadOptions
Configuration for loading and filtering data
returns
Promise<MonthlyUsage[]>
Array of monthly usage summaries sorted by month
MonthlyUsage Type:
month
string
Month in YYYY-MM format
inputTokens
number
Total input tokens for the month
outputTokens
number
Total output tokens for the month
cacheCreationTokens
number
Total cache creation tokens
cacheReadTokens
number
Total cache read tokens
totalCost
number
Total cost in USD
modelsUsed
string[]
Array of unique model names used
modelBreakdowns
ModelBreakdown[]
Per-model usage breakdowns
project
string
Project name (when groupByProject is enabled)
import { loadMonthlyUsageData } from 'ccusage/data-loader';

const monthlyData = await loadMonthlyUsageData({
  mode: 'calculate',
  order: 'desc'
});

for (const month of monthlyData) {
  console.log(`${month.month}: $${month.totalCost.toFixed(2)}`);
}

loadWeeklyUsageData()

Loads and aggregates Claude usage data by week.
export async function loadWeeklyUsageData(
  options?: LoadOptions
): Promise<WeeklyUsage[]>
options
LoadOptions
Configuration including week start day
returns
Promise<WeeklyUsage[]>
Array of weekly usage summaries sorted by week
Additional Option:
startOfWeek
WeekDay
Start of week for weekly aggregation (e.g., ‘sunday’, ‘monday’)
WeeklyUsage Type:
week
string
Week start date in YYYY-MM-DD format
inputTokens
number
Total input tokens for the week
outputTokens
number
Total output tokens for the week
cacheCreationTokens
number
Total cache creation tokens
cacheReadTokens
number
Total cache read tokens
totalCost
number
Total cost in USD
modelsUsed
string[]
Array of unique model names used
modelBreakdowns
ModelBreakdown[]
Per-model usage breakdowns
import { loadWeeklyUsageData } from 'ccusage/data-loader';

const weeklyData = await loadWeeklyUsageData({
  startOfWeek: 'monday',
  order: 'desc'
});

for (const week of weeklyData) {
  console.log(`Week of ${week.week}: $${week.totalCost.toFixed(2)}`);
}

loadSessionData()

Loads and aggregates Claude usage data by session.
export async function loadSessionData(
  options?: LoadOptions
): Promise<SessionUsage[]>
options
LoadOptions
Configuration for loading and filtering data
returns
Promise<SessionUsage[]>
Array of session usage summaries sorted by last activity
SessionUsage Type:
sessionId
string
Unique session identifier
projectPath
string
Project path for the session
inputTokens
number
Total input tokens for the session
outputTokens
number
Total output tokens for the session
cacheCreationTokens
number
Total cache creation tokens
cacheReadTokens
number
Total cache read tokens
totalCost
number
Total cost in USD
lastActivity
string
Date of last activity (YYYY-MM-DD)
versions
string[]
Claude Code versions used in session
modelsUsed
string[]
Array of unique model names used
modelBreakdowns
ModelBreakdown[]
Per-model usage breakdowns
import { loadSessionData } from 'ccusage/data-loader';

const sessions = await loadSessionData({
  order: 'desc'
});

for (const session of sessions) {
  console.log(`${session.projectPath} (${session.sessionId})`);
  console.log(`  Cost: $${session.totalCost.toFixed(4)}`);
  console.log(`  Last Activity: ${session.lastActivity}`);
}

loadSessionUsageById()

Load usage data for a specific session by sessionId.
export async function loadSessionUsageById(
  sessionId: string,
  options?: { mode?: CostMode; offline?: boolean }
): Promise<{ totalCost: number; entries: UsageData[] } | null>
sessionId
string
required
The session ID to load data for (matches JSONL filename)
options.mode
'auto' | 'calculate' | 'display'
Cost calculation mode (default: ‘auto’)
options.offline
boolean
Use offline pricing data (default: false)
returns
Promise<object | null>
Usage data for the session or null if not found
totalCost
number
Total cost for the session in USD
entries
UsageData[]
Array of raw usage data entries
import { loadSessionUsageById } from 'ccusage/data-loader';

const sessionData = await loadSessionUsageById('session-123', {
  mode: 'auto'
});

if (sessionData) {
  console.log(`Total cost: $${sessionData.totalCost.toFixed(4)}`);
  console.log(`Number of entries: ${sessionData.entries.length}`);
} else {
  console.log('Session not found');
}

loadSessionBlockData()

Loads usage data organized into session blocks (5-hour billing periods).
export async function loadSessionBlockData(
  options?: LoadOptions
): Promise<SessionBlock[]>
options
LoadOptions
Configuration including session duration
returns
Promise<SessionBlock[]>
Array of session blocks with usage and cost information
Additional Option:
sessionDurationHours
number
Session block duration in hours (default: 5)
SessionBlock Type:
startTime
Date
Block start time
endTime
Date
Block end time
inputTokens
number
Total input tokens in block
outputTokens
number
Total output tokens in block
cacheCreationTokens
number
Total cache creation tokens
cacheReadTokens
number
Total cache read tokens
totalCost
number
Total cost in USD
usageLimitResetTime
Date
Time when usage limit resets
import { loadSessionBlockData } from 'ccusage/data-loader';

const blocks = await loadSessionBlockData({
  sessionDurationHours: 5,
  order: 'desc'
});

for (const block of blocks) {
  console.log(`Block: ${block.startTime.toISOString()}`);
  console.log(`  Cost: $${block.totalCost.toFixed(4)}`);
  console.log(`  Tokens: ${block.inputTokens + block.outputTokens}`);
}

calculateContextTokens()

Calculate context tokens from transcript file.
export async function calculateContextTokens(
  transcriptPath: string,
  modelId?: string,
  offline?: boolean
): Promise<{
  inputTokens: number;
  percentage: number;
  contextLimit: number;
} | null>
transcriptPath
string
required
Path to the transcript JSONL file
modelId
string
Model identifier for context limit lookup
offline
boolean
Use offline mode (default: false)
returns
Promise<object | null>
Context token information or null if unavailable
inputTokens
number
Total input tokens used
percentage
number
Percentage of context limit used (0-100)
contextLimit
number
Model’s context limit
import { calculateContextTokens } from 'ccusage/data-loader';

const context = await calculateContextTokens(
  '/path/to/transcript.jsonl',
  'claude-sonnet-4-20250514'
);

if (context) {
  console.log(`Context: ${context.percentage}% (${context.inputTokens}/${context.contextLimit})`);
}

Utility Functions

createUniqueHash()

Create a unique identifier for deduplication using message ID and request ID.
export function createUniqueHash(data: UsageData): string | null
data
UsageData
required
Usage data entry
returns
string | null
Hash string or null if IDs are missing

getEarliestTimestamp()

Extract the earliest timestamp from a JSONL file.
export async function getEarliestTimestamp(
  filePath: string
): Promise<Date | null>
filePath
string
required
Path to JSONL file
returns
Promise<Date | null>
Earliest timestamp or null if not found

sortFilesByTimestamp()

Sort files by their earliest timestamp.
export async function sortFilesByTimestamp(
  files: string[]
): Promise<string[]>
files
string[]
required
Array of file paths
returns
Promise<string[]>
Sorted array of file paths (oldest first)

globUsageFiles()

Glob files from multiple Claude paths in parallel.
export async function globUsageFiles(
  claudePaths: string[]
): Promise<GlobResult[]>
claudePaths
string[]
required
Array of Claude base paths
returns
Promise<GlobResult[]>
Array of file paths with their base directories
GlobResult Type:
file
string
Absolute file path
baseDir
string
Base directory path

Types

UsageData

Type definition for Claude usage data entries from JSONL files.
type UsageData = {
  timestamp: string;
  sessionId?: string;
  version?: string;
  message: {
    usage: {
      input_tokens: number;
      output_tokens: number;
      cache_creation_input_tokens?: number;
      cache_read_input_tokens?: number;
    };
    model?: string;
    id?: string;
    content?: Array<{ text?: string }>;
  };
  costUSD?: number;
  requestId?: string;
  isApiErrorMessage?: boolean;
};

ModelBreakdown

Type definition for model-specific usage breakdown.
type ModelBreakdown = {
  modelName: string;
  inputTokens: number;
  outputTokens: number;
  cacheCreationTokens: number;
  cacheReadTokens: number;
  cost: number;
};

Cost Calculation Modes

auto (Default)

Uses pre-calculated costUSD when available, otherwise calculates from tokens using model pricing.

calculate

Always calculates costs from token counts using model pricing, ignoring costUSD.

display

Always uses pre-calculated costUSD values, shows 0 for missing costs.

Date Filtering

All date filters use YYYYMMDD format:
const data = await loadDailyUsageData({
  since: '20240101',  // January 1, 2024
  until: '20240131'   // January 31, 2024
});

Environment Variables

CLAUDE_CONFIG_DIR

Custom Claude data directory paths (comma-separated):
export CLAUDE_CONFIG_DIR="/path/to/claude1,/path/to/claude2"
When not set, uses default paths:
  • ~/.config/claude/projects/
  • ~/.claude/projects/

Build docs developers (and LLMs) love