---
title: TypeScript Client — Quickstart
nextjs:
  metadata:
    title: TypeScript Client — Quickstart
    description: Connect to TerminusDB from TypeScript. Branch, edit, diff, and merge documents using the terminusdb npm client.
    keywords: terminusdb, branch, client, connect, connection, diff, document, javascript
    openGraph:
      images: https://assets.terminusdb.com/docs/technical-documentation-terminuscms-og.png
    alternates:
      canonical: https://terminusdb.com/docs/connect-with-the-javascript-client/
tags:
  - typescript
  - how-to
  - beginner
---

{% callout type="note" %}
**What you'll achieve**
By the end of this guide, you will have established a connection to TerminusDB using the JavaScript client.
{% /callout %}

{% callout type="note" %}
This guide uses **TypeScript**. Also available in [Python](/docs/connect-with-python-client/) · [Rust](/docs/rust-client-quickstart/)
{% /callout %}

## Prerequisites

- TerminusDB running locally ([Install guide →](/docs/install-terminusdb-as-a-docker-container))
- Node.js 20+ installed
- A terminal

If you haven't run the [curl quickstart](/docs/get-started/) yet, do that first — it takes 5 minutes and introduces the branch/diff/merge concepts this guide builds on.

{% callout type="warning" title="TerminusDB must be running" %}
This guide assumes TerminusDB is running on `localhost:6363`. If you have trouble connecting, see [Troubleshooting Connection Failures](/docs/troubleshooting-connection) and [Authentication Errors](/docs/troubleshooting-auth).
{% /callout %}

## Install the client

```bash
mkdir my-terminusdb-app && cd my-terminusdb-app
npm init -y
npm install terminusdb
```

