node
javascript
openai
llm
(Alternates: typescript, npm, webdev)
Use a dashboard screenshot or a simple banner with:
"Track input/output LLM tokens in Node.js"
If you build with OpenAI, Anthropic, or any LLM API, you've probably wondered:
How many tokens did that request actually use?
Token usage drives cost, performance, and scaling. But in many Node.js apps, response.usage
gets logged once and forgotten.
I built ** all-llm-token-tracker** β a small npm package that tracks
npm: https://www.npmjs.com/package/all-llm-token-tracker
GitHub: https://github.com/rkanumetta/all-llm-token-tracker
Most integrations look like this:
const response = await openai.chat.completions.create({ ... });
console.log(response.usage); // logged, rarely stored
That works for debugging β not for production. You usually need:
Many existing tools bundle pricing engines, MCP servers, or heavy infra. Sometimes you just want clean token tracking.
all-llm-token-tracker
does one job well:
| Feature | Supported |
|---|---|
| Manual token recording | β |
| Auto-wrap LLM calls | β |
| OpenAI extractor | β |
| Anthropic extractor | β |
| Memory storage | β |
| File (JSON) storage | β |
| MongoDB storage | β |
| Query & summarize | β |
| Browser dashboard | β |
| Zero required deps | β |
Requirements: Node.js 18+
License: MIT
npm install all-llm-token-tracker
MongoDB storage (optional):
npm install all-llm-token-tracker mongodb
js
import { createTracker } from 'all-llm-token-tracker';
const tracker = createTracker({ storage: 'memory' });
const record = await tracker.record({
provider: 'openai',
model: 'gpt-4o-mini',
inputTokens: 120,
outputTokens: 45,
metadata: { userId: 'user-123' },
});
console.log(record.totalTokens); // 165
Each record gets a UUID, timestamp, and optional metadata.
Wrap your existing function β usage is recorded automatically:
import {
createTracker,
extractOpenAiUsage,
} from 'all-llm-token-tracker';
import OpenAI from 'openai';
const tracker = createTracker({
storage: 'file',
file: { filePath: './.llm-usage/usage.json' },
});
const openai = new OpenAI();
const { result, record } = await tracker.track(
() =>
openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: 'Hello!' }],
}),
{
provider: 'openai',
model: 'gpt-4o-mini',
extractUsage: extractOpenAiUsage,
metadata: { feature: 'chat' },
}
);
console.log(result.choices[0].message.content);
console.log(record.inputTokens, record.outputTokens);
What happens:
{ result, record }
backNo changes to your core LLM logic β just a wrapper.
import { extractAnthropicUsage } from 'all-llm-token-tracker';
await tracker.track(
() => anthropic.messages.create({
model: 'claude-3-5-sonnet-20241022',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello!' }],
}),
{
provider: 'anthropic',
model: 'claude-3-5-sonnet-20241022',
extractUsage: extractAnthropicUsage,
}
);
js
const tracker = createTracker({ storage: 'memory' });
js
const tracker = createTracker({
storage: 'file',
file: { filePath: './.llm-usage/usage.json' },
});
js
const tracker = createTracker({
storage: 'mongodb',
mongodb: {
uri: process.env.MONGODB_URI,
database: 'my_app',
collection: 'llm_token_usage',
},
});
// on shutdown
await tracker.close();
js
const calls = await tracker.getCalls({
provider: 'openai',
from: '2026-07-01',
limit: 100,
});
const summary = await tracker.getSummary();
/*
{
totalCalls: 42,
totalInputTokens: 12500,
totalOutputTokens: 3200,
totalTokens: 15700,
averageInputTokens: 297.6,
averageOutputTokens: 76.2,
averageTotalTokens: 373.8
}
*/
const byModel = await tracker.getSummaryByModel();
const byProvider = await tracker.getSummaryByProvider();
Every call is stored like this:
{
"id": "uuid",
"provider": "openai",
"model": "gpt-4o-mini",
"inputTokens": 120,
"outputTokens": 45,
"totalTokens": 165,
"timestamp": "2026-07-10T06:00:00.000Z",
"durationMs": 842,
"metadata": { "userId": "user-123" }
}
js
import { createUsageExtractor } from 'all-llm-token-tracker';
const extractMyProvider = createUsageExtractor((response) => ({
inputTokens: response.tokens.in,
outputTokens: response.tokens.out,
}));
Or plug in your own storage (Postgres, Redis, etc.):
import { createTracker, type StorageAdapter, type LlmCallRecord } from 'all-llm-token-tracker';
class PostgresStorage implements StorageAdapter {
async save(record: LlmCallRecord) { /* ... */ }
async find(query) { /* ... */ }
async count(query) { /* ... */ }
}
const tracker = createTracker({ storage: new PostgresStorage() });
The repo includes a simple dashboard to visualize input vs output tokens:
git clone https://github.com/rkanumetta/all-llm-token-tracker.git
cd all-llm-token-tracker
npm install
npm run example
npm run dashboard
You'll see:
npm install all-llm-token-tracker
Links:
If you find it useful, star the repo β and open an issue if you want support for another provider (Gemini, Mistral, etc.).
LLM token tracking doesn't need to be complicated. Wrap your API calls, store consistent records, query when you need insights.
Track input. Track output. Store it. Query it. Done.
What storage backend do you use for LLM observability β file, MongoDB, or something else? Drop a comment below.
node
, javascript
, openai
, llm
Paste this as the first line under the title if DEV shows a preview/subtitle field:
A lightweight Node.js npm package to track input/output tokens for OpenAI, Anthropic, and custom LLM providers β with memory, file, and MongoDB storage plus a browser dashboard.