mrkeyoor.com_
Sat 19 Sept 15:53 UTC
npmAI / MLupdated 19 Sept 2026

ollama review

Ollama 0.6.3 is the official JavaScript client for an Ollama server. It sends typed requests for chat, text generation, embeddings, model pulls, tool calls, model inspection, and web search; it does not load or run a model inside your Node process. The current release adds token log probabilities and a version() call for checking the server. Our package test found bundled TypeScript declarations and working require() and ESM import paths, but the documented browser entry did not survive our esbuild browser-bundle test.

Verdict

Ollama 0.6.3 installed in 0.8 seconds and used 1 MB in our sandbox, with bundled types, both require() and ESM import support, and 0 audit findings. Install it for a Node service that already depends on Ollama; choose a provider-neutral client if Ollama is only one possible backend, and do not assume its browser entry will bundle because ours failed.

We installed it

Lab card: what happened when we installed ollamaScreenshot of ollama documentation
Install✓ · 0.8s2 packages on disk · 1 MB
ImportESM import works · require() works · CommonJS package with exports map
Browsern/acould not be bundled for the browser (Node-only code, most likely)
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does ollama install cleanly?

Yes. In a fresh container with an empty cache, npm install ollama finished in 0.8s, leaving 2 packages and 1 MB on disk. npm audit reported no known vulnerabilities.

Can ollama run in a browser?

Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.

Does ollama work with both ESM and CommonJS?

Yes. Both import 'ollama' and require('ollama') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does ollama include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

ollama or openai: which should you use?

openai: Use it when the application targets OpenAI's hosted API and needs that service's full request and response surface. Ollama 0.6.3 installed in 0.8 seconds and used 1 MB in our sandbox, with bundled types, both require() and ESM import support, and 0 audit findings.

When should you not use ollama?

You need inference inside the Node process; this package only calls an Ollama server, while node-llama-cpp embeds a llama.cpp runtime

API stability3/5Ollama 0.6.3 exposes typed overloads for streamed and non-streamed chat, generation, pulls, and model creation, so TypeScript catches the changed return shape when stream is true. The package is still on a 0.x release line, and its surface follows the server. Version 0.6.3 added logprobs and version(), while 0.6.0 added webSearch() and webFetch(); users should check client and server support before adopting newer request fields.
Docs4/5The 0.6.3 README documents every public method, request fields, streaming return types, custom hosts and headers, cloud authentication, and the fact that abort() affects every stream on one client. It also states that create() does not support files. An examples directory covers common flows. There is no versioned documentation site or migration guide, and the browser section is only an import line despite the build and cross-origin questions that browser users must solve.
Maintenance3/5The official ollama/ollama-js repository had 4355 stars and 84 open issues and pull requests when checked, and its latest push was 2026-02-18. npm 0.6.3 was published on 2025-11-13 after releases that added web methods, fixed streaming chunk boundaries, and added server-version support. The gap since the last package release is worth watching because the client API follows features exposed by the separately released Ollama server.
Ecosystem4/5npm recorded 635516 downloads for the week ending 2026-08-24, and this is the client maintained under the Ollama GitHub organization. It covers chat, generation, embeddings, model lifecycle calls, tools, cloud models, and Ollama web search without a third-party adapter. That reach ends at the Ollama protocol: applications that need several model providers still need another abstraction, and the package does not replace the server or its model library.

Use it if

  • Your application already runs an Ollama server and needs typed chat, generation, embedding, and model-management calls from JavaScript
  • You need streamed local-model output as an AsyncGenerator that fits naturally into a Node response loop
  • You want to inspect, pull, copy, or delete models through the same client used for inference
  • You use Ollama cloud models or web search and can supply an Ollama account key through a custom client
Skip it if

Setup reality

Our clean install of ollama 0.6.3 on Node 22 succeeded in 0.8 seconds and left 2 packages using 1 MB on disk. npm audit reported 0 known vulnerabilities across every severity. The package has 1 direct dependency, no peer dependencies, an exports map, and 204 KB unpacked. It is a CommonJS package with working require() and ESM import paths in our sandbox, and its TypeScript declarations are bundled.

The client alone cannot answer a prompt. A local setup needs the separate Ollama server running at the default http://127.0.0.1:11434 address and a model pulled before chat() or generate() can work. A remote server goes in new Ollama({ host, headers }). Direct Ollama cloud calls use https://ollama.com plus an OLLAMA_API_KEY bearer token, while webSearch() also requires an Ollama account and key.

Model state belongs to the server, so the 1 MB npm install says nothing about model storage or inference memory. pull() can return streamed progress while the server downloads a model. list() reports models stored on disk, ps() reports models currently loaded, and keep_alive accepts seconds or duration strings such as '30m'. Pick that value with the server's available memory in mind instead of pinning every model indefinitely.

Streaming changes the return value to an AsyncGenerator and errors surface while the for-await loop is consuming it. abort() stops all active streams on one Ollama client, so independent request cancellation needs separate client instances. The README provides an ollama/browser import, but our esbuild browser bundle failed. Treat browser delivery as unverified on your toolchain and keep server credentials out of frontend code.