Create a file called `index.ts`. You will build it up step by step below, or copy the [complete file](#the-complete-indexts) at the end.

## Connect to TerminusDB

```typescript test-example id="ts-quickstart-connect" file="examples/ts-quickstart-connect.example.ts"
```

**What you should see:** A server info object with version and storage details. If you see a connection error, check that Docker is running and TerminusDB is on port 6363.

## Create a database and insert a document

No schema needed — insert any JSON document with `raw_json: true` and give it a human-readable ID:

```typescript test-example id="ts-quickstart-create-db" fixture="docs-test" file="examples/ts-quickstart-create-db.example.ts"
```

**What you should see:** `["terminusdb:///data/jane"]`. The `@id` gives the document a stable, human-readable identifier you choose. Schema comes later when you are ready.

## Create a branch

Just like `git branch`, this creates an isolated copy of your data:

```typescript test-example id="ts-quickstart-branch" file="examples/ts-quickstart-branch.example.ts"
```

**What you should see:** `Now on branch: feature`

Everything you do now happens on `feature` — main is untouched.

## Edit the document on the branch

```typescript test-example id="ts-quickstart-edit" file="examples/ts-quickstart-edit.example.ts"
```

**What you should see:** The document retrieved, then confirmation of the update. The change only exists on `feature` — `main` still has the original email.

## See the diff

This is the moment. TerminusDB can show you exactly what changed between branches — structurally, field by field:

```typescript test-example id="ts-quickstart-diff" file="examples/ts-quickstart-diff.example.ts"
```

**What you should see:**

```json
[
  {
    "@id": "terminusdb:///data/jane",
    "email": { "@op": "SwapValue", "@before": "jane@example.com", "@after": "jane.smith@company.com" }
  }
]
```

{% callout type="note" %}
**What just happened?**
TerminusDB computed a **structural diff** — not a line-by-line text diff, but semantic operations (`SwapValue`) that know exactly which fields changed, what the old values were, and what the new values are. This patch can be applied, reversed, or composed with other patches.
{% /callout %}

## Merge the branch

Bring the changes back to `main`:

```typescript test-example id="ts-quickstart-merge" file="examples/ts-quickstart-merge.example.ts"
```

**What you should see:** `Merged feature into main`

## Verify the merge

Confirm the changes are now on `main`:

```typescript test-example id="ts-quickstart-verify" file="examples/ts-quickstart-verify.example.ts"
```

**What you should see:** Jane Smith with `jane.smith@company.com` — the changes from the feature branch are now on `main`.

## What just happened?

You just used your database like a git repository:

1. **Branched** — created an isolated workspace (`feature`) without copying data
2. **Edited** — made changes that only exist on that branch
3. **Diffed** — asked TerminusDB to show exactly what changed, field by field
4. **Merged** — brought changes back to `main` cleanly

This is the core workflow of TerminusDB. Every change is a commit. Every prior state is recoverable. Multiple branches can exist simultaneously — for testing, staging, feature development, or collaboration.

## The complete `index.ts`

Run with `npx tsx index.ts`:

```typescript
import TerminusClient from "terminusdb"

async function main() {
  // 1. Connect
  const client = new TerminusClient.WOQLClient("http://localhost:6363", {
    user: "admin",
    organization: "admin",
    key: "root",
  })

  // 2. Create database + insert document (no schema)
  await client.createDatabase("MyDatabase", {
    label: "My Database",
    comment: "TypeScript quickstart",
    schema: false,
  })

  const result = await client.addDocument(
    { "@id": "terminusdb:///data/jane", name: "Jane Smith", email: "jane@example.com", age: 30 },
    { raw_json: true },
  )
  console.log("Document created:", result)

  // 3. Branch
  await client.branch("feature")
  client.checkout("feature")
  console.log("Now on branch:", client.checkout())

  // 4. Edit on branch
  const person = await client.getDocument({ id: "terminusdb:///data/jane", as_list: true })

  await client.updateDocument(
    { "@id": "terminusdb:///data/jane", name: "Jane Smith", email: "jane.smith@company.com", age: 30 },
    { raw_json: true },
    "",
    "Updated Jane's email",
  )
  console.log("Document updated on feature branch")

  // 5. See the diff
  const diff = await client.getVersionDiff("main", "feature")
  console.log("\nChanges between main and feature:")
  console.log(JSON.stringify(diff, null, 2))

  // 6. Merge
  client.checkout("main")
  await client.rebase({
    rebase_from: "admin/MyDatabase/local/branch/feature",
    message: "Merge feature: updated Jane's email",
  })
  console.log("\nMerged feature into main")

  // 7. Verify
  const updated = await client.getDocument({ id: "terminusdb:///data/jane", as_list: true })
  console.log("\nPerson on main after merge:", updated)
}

main().catch(console.error)
```

{% details title="Running this again? Clean up first" %}
If you've already run this quickstart, delete the database before running again:

```typescript
await client.deleteDatabase("MyDatabase")
```
{% /details %}

## Troubleshooting

### Error: Connection refused

**You see:**
```
Error: connect ECONNREFUSED 127.0.0.1:6363
```

**Cause:** TerminusDB is not running, or another process is using port 6363.

**Fix:**
```bash
# Check if the container is running
docker ps | grep terminusdb

# If not running, start it
docker start terminusdb

# If it doesn't exist, create it
docker run -d --name terminusdb -p 127.0.0.1:6363:6363 \
  -v terminusdb_storage:/app/terminusdb/storage \
  terminusdb/terminusdb-server
```

[Troubleshooting Connection Failures →](/docs/troubleshooting-connection)

### Error: 401 Unauthorized

**You see:**
```
Error: 401 Unauthorized
```

**Cause:** Wrong username or password. The default local credentials are `admin` / `root`.

**Fix:**
```bash
# Verify credentials work
curl -u admin:root http://localhost:6363/api/info
```

If you set a custom password via `TERMINUSDB_ADMIN_PASS` when creating the container, use that value instead of `root`.

[Troubleshooting Authentication Errors →](/docs/troubleshooting-auth)

### Error: Database does not exist (404)

**You see:**
```
Error: 404 - {"@type":"api:ErrorResponse","api:error":{"@type":"api:UnresolvableAbsoluteDescriptor"}}
```

**Cause:** You are trying to read/write a database that has not been created yet, or the path is wrong.

**Fix:**
```bash
# List existing databases
curl -u admin:root http://localhost:6363/api/db

# Create the database if missing
curl -u admin:root -X POST "http://localhost:6363/api/db/admin/MyDatabase" \
  -H "Content-Type: application/json" \
  -d '{"label": "MyDatabase", "comment": "My database"}'
```

### Error: Cannot find module 'terminusdb'

**You see:**
```
Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'terminusdb'
```
or
```
Cannot find module 'terminusdb' or its corresponding type declarations
```

**Cause:** The package is not installed, or you are running from the wrong directory.

**Fix:**
```bash
# Make sure you are in the project directory
cd my-terminusdb-app

# Install the package
npm install terminusdb
```

### Error: Cannot use import statement outside a module

**You see:**
```
SyntaxError: Cannot use import statement outside a module
```

**Cause:** You are running the file with `node index.ts` without ESM support.

**Fix:** Use `npx tsx` (recommended) which handles both TypeScript and ESM:
```bash
npx tsx index.ts
```

Alternatively, add `"type": "module"` to your `package.json` if using plain JavaScript.

### Error: Database already exists

**You see:**
```
Error: 400 - {"@type":"api:DbCreateErrorResponse","api:error":{"@type":"api:DatabaseAlreadyExists"}}
```

**Cause:** You ran this quickstart before and the database still exists.

**Fix:**
```typescript
await client.deleteDatabase("MyDatabase")
```

## Next steps

- [**Your First Schema**](/docs/schema-reference-guide/) — Add type safety to your documents with schema validation
- [**WOQL Query Guide**](/docs/woql-basics/) — Query your data with TerminusDB's pattern-matching query language
- [**JSON Diff and Patch**](/docs/json-diff-and-patch/) — Deep dive into structural diff operations
- [**API Reference**](/docs/javascript/) — Full TypeScript/JavaScript client API documentation
