Getting Started
This page gets a basic application working with the smallest possible integration.
1. Install The Library
Install from GitHub:
pnpm add github:07rjain/LLMlibraryThe package name you import is still unified-llm-client.
If you are working locally against a checked-out copy, you can also install with:
pnpm add file:../LLMlibrary2. Add Environment Variables
Add a .env file in the consuming project, not in this repository.
OPENAI_API_KEY=
OPENAI_ORG_ID=
OPENAI_PROJECT_ID=
ANTHROPIC_API_KEY=
GEMINI_API_KEY=
DATABASE_URL=You only need the keys for the providers you actually use.
DATABASE_URL is optional unless you want Postgres-backed session persistence or usage logging.
3. Create A Client
The simplest entry point is LLMClient.fromEnv().
import { LLMClient } from 'unified-llm-client';
const client = LLMClient.fromEnv({
defaultModel: 'gpt-4o',
});defaultModel becomes the fallback when an individual request does not pass model.
If you want to avoid environment variables, you can pass credentials directly:
import { LLMClient } from 'unified-llm-client';
const client = new LLMClient({
defaultModel: 'gpt-4o',
openaiApiKey: process.env.OPENAI_API_KEY,
});4. Send Your First Request
Use complete() for non-streaming requests.
const response = await client.complete({
messages: [
{
role: 'user',
content: 'Explain what this library does in one sentence.',
},
],
});
console.log(response.text);
console.log(response.model);
console.log(response.provider);
console.log(response.usage.costUSD);The response is provider-agnostic. The most commonly used fields are:
response.textThe plain text output assembled from the assistant messageresponse.contentThe canonical structured content partsresponse.toolCallsAny tool requests emitted by the modelresponse.finishReasonWhy the generation endedresponse.usageInput tokens, output tokens, cached tokens, and estimated cost
For numeric operations, use response.usage.costUSD. response.usage.cost is the formatted display string.
5. Override Model Or Provider Per Request
You can keep one shared client and choose a different route on specific calls.
const response = await client.complete({
model: 'gpt-4o-mini',
provider: 'openai',
messages: [{ role: 'user', content: 'Summarise this in five words.' }],
});If you pass a provider without configuring its API key, the library throws an AuthenticationError.
6. Use A System Prompt
Pass system when you want a top-level instruction without manually building a system message into messages.
const response = await client.complete({
system: 'You are concise, direct, and operational.',
messages: [{ role: 'user', content: 'Write a standup update.' }],
});7. Inspect The Model Registry
The client exposes a registry so your application can inspect or override model metadata.
const knownModels = client.models.list();
const modelInfo = client.models.get('gpt-4o');
console.log(knownModels.length);
console.log(modelInfo?.supportsStreaming);
console.log(modelInfo?.supportsTools);This is useful when you want to expose model choices in an admin UI or enforce capability checks before sending a request.
8. Discover Live Provider Models
If you need the provider's current remote catalog instead of the checked-in registry, call client.models.listRemote({ provider }).
const remoteOpenAIModels = await client.models.listRemote({
provider: 'openai',
});
console.log(remoteOpenAIModels[0]?.id);
console.log(remoteOpenAIModels[0]?.ownedBy);This is discovery-only. It does not automatically make newly discovered models routable through complete(), stream(), speak(), or transcribe(). If you want to use an unshipped model with this library today, register it explicitly with client.models.register(...) first.
9. Use Speech APIs
OpenAI batch text-to-speech and speech-to-text use separate methods.
const speech = await client.speak({
input: 'Your appointment is confirmed for 10 AM.',
model: 'gpt-4o-mini-tts',
voice: 'alloy',
format: 'mp3',
estimatedOutputSeconds: 4,
});
const transcript = await client.transcribe({
input: {
data: audioBase64,
filename: 'call.wav',
mediaType: 'audio/wav',
},
inputAudioSeconds: 42,
model: 'gpt-4o-mini-transcribe',
});
console.log(speech.audio);
console.log(transcript.text);
console.log(speech.usage?.costUSD);Speech usage uses different units from text generation, including audio seconds and characters. Use usage.costUSD for numeric operations and usage.cost only as a formatted display string. See Speech for the full guide.
Common Import Patterns
Import from the root package when possible:
import {
LLMClient,
InMemorySessionStore,
PostgresSessionStore,
createSessionApi,
defineTool,
} from 'unified-llm-client';Use subpath imports only when you want a narrower surface:
import { OpenAIAdapter } from 'unified-llm-client/providers/openai';
import { calcCostUSD, estimateTokens } from 'unified-llm-client/utils';Common Startup Errors
- Missing model Set
defaultModelon the client or passmodelon the request. - Missing provider credentials Add the matching provider key in the consuming project's environment.
- Wrong import name The package is installed from
LLMlibrary, but the import id isunified-llm-client. - Expecting automatic persistence without a store Persistence only happens when the client has a session store. If
DATABASE_URLis present,LLMClient.fromEnv()auto-wiresPostgresSessionStorefor conversations.
Next Step
If the first complete() call works, move to Completions And Streaming.