> For the complete documentation index, see [llms.txt](https://codemash.gitbook.io/codemash/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codemash.gitbook.io/codemash/sdks/javascript-typescript.md).

# JavaScript / TypeScript

Write and read records from Node.js or the browser with the Norbix JavaScript / TypeScript SDK.

The JavaScript / TypeScript SDK is [`@norbix.ai/ts`](https://www.npmjs.com/package/@norbix.ai/ts) (source: [github.com/norbix-code/sdk-ts](https://github.com/norbix-code/sdk-ts)). It runs in Node.js 18 or newer and in the browser, and ships its own TypeScript types.

This page was run on 2026-10-06 with `@norbix.ai/ts` **4.13.0** and Node.js 24. All the code below is one file, `quickstart.mjs`: put the blocks one after the other.

## Before you start

* A project with a `books` collection — `title` (text, required), `pages` (number, required), `in_stock` (yes / no), `genre`. Create it in Cloud as in step 3 of the [Quickstart](/codemash/get-started/managed-service/quickstart.md).
* A key and your project id in `NORBIX_API_KEY` and `NORBIX_PROJECT_ID` — see [Install a Norbix SDK](/codemash/sdks/install.md). The key needs a role that may write records, for example **Data Editor**.

## Install

```sh
npm install @norbix.ai/ts
```

## Create the client

```js
import { Norbix, NorbixError } from '@norbix.ai/ts';

// Reads NORBIX_API_KEY and NORBIX_PROJECT_ID from the environment.
const norbix = new Norbix();
```

`norbix.api` is the data part (records, files, users), `norbix.hub` the configuration part (schemas, integrations, templates). To pass the values in code instead: `new Norbix({ apiKey: 'nbsu_…', projectId: 'pr_…' })`.

## Write a record

A record goes in as a JSON string in `document`. The answer has the new record's `id`.

```js
// Write: add one book to the `books` collection.
const created = await norbix.api.database.insertOne({
  collectionName: 'books',
  document: JSON.stringify({ title: 'Dune', pages: 412, genre: 'fiction' }),
});
console.log('Inserted', created.id);
```

## Read records

`find` returns one page of records in `list.items`. Add `filter`, `sort` or `projection` as in [Search parameters](/codemash/cloud/concepts/search-parameters.md).

```js
// Read: find the books.
const found = await norbix.api.database.find({ collectionName: 'books', pageSize: 10 });
for (const book of found.list.items) {
  console.log(`${book.title} — ${book.pages} pages`);
}
```

## Handle errors

A failed call throws a `NorbixError` with the gateway's `code` and `message`, the HTTP `status`, and every error in `errors`. Here the schema says `pages` is required:

```js
// Error handling: the schema requires `pages`, so this insert fails.
try {
  await norbix.api.database.insertOne({
    collectionName: 'books',
    document: JSON.stringify({ title: 'Untitled draft' }),
  });
} catch (err) {
  if (!(err instanceof NorbixError)) throw err;
  console.log(`Failed: ${err.code} — ${err.message}`);
}
```

The SDK has subclasses for the common cases: `NorbixAuthError`, `NorbixValidationError`, `NorbixNetworkError` and `NorbixTimeoutError`.

## Run it

```sh
node quickstart.mjs
```

The output (the collection already had *The Hobbit*):

```
Inserted 6ac54a59212c29912eaddd81
Dune — 412 pages
The Hobbit — 310 pages
Failed: CM-ERRORS-DATABASE-030 — Field 'pages' is invalid: a value is required
```

### In TypeScript

Records come back as plain objects, so give them your own type. In `quickstart.ts`, the read loop becomes:

```ts
type Book = { title: string; pages: number };
for (const book of (found.list?.items ?? []) as Book[]) {
  console.log(`${book.title} — ${book.pages} pages`);
}
```

The rest of the file stays the same. It was checked with `tsc --strict --skipLibCheck` and run with `node quickstart.ts` (Node.js 24), with the same output.

{% hint style="warning" %}
Keep `"skipLibCheck": true` in `tsconfig.json` (the default of Vite and most templates). The type files of 4.13.0 have errors of their own (`Cannot find name 'IGet'`, `'JsonObject'`, `'CancellationToken'`) that stop `tsc` without it.
{% endhint %}

## Next steps

* React app? Use [React Redux](/codemash/sdks/react-redux.md) — hooks with caching on top of this SDK.
* Every operation, with a tab per language: [SDK reference](/codemash/sdks/database.md).
* The same calls from the terminal: [CLI](/codemash/cli/cli.md).