Patterns

Send a chat message chat-basic

import ollama from 'ollama'

const response = await ollama.chat({
  model: 'llama3.1',
  messages: [{ role: 'user', content: 'Explain event loops in one paragraph.' }],
})

console.log(response.message.content)

The default client calls http://127.0.0.1:11434. A connection error at that address means the separate Ollama server is unavailable.

Stream a chat response chat-streaming

const stream = await ollama.chat({
  model: 'llama3.1',
  messages: [{ role: 'user', content: 'Write a short release note.' }],
  stream: true,
})

for await (const part of stream) {
  process.stdout.write(part.message.content)
}

stream: true returns an AsyncGenerator instead of a completed ChatResponse. Network and server errors can therefore arrive inside the for-await loop.

Connect to a remote or cloud host custom-host-auth

import { Ollama } from 'ollama'

const client = new Ollama({
  host: 'https://ollama.com',
  headers: {
    Authorization: `Bearer ${process.env.OLLAMA_API_KEY}`,
  },
})

Ollama cloud uses https://ollama.com with a bearer key. Custom headers are sent on every request made by this client instance.

Generate text from one prompt generate-prompt

const result = await ollama.generate({
  model: 'llama3.1',
  system: 'Answer in one sentence.',
  prompt: 'Why should a server set request timeouts?',
})

console.log(result.response)

generate() puts generated text in response, while chat() puts it in message.content. The two result shapes are not interchangeable.

Embed several documents create-embeddings

const result = await ollama.embed({
  model: 'nomic-embed-text',
  input: ['first document', 'second document'],
})

console.log(result.embeddings.length)

embed() accepts one string or an array and returns embeddings as an array of vectors. The requested embedding model must already be available to the server.

Offer a function to the model call-tool

const response = await ollama.chat({
  model: 'llama3.1',
  messages: [{ role: 'user', content: 'What is the weather in Delhi?' }],
  tools: [{
    type: 'function',
    function: {
      name: 'get_weather',
      description: 'Get weather for a city',
      parameters: {
        type: 'object',
        properties: { city: { type: 'string' } },
        required: ['city'],
      },
    },
  }],
})

for (const call of response.message.tool_calls ?? []) {
  console.log(call.function.name, call.function.arguments)
}

Tool support depends on the selected model, and tool_calls can be absent. Your code executes the function and supplies its result in a later message.

Send an image with a message chat-with-image

import { readFile } from 'node:fs/promises'

const image = await readFile('photo.jpg')
const response = await ollama.chat({
  model: 'llava',
  messages: [{
    role: 'user',
    content: 'Describe this image.',
    images: [image],
  }],
})

Node accepts image bytes, base64 text, or a file path through its image encoder. The selected model must support image input.

Report model pull progress pull-model

const progress = await ollama.pull({
  model: 'llama3.1',
  stream: true,
})

for await (const part of progress) {
  if (part.total && part.completed) {
    console.log(part.status, `${Math.round(part.completed / part.total * 100)}%`)
  }
}

A streamed pull reports server-side download progress. Keep the loop running until the server finishes or throws an error.

Distinguish stored and loaded models inspect-models

const stored = await ollama.list()
const running = await ollama.ps()

console.log('stored', stored.models.map((model) => model.name))
console.log('loaded', running.models.map((model) => model.name))

list() returns models stored by the server, while ps() returns models currently loaded into memory. Their model arrays answer different operational questions.

Request JSON output request-json

const response = await ollama.chat({
  model: 'llama3.1',
  format: 'json',
  messages: [{
    role: 'user',
    content: 'Return JSON with a string field named summary.',
  }],
})

const data = JSON.parse(response.message.content)

format: 'json' requests JSON output, but application code should still parse and validate the returned fields before using them.

Cancel one isolated stream cancel-stream

import { Ollama } from 'ollama'

const requestClient = new Ollama()
const timer = setTimeout(() => requestClient.abort(), 5000)

try {
  const stream = await requestClient.generate({
    model: 'llama3.1',
    prompt: 'Write a long explanation.',
    stream: true,
  })
  for await (const part of stream) process.stdout.write(part.response)
} finally {
  clearTimeout(timer)
}

abort() cancels every active stream on its client instance. One client per cancellable request prevents a timeout from stopping unrelated generations.

Read the Ollama server version check-server-version

const { version } = await ollama.version()
console.log(`Ollama server ${version}`)

version() was added in client 0.6.3 and reports the server version. Use it when a request field depends on a newer server release.

Alternatives

PackageRegistryPick it when
openainpmUse it when the application targets OpenAI's hosted API and needs that service's full request and response surface.
ainpmUse the Vercel AI SDK when provider switching and framework UI helpers matter more than direct Ollama model-management methods.
node-llama-cppnpmUse it when local llama.cpp inference must run inside the Node process without a separate Ollama daemon.

More ai / ml guides

openai · mcp · huggingface-hub · @modelcontextprotocol/sdk · scikit-learn · tiktoken · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.